命令注入是指通過提交惡意構造的參數破壞命令語句的結構,達到非法執行命令的手段。
我將從易到難對不同難度的命令注入嘗試
簡單難度程序關鍵代碼:
<?php
if( isset( $_POST[ 'Submit' ] ) )
{
$target = $_REQUEST[ 'ip' ];
if( stristr( php_uname( 's' ), 'Windows NT' ) )
{
$cmd = shell_exec( 'ping ' . $target );
}
else {
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
echo "<pre>{$cmd}</pre>";
}
?>
從程序中可以看出對於輸入數據,除了對空的輸入有作區別,沒有對輸入的數據進行任何處理
輸入127.0.0.1&&net user
可以看到除了顯示合法的信息還包含了非法信息,所以要對輸入的內容進行過濾
困難難度關鍵代碼
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
$target = $_REQUEST[ 'ip' ];
$substitutions = array(
'&&' => '',
';' => '',
);
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
$cmd = shell_exec( 'ping ' . $target );
}
else {
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
echo "<pre>{$cmd}</pre>";
}
?>
程序使用str_replace將“&&”和“;”轉換成了空,所以無法使用&&和;進行有效注入;
但在命令行中有許多的特殊符號,所以可以用其他符號繞過過濾
輸入127.0.0.1&;&ipconfig
按照規則中刪除;正好執行命令127.0.0.1&&ipconfig,說明過濾的不嚴格
再次升級,過濾部分程序如圖所示
$substitutions = array(
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
命令行中各個符號的含義:
'&':Command 1&Command 2,先執行Command 1,不管是否成功,都會執行Command 2
';' 標記語句結束
'|' Command 1|Command 2,Command 1的輸出作為Command 2的輸入,並且只打印Command 2執行的結果
'-'
'$' 變量替換(Variable Substitution)的代表符號。
'(' '()'指令群組部分內容
')' 同上
'`' 返回當前命令執行結果
'||' A||B表示A執行成功后,B就不會再執行了;A失敗或不執行,B才能執行。
將所有的能夠在shell引起執行停止和條件執行的符號都進過濾,並且對兩個分符號的單獨符號也進行過濾,就能有效避免命令注入,防止嚴重后果的發生。
此時輸入127.0.0.1|&;&|ipconfig
結果不顯示: