ksnctf Q.6


これはログインまでいったものの、そこからが行き詰まったため、write up を見た。

そして、自分でまとめ直してみようとおもう。

これは、SQL インジェクションの問題だが、ただ 1 OR 1 = 1; -- と打てばよいものではない。

ブラインド SQL インジェクションという手法を使う。

これは、直接 SQL 実行結果をみることはできずとも、クエリを実行した後の様子を観察することで情報を取得するもの。

今回の問題ではまさに SQL の実行結果をみることはできない。

しかし、ログインできたかどうかがわかる。

この「ログインできたかどうか」を使って、FLAG の奪取を目指す。

今回普通に SQL インジェクションでログインを試みると、普通に入ることができる。

しかし、そこにはログインはできたものの、「FLAG は admin ユーザーの password だよ」と知らされる。

ここから、なんとかして password を表示させたいが、実行結果を表示させるよな機構がないため上手くいかない。

そこで上記の「ブラインド SQL インジェクション」である。

1 OR 1 = 1; --

このテキストを入力するとログインできるのは、1 = 1が true であるから。 つまり、ここが true になればなんでもよい。

この1 = 1を、(SELECT LENGTH(pass) FROM user WHERE id = 'admin') > 1

と置き換えてみる(id が admin なのは、問題で公開されてる情報)

こうすると、admin  の  pass の文字列の長さが 1  より大きければ true、 つまりログインできるということになる。

これを使って、ログインできるかできないかを見ながら pass の長さが特定できる。

さらに、これを使って pass 自身も特定することができる。

SQL には SUBSTR というクエリがある(今回初めて知った)

これは、文字を切り取る関数で、開始位置と切り取り文字数を指定する。

これを使って、例えば

' or SUBSTR((SELECT pass FROM user WHERE id = 'admin'), 1, 1) = 'F' --

インジェクションする文字列をこのようにすれば、1 番目の文字が F であればログインできる、ということになる。

あとはこれを繰り返せば password が特定できると言うわけだ。(感動しました)

もちろんスクリプトを書いてやる。