指令執行漏洞是指攻擊者可以随意執行系統指令,屬于高危漏洞之一,也屬于代碼執行的範疇。不僅存在一B/S架構中,也存在于C/S架構中。
OS指令執行漏洞:在windows和linux系統下,"&&"的作用是将兩條指令連起來執行,此外,&、||、|符号同樣也可以作為指令連接配接符使用,如net user ||set、net user | set、net user & set,如果web應用沒有過濾好輸入,就變得相當危險,權限足夠大的情況下,伺服器可被攻擊者直接攻陷。
指令執行漏洞 | 直接調用作業系統指令 |
---|---|
代碼執行漏洞 | 靠執行腳本代碼調用作業系統指令如eval(system(‘set’)) |
php指令執行:
部分函數用來執行外部應用程式:
system ( string $command ) | 執行外部程式,并且顯示輸出,如果 PHP 運作在伺服器子產品中, system() 函數還會嘗試在每行輸出完畢之後, 自動重新整理 web 伺服器的輸出緩存。 |
---|---|
shell_exec() | 用于通過shell執行指令并以字元串的形式傳回完整的輸出。shell_exec是backtick操作符的别名,用于*nix。如果指令失敗,則傳回NULL,并且這些值對于錯誤檢查不可靠。 |
exec() | 如果提供了 output 參數, 那麼會用指令執行的輸出填充此數組, 每行輸出填充數組中的一個元素。 數組中的資料不包含行尾的空白字元,例如 \n 字元。 請注意,如果數組中已經包含了部分元素,exec() 函數會在數組末尾追加内容。如果你不想在數組末尾進行追加, 請在傳入 exec() 函數之前 對數組使用 unset() 函數進行重置。 |
– | – |
passthru() | 當所執行的 Unix 指令輸出二進制資料, 并且需要直接傳送到浏覽器的時候, 需要用此函數來替代 exec() 或 system() 函數。 常用來執行諸如 pbmplus 之類的可以直接輸出圖像流的指令。 通過設定 Content-type 為 image/gif, 然後調用 pbmplus 程式輸出 gif 檔案, 就可以從 PHP 腳本中直接輸出圖像到浏覽器。 |
Low
解決亂碼問題的方法:在DVWA-master\dvwa\includes目錄下找到dvwaPage.inc.php檔案中所有的”charset=utf-8”,修改”charset=gb2312”
1、檢視伺服器端源代碼
<?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
echo "<pre>{$cmd}</pre>";
}
?>
函數解釋:
stristr() | 搜尋字元串在另一字元串中的第一次出現的位置 |
---|---|
$_REQUEST() | 擷取以POST方法和GET方法送出的資料 |
2、檢視用戶端源代碼
<div class="body_padded">
<h1>Vulnerability: Command Injection</h1>
<div class="vulnerable_code_area">
<h2>Ping a device</h2>
<form name="ping" action="#" method="post">
<p>
Enter an IP address:
<input type="text" name="ip" size="30">
<input type="submit" name="Submit" value="Submit">
</p>
</form>
<pre>
3、構造執行語句
在包含注入指令資料送出後可根據回顯結果是否包含執行指令結果特征進行判斷是否存在注入指令漏洞,例如在輸入指令中包含 id 的資料,檢視響應結果是否包含 uid 和gid。
分别填寫以下送出資料:
127.0.0.1&&id:uid,gid
127.0.0.1&&net user:得到系統中所有使用者
testcmdinjection||id
testcmdinjection||net user
127.0.0.1&id
127.0.0.1|net user
testcmdinjection&id
testcmdinjection|net user
也可自編python腳本進行指令注入。
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
echo "<pre>{$cmd}</pre>";
}
?>
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
echo "<pre>{$cmd}</pre>";
}
?>
針對輸入資料删除&、;、-、$、(、)、`、||、|空格等字元(注意删除|空格,對|并不進行處理)
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
echo "<pre>{$cmd}</pre>";
}
else {
// Ops. Let the user name theres a mistake
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
CSRF是跨站域請求僞造,加入Anti-CSRFtoken,伺服器端對token進行驗證,防止黑客利用儲存使用者驗證資訊的cookie來僞造請求。
輸入資料會根據小數點進行拆分,拆分成四段再組合起來,惡意指令難以入侵。
修複建議
a) 使用白名單對送出資料類型和格式進行嚴格驗證
b) 限制執行指令由使用者送出,使用白名單限制執行指令
c) 避免 web 伺服器啟動使用者權限過高