pico CTFでweb問題を解いてみる #2
web問題writeupの第二回目です
picobrowser
https://play.picoctf.org/practice/challenge/9?category=1&page=1
問題文には「picobrowserだけがflagを表示できる」と書いてあった。とりあえずpicobrowserと検索してみたらandroidアプリがヒットしたけれど...もし仮に「このアプリをインストールしてページを見ろ」ってことだとすると、iOS勢じゃ解けないっぽいし、とりあえず保留にして別の方法を考えることにした ※
さて、このページには"flag"と書いてあるボタンのみが設置されており、試しにクリックしてみるものの「 You're not picobrowser! Mozilla/5.0 ~~~」と表示されてしまう。そこで「ブラウザ 偽る」とか調べてみると、”ユーザーエージェント”とかいうものが出てきた。どうやらこれを使うっぽい。さらに調べていくと、chromeのデベロッパーツールにはnetwork conditionsという項目があり、そこで任意のブラウザ名に変更できるということだったので、"picobrowser"に変更してから"flag"ボタンを押してみると、見事flagを取得できた。
※問題を解いた後、興味本位でアプリDLしてflagを見れるか確認してみたけど「You're not picobrowser!」って表示されてしまい、笑ってしまった。
Web Gauntlet
https://play.picoctf.org/practice/challenge/88?category=1&page=1
問題文には「adminとしてログインしてみろ」と書いてある。問題サイトに飛んでみるとログインフォームがあって、usernameとpasswordという項目がある。SQLインジェクションだと思うが、添付ページを見てみるとどうやら"or"というキーワードはフィルター処理されてるみたいなので、「'OR 1=1」とか入力しても無駄っぽい。
とりあえずユーザー名に"admin"、パスワードに適当な文字を入力してみると
SELECT * FROM users WHERE username='admin' AND password='a'
と表示された。このSQL文が実行されているっぽい。
ユーザ名に 「admin'--」、パスワードには適当な文字列を入力してみた。
SELECT * FROM users WHERE username='admin' -- AND password='a'
無事突破できた。
...と思ったらRound2という表示とともに別のフォームが出てきた。添付ページを見ると、今度は [or] [and] [like] [=] [--] というワードがフィルター処理されてしまってるらしいのでRound1の方法は使えない。SQLコメントの別の書き方について調べてみたら/* */とかが出てきたので。ユーザ名「admin' /*」パスワード「*/ '」とか試してみたんだけど...まぁ正しい文になってないし当然うまくいかない。ネットで20分くらい色々なSQLを見た時、ふと、[;]を使えばSQLを終了できるのではないかという考えに至って、ユーザー名に「admin';」と入力してみたところ突破できた。
Round3に入った。 [>] [<] が追加でフィルターになっている。 [;]が禁止になっていないなら多分Round2と同じようにやれば解けそうだなぁと思ったら案の定解けた。
Round4では [admin]という単語そのものがフィルターになってて使えなくなった。adminという単語を使わずにadminユーザーの情報を持ってこなければいけないらしい。そこで、adminの一部を大文字にしてみたり、単語の中に/**/を挿入してみたり、admadminin(adminという文字が取り除かれるとadminになる)とかも試したけれど全て無駄だった。万策尽きたのでwriteUPを探すことにした...
解法の一つとしてUNION句を使うやり方が紹介されていた。データーベースの中ではadminが一番最初の行にあるだろうという予想のもとで、「UNIONで複数のクエリを結合」→「LIMIT 1を指定することで一番上のものを取得する」という手順によって解いていた。SQLコードで示すと
SELECT * FROM users WHERE username='bob' UNION SELECT * FROM users LIMIT 1;
これで行ける
...と思いきや実はまだダメ。空白文字が禁止されているらしい。
SQL Injection: Bypassing Common Filters - PortSwiggerを見てみると、
/**/は空白文字に置換して扱ってくれるということが書いてあるので、
ユーザー名を bob'/**/UNION/**/SELECT/**/*/**/FROM/**/users/**/LIMIT/**/1;とし、パスワードに適当な文字列を入れたところうまく行った。
(参考writeup: https://www.youtube.com/watch?v=ZQj5tSwaG0k)
次にRound5。ここにきて[union]が禁止されてしまった。いろいろ調べてみたところ、sqlでは||による文字列の連結が行えるということだったので、adminをaとdminに分割してみた。つまり
SELECT * FROM users WHERE username='a'||'dmin';
としてみた。無事突破できた(多分Round4もこのやり方なら突破できただろうと思う)
こうしてflagを獲得したのであった↓
picoCTF{y0u_m4d3_1t_96486d415c04a1abbbcf3a2ebe1f4d02}
flag入力する時に気づいたけど、pico CTFの問題ページにヒント載ってるので、次詰まったらまずそこをみようと思った。
Open-to-admins
https://play.picoctf.org/practice/challenge/1?category=1&page=1
"管理者として"、"14:00ぴったり"にボタンを押すとフラグが得られるとのこと。色々調べたけど分からなかったのでヒントを見るとcookieが役に立つと書いてあった。前に似たような問題を解いた時はcookieの値を書き換えるだけで大丈夫だったけど、今回はadminとかtimeとかいう属性は一つもない。調べていくキーワードとかも全然思い浮かばなかったので潔くwriteupを見た。ついでに、いい機会だと思ったので改めてcookie(ついでにセッション)についても勉強しなおした。
さて結果から言うと「adminという属性を追加して値をtrueにし、timeという属性を追加して値を1400に」するというのが本問の答えっぽくて、実際それで解けた。内心「運じゃん」と思った。picoCTFは問題の良し悪しを評価できるようになっているのだがこの問題だけ異様にbadが多い。そういうことだと思う...。
picoCTF{0p3n_t0_adm1n5_132f8585}
これで200点問題まではおしまい。
なんかもうwriteup無しでやっていけるのか不安だけど、それでも、わからなかった部分はちゃんと理解して進めるようにしたい。