您好,登錄后才能下訂單哦!
注:命令注入漏洞的分析,及含有命令注入漏洞的函數解析
含有命令注入漏洞的函數:system()、exec()、passthru()、shell_exec()、``(與shell_exec()功能相同)
1、 函數用法
String shell_exec(string command)
command 要執行的命令
2、 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
echo "<pre>{$cmd}</pre>";
}
?>
源碼分析:
函數首先判斷環境下的系統,如果是win則執行第一個命令,若是linux執行的命令加上-c選項,以為linux中ping命令是一直執行的。只有加了-c指定發送的跳數才能停止。
可以看到在接收用戶輸入的地方,對用戶的輸入沒有做任何的處理。不難看出這就是一個典型的命令注入漏洞。而且孩子是最輕易。
我們正常測試一下:
可以看到,正常返回的是ping返回的數據。
我們通過這個命令執行漏洞進行測試一下:
構造我們的語句:10.39.1.4 | net user
解釋: | 的意思是前面命令的輸出結果作為后面命令的輸入。
net user 查看當前系統中存在哪些用戶
測試:
可以看到當前系統中存在三個用戶。如果作為×××去利用的話就可以使用命令去創建一個用戶。就不在演示
漏洞分析:不處理用戶的任何輸入就直接執行函數中的命令。
知識擴展:
; - 分號在linux命令執行的時候,可以直接執行幾條命令,命令與命令之間用分號隔開。
& 前面的命令執行后接著執行候命的命令
&& 前面的命令執行成功后才可以執行下面的命令
| 前面的命令輸出結果最為后面命令輸入的內容
|| 前面的命令執行失敗后才會執行后面的命令
3、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>";
}
?>
源碼分析:
Str_replace()函數,以其他字符替換字符串中的一些字符(區分大小寫)。
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );將用戶輸入的內容,含有&&或;的替換為空。
其他的部分基本和low相差不大。
這里的源碼對用戶的輸入進行了初步的過濾,過濾掉了一些能夠同時執行命令的符號,但是我們知道,擁有同樣作用的符號不止&&和;。所以依然可以進行命令注入。
命令注入測試:
構造語句: 10.39.1.4 & net user
& 前面命令執行后接著執行后面的命令
測試:
依然獲得了執行的結果
漏洞分析:此級別下的源碼雖然對用戶的輸入設置了過濾,但是沒有將特殊符號過濾完全,僅僅設置黑名單是不夠的,你不知道用戶會輸入什么,造成有心者亦可以利用此漏洞。
4、 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>";
}
?>
源碼分析:
這個級別的源碼和medium級別的源碼相差不大,只是將更多的符號加入黑名單。
通過這樣的確實能夠有效的防御之前的諸多思路。
測試:
輸入10.39.1.4 | net user
已經不能用那些方法了。具體的利用我也沒有找到合適的方法。
漏洞分析:只是做黑名單的話,總是不夠安全的,只要黑名單不夠完整,就不是很安全。即使你認為名單已經很完整了。可能還有你不知道的存在可以利用。
5、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();
源碼分析:
Explode()函數,將字符串變為數組。這里就是將我們輸入的ip,變成數組
然后判斷數組的前四組數是否為數字,并且數組中有四個對象。不滿足就會報錯提醒。也就是說這里只允許你輸入四組數字。
若果判斷為true的話,就會再將這四組數通過點連接起來再就行ping命令。
就不測試了,這樣的源碼已經杜絕了你的所有命令注入×××。
1、函數用法
eval(phpcode)
Phpcode 規定要計算的php代碼。通常用分號結束每句代碼的執行。
2、環境源碼:
<?php
$var = "var";
if(isset($_GET["name"])){
$arg = $_GET["name"];
eval("\$var=$arg;");
echo "\$var = ".$var;
}
?>
構造語句:
name=phpinfo()
測試效果:
3、 ctf題目實例
題目地址bugku中的本地包含:http://120.24.86.145:8003/
題目解析:
源碼:
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);
?>
構造語句:
Hello = file(‘flag.php’)
解析,當參數接收到的構造的語句的時候,代碼就會變為
Eval(var_dump(file(‘flag.php’)))
Eval函數,執行函數體沒的php代碼;file()函數把整個文件讀到一個數組中。Var_dump()函數 輸出。
所以執行結果就是將flag.php中的內容以數組的形式輸出出來。
得到flag
1、函數用法:
System(string command,int &return_var)
Command 要執行的命令
Return_var 存放命令的執行后的狀態值
2、環境源碼:
<?php
$cmd = $_GET['cmd'];
if(isset($cmd)){
echo system("dir".$cmd);
}
?>
構造語句:
Cmd=| net user
測試:
通過漏洞我們獲得了系統中存在哪些用戶,同樣的我們也可以通過這樣的方法在系統中創建我們自己的用戶。并可以加入到管理員組中。這里就不在說了。
1、函數用法:
shell_exec(string command)
command 要執行的命令
2、環境源碼:
<?php
$cmd = $_GET['cmd'];
if(isset($cmd)){
echo "<h4>";
echo shell_exec("dir".$cmd);
echo "<h4>";
}
?>
4、 測試:
構造語句: | net user
實現方法和上一個函數是一樣的。同樣的函數還有exec()和符號
五、passthru()函數造成的漏洞
1、函數用法:
void passthru (string command, int &return_var)
command 要執行的命令
return_var 存放執行命令后的狀態值
同 exec() 函數類似, passthru() 函數 也是用來執行外部命令(command)的。 當所執行的 Unix 命令輸出二進制數據, 并且需要直接傳送到瀏覽器的時候, 需要用此函數來替代 exec() 或 system() 函數。
2、環境源碼:
<?php
$cmd = $_GET['cmd'];
if(isset($cmd)){
echo passthru($cmd);
}
?>
3、測試
構造語句 cmd=net user
獲得用戶列表
總結以上所有函數漏洞造成的命令注入漏洞,每一個例子都是因為沒有對用戶的輸入進行處理。在防御漏洞的時候,一定明白一個道理,所有用戶的輸入都是有害的。所有的輸入都是不值得相信的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。