<?php include "./config.php"; login_chk(); $db = mssql_connect(); if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['id'])) exit("No Hack ~_~"); if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['pw'])) exit("No Hack ~_~"); $query = "select * from prob_revenant where id='{$_GET['id']}' and pw='{$_GET['pw']}'"; echo "<hr>query : <strong>{$query}</strong><hr><br>"; sqlsrv_query($db,$query); if(sqlsrv_errors()) exit(mssql_error(sqlsrv_errors())); $query = "select * from prob_revenant where id='admin'"; $result = sqlsrv_fetch_array(sqlsrv_query($db,$query)); if($result['4'] === $_GET['pw']) solve("revenant"); // you have to pwn 5th column highlight_file(__FILE__);
特徴は以下。
- SQL Server
- id,pwが入力可能
master,sys,information,prob,;,waitfor
がフィルタリング
- エラーが出れば表示される
- adminの5番目のカラムの内容を取得してくる必要がある
カラム名をまずは抜き取る
- HAVING, GROUP BYトリック
- [Lord of SQL Injection] LoS - revenant 문제풀이 | mingzzi
- ここに書いてある。having 1=1を書いておくと、エラーが出る。かつ、エラーが表示されるようになっていると、カラム名が流出する。
- 1個とってきたら、
group by name1 having 1=1
としてエラーを出すと2つ目のカラム名が出てくる。 - カラム名を入れてうまくいかなかったら
[カラム名]
のようにするとうまくいったりする(よくわからん) - エラーが消えたら全部抜き取り成功
こんな技があるのか…
書いてあるままにやってみると、確かに抜き出せる。
id, pw, [45a88487], [13477a35], [9604b0c8]
中身を抜き取る
これで後は、Blind SQL Injectionかな…と思いきや、エラーから直接抜き取るテクもある。
- エラー文から内容を抜き取る方法
ほほう。?id=admin' and "9604b0c8"=1 --
で抜き出せる。