pico CTFでweb問題を解いてみる #4
今日もやっていきます。
web問題は残り3つっぽい。
Irish-Name-Repo 3
https://play.picoctf.org/practice/challenge/8?category=1&page=1
irish-name-repoシリーズ第三弾。指定されたページに飛んでみると見慣れた画面が現れる。これまでとの違いは、adminのログインフォームに"ユーザー名"欄が無い(パスワード欄のみある)こと。
いろんな文字列を入力して挙動を調べようとしたけれど別段不自然な点とかは見つけられなかった。とりあえずパスワード欄に「' or 'a' = 'a」を入力してみたけれど、それも弾かれてしまった。
一旦ここでHTMLを眺めてみる。
するとこんな一行を見つけた。
<input type="hidden" name="debug" value="0">
typeがhiddenになってて怪しい (...と言いつつ仕様とか使い方とかちょっと曖昧だったので、ここでhiddenについてちょこっとだけ調べた)。debugなんて名前ついてるし、もうここまで来たら正解に辿り着いたも同然だなと思いながら、htmlを編集。
<input type="text" name="debug" value="0">
上記のようにtypeを変更したら、送信ボタンの上に、隠れていたフォームが出現した。値のところには"0"が入っていたのでとりあえずこれを"5"に変えてみて、ついでにパスワード欄には12345とか適当な文字列を入力して一度送信ボタンを押してみる。
すると先ほどとは違って、"Login failed"の文字の上に以下が表示された
password: 12345 SQL query: SELECT * FROM admin where password = '12345'
まぁ...これを見たところでそんなに嬉しくない(想像通りのSQL文だった)
一旦前のページに戻って、パスワードの部分をアルファベットに変更してみる。
すると
password: abcde SQL query: SELECT * FROM admin where password = 'nopqr'
変化あり。
どうやら入力されたパスワードをROT13で(お気持ち)暗号化してるみたい。
さっき「' or 'a' = 'a」が弾かれたの理由もこれ。
ということで、orの部分をbeに変更して「' be 'a' = 'a」として実行すると
picoCTF{3v3n_m0r3_SQL_06a9db19}
JaWT Scratchpad
https://play.picoctf.org/practice/challenge/25?category=1&originalEvent=1&page=1
指定ページに飛んでみた。
どうやらオンラインメモ帳サービスということらしい。フォームに名前を書いてログインすると、「Hello **(名前)」と表示されてメモ帳が使えるようになる仕様。問題文を読む限り、adminでログインすればいいみたい。
とりあえずフォームにadminと入力してみると「YOU CANNOT LOGIN AS THE ADMIN! HE IS SPECIAL AND YOU ARE NOT.」と怒られた。何から手をつけていいかわからなかったので、まずはサイトをいろいろ見てみることにした。まず気になったのは問題タイトルにもなっているJaWTという単語。指定ページ上部にも「powered by JWT」と書いてあるし、ちょっとその辺から調べてみる。
JWTはJSON web Tokenの略で、(詳細についてはネットで調べればたくさん情報が出るので省くけれど)一言で言うなら「”署名”を使うことで情報を安全に正確に伝えることができるようになったJSON」である。
JWTは3つの文字列を.(ドット)で区切ることで以下のように表現される。
(1).(2).(3)
1. ヘッダー:署名にどんなアルゴリズムを用いるか
2. ペイロード:伝えたい任意の情報
3. シグネチャ:署名
上記のうち、1と2には「JSON形式で表したものをbase64エンコードした文字列」が入り、3には「1と2を連結させたものをSHA-256でハッシュ化し、それをもとに1で指定したアルゴリズム(HMACまたはRSA)によって署名したもの」が入る。
さて、ここまでわかればこの問題を解き進めることができる。
問題のサイトにとりあえずTestUserという名前でログインすると、Cookieにjwtという属性が追加されており、値は以下のようになっている。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiVGVzdFVzZXIifQ.2BxYaDEVw5nMTi4b1rkjjXnsWhjbmjTn2hhFfmGYG0U
文字列が.で3分割されているのでこれがjwtということがわかる。JSON Web Tokens - jwt.ioというサイトでjwtをデコードできるので、コピペして試してみると、
ヘッダー
{ "typ": "JWT", "alg": "HS256" }
{ "user": "TestUser" }
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), [your-256-bit-secret] )
ペイロードの部分に注目すると、user属性が(先ほど自分が設定した名前の)"TestUser"になっている。普通に考えれば、これを"admin"に書き換えたjwtを作り、cookieの値として設定すればいいのだろう。しかしそうなると問題はシグネチャ部分。[your-256-bit-secret]となっている秘密鍵がわからないことには偽装jwtは作れない。
jwtの攻撃例を調べてみたところ、ヘッダーのalg部分を"none"に書き換えてシグネチャ部分をごっそり削り取る(つまり「署名しないよ」というjwtに改ざんする)方法があるようで、これを試してみたものの、内部エラーと表示されてうまく行かなかった。
一旦詰まってしまったので、改めてJaWTサイトを見て手がかりを探してみる。するとページ下部に「気に入った名前がないなら、Johnみたいなかっこいい名前を使うといいよ!」という一文があって、なぜかJohnの部分がリンクになっている。クリックしてみると”John the Ripper”というプロジェクトのgithubのページに飛んだ。John The Ripperについては初めて聞いたけど、調べてみるとどうやらパスワードクラック用のツールらしい。これを使って秘密鍵を見つけてねということだろう。
早速使い方を調べてみた。
攻撃して学ぶJWT【ハンズオンあり】 | Money Forward Engineers' Blogに書かれている方法を使って全探索してみた。
$ ./john jwt.txt Using default input encoding: UTF-8 Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x]) Proceeding with single, rules:Single Press 'q' or Ctrl-C to abort, almost any other key for status Almost done: Processing the remaining buffered candidate passwords, if any. Proceeding with wordlist:./password.lst Proceeding with incremental:ASCII 0g 0:00:30:17 3/3 0g/s 1786Kp/s 1786Kc/s 1786KC/s tm0kam74..tm0k35sd 0g 0:00:30:21 3/3 0g/s 1785Kp/s 1785Kc/s 1785KC/s kisch378..kiscis39 〜略〜 0g 0:01:23:12 3/3 0g/s 2269Kp/s 2269Kc/s 2269KC/s rlcm2try..rlcmunk4 0g 0:01:34:17 3/3 0g/s 2269Kp/s 2269Kc/s 2269KC/s u Niy8..u Nis3
1時間半くらい放置しても中々終わる気配がないので中断。
きっと時間をかければそのうち見つかるんだろうけれど、ワードリストを使って辞書型攻撃した方が効率的だろうと思って更にいろいろ調べてみると、何やら”rockyou.txt”というものがあるらしい。それを使ってみた。
$ ./john jwt.txt --wordlist=rockyou.txt Using default input encoding: UTF-8 Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x]) Press 'q' or Ctrl-C to abort, almost any other key for status ilovepico (?) 1g 0:00:00:02 DONE (2020-11-29 21:03) 0.3424g/s 2532Kp/s 2532Kc/s 2532KC/s ilovepinkxxx..ilovepatopollo Use the "--show" option to display all of the cracked passwords reliably Session completed.
ilovepico ←これが秘密鍵らしい。一瞬で見つかった。恐るべし。
さて、ここまでわかればhttps://jwt.io/ で偽装jwtを作るだけ。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.gtqDl4jVDvNbEe_JYEZTN19Vx6X9NNZtRVbKPBkhO-s
完成品↑
これをcookieに設定したところ、"Hello admin!"と表示されて、メモ帳の部分にFlagが表示されていた。とても嬉しかった。
picoCTF{jawt_was_just_what_you_thought_44c752f5}
長くなったのでここまで。あと1問頑張りたい。