low
,看到其界面以下:IP地址
,而後經過ping
進行測試,先輸入127.0.0.1
和www.baidu.com
測試以下:127.0.0.1
php
www.baidu.com
linux
命令拼接
測試了,輸入127.0.0.1 | whoami
shell
命令注入成功。windows
127.0.0.1|whoami數組
127.0.0.1&whoami安全
127.0.0.1000 || whoami服務器
127.0.0.1 && whoamisession
注意:
有空格和無空格有時會有意想不到的效果函數
作完了固然得看一下源碼:學習
能夠看到,該代碼沒有對用戶的輸入作任何的過濾,直接使用shell_exec函數
執行用戶輸入,這是很是危險的。
經過分析,能夠看出,medium
關卡比low
關卡多了一個黑名單
。其經過數組的方式將&&
和;
進行了過濾,即將其替換爲空
。可是,這種過濾基本上仍是跟沒有過濾差很少,由於黑名單裏的過濾太少了,黑名單也不安全。
127.0.0.1 || whoami
127.0.0.1|whoami
127.0.0.1000||whoami
能夠看到,此次的黑名單過濾明顯的多了起來,可是也發現(多是故意給咱們漏出來的😂),其在過濾的時候,沒有過濾|
而是過濾了|+空格
,因此,該代碼只是遇到單單一個|
,不會進行過濾。
<?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(); ?>
一波代碼審計,咱們發現,此次的過濾和前面的兩關沒有任何類似之處,而是直接換了一種思路,也就是咱們所說的白名單
。其控制了用戶的輸入,不在控制用戶的輸入哪些不能用,而是控制用戶的輸入哪些能用。
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
這段代碼是控制了用戶身份信息,在每次和服務器交互之時,服務器會隨機給用戶分配一個ID,用做用戶的身份憑證,這樣也就斷絕了假冒用戶的事件發生。
$target = stripslashes( $target );
stripslashes函數
用於刪除輸入中的反斜槓。
$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 ))
而這段代碼是控制了用戶只能輸入IP地址
,沒法使用域名。且在用戶輸入IP地址後,使用explode函數
以.
爲分割,將IP地址分割爲數組,最後判斷數組的個數是否爲4
。能夠說,過濾確實很絕,可是也有一個很差之處就是屏蔽掉了域名。
命令執行漏洞(| || & && 稱爲管道符)
command1 && command2 先執行 command1,若是爲真,再執行 command2
command1 | command2 只執行 command2
command1 & command2 先執行 command2 後執行 command1
command1 || command2 先執行 command1,若是爲假,再執行 command2
windows:(1)|(2)||(3)&(4)&&
linux:(1)|(2)||(3);(4)&&
① system()
② exec()
③ shell_exec()
④ passthru()
⑤ popen()
⑥ ``(反引號)