Skip to content

Commit

Permalink
Merge branch 'kevoreilly:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
dsecuma authored Oct 22, 2024
2 parents db495ec + 00ba68f commit 220b5e9
Show file tree
Hide file tree
Showing 17 changed files with 417 additions and 169 deletions.
6 changes: 6 additions & 0 deletions conf/default/auxiliary.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,9 @@ bpf = not arp
# Enable or disable the use of QEMU as screenshot capture [yes/no].
# screenshots_linux and screenshots_windows must be disabled
enabled = no

[Mitmdump]
# Enable or disable the use of mitmdump (mitmproxy) to get dump.har [yes/no].
# This module requires installed mitmproxy see install_mitmproxy
# (https://github.com/kevoreilly/CAPEv2/blob/master/installer/cape2.sh#L1320)
enabled = no
11 changes: 11 additions & 0 deletions conf/default/mitmdump.conf.default
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[cfg]
# bin path to mitmdump
bin = /opt/mitmproxy/mitmdump

# Host ip where mitmdump is listening
host = 127.0.0.1

# Interface where mitmdump is listening
interface = virbr0

# Future options like custom ports, cert paths, etc
5 changes: 0 additions & 5 deletions conf/default/processing.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -321,11 +321,6 @@ key =
[script_log_processing]
enabled = yes

# Community
# Dump PE's overlay info
[overlay]
enabled = no

# Community
[floss]
enabled = no
Expand Down
5 changes: 5 additions & 0 deletions conf/default/selfextract.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,8 @@ timeout = 60
[msix_extract]
enabled = no
timeout = 60

# PE file overlay
[overlay]
enabled = yes
timeout = 60
7 changes: 4 additions & 3 deletions data/yara/CAPE/Lumma.yar
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ rule Lumma
description = "Lumma Payload"
cape_type = "Lumma Payload"
packed = "0ee580f0127b821f4f1e7c032cf76475df9724a9fade2e153a69849f652045f8"
packed = "23ff1c20b16d9afaf1ce443784fc9a025434a010e2194de9dec041788c369887"
strings:
$c2 = {8D 44 24 ?? 50 89 4C 24 ?? FF 31 E8 [4] 83 C4 08 B8 FF FF FF FF}
$peb = {8B 44 24 04 85 C0 74 13 64 8B 0D 30 00 00 00 50 6A 00 FF 71 18 FF 15}
$remap = {C6 44 24 20 00 C7 44 24 1C C2 00 00 90 C7 44 24 18 00 00 FF D2 C7 44 24 14 00 BA 00 00 C7 44 24 10 B8 00 00 00 8B ?? 89 44 24 11}
$decode1 = {C1 (E9|EA) 02 [0-3] 0F B6 (44|4C) ?? FF 83 (F8|F9) 3D 74 05 83 (F8|F9) 2E 75 01 (49|4A) [0-30] 2E 75}
$decode2 = {B0 40 C3 B0 3F C3 89 C8 04 D0 3C 09 77 06 80 C1 04 89 C8 C3 89 C8 04 BF 3C}
$decode3 = {B0 40 C3 B0 3F C3 80 F9 30 72 ?? 80 F9 39 77 06 80 C1 04 89 C8 C3}
condition:
uint16(0) == 0x5a4d and any of them
}
14 changes: 14 additions & 0 deletions installer/cape2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,17 @@ function install_volatility3() {
chown "${USER}:${USER}" $vol_path -R
}

function install_mitmproxy() {
sudo mkdir /opt/mitmproxy
sudo chown ${USER}:${USER} /opt/mitmproxy
cd /opt/mitmproxy
mitmproxy_version=$(curl -s https://api.github.com/repos/mitmproxy/mitmproxy/releases/latest | grep '"tag_name":' | cut -d '"' -f 4 | sed 's/^v//')
wget https://downloads.mitmproxy.org/"$mitmproxy_version"/mitmproxy-"$mitmproxy_version"-linux-x86_64.tar.gz -O mitmproxy.tar.gz
tar xvzf mitmproxy.tar.gz
rm mitmproxy.tar.gz
chown "${USER}:${USER}" /opt/mitmproxy -R
}

function install_guacamole() {
# Kudos to @Enzok https://github.com/kevoreilly/CAPEv2/pull/1065
# https://guacamole.apache.org/doc/gug/installing-guacamole.html
Expand Down Expand Up @@ -1451,6 +1462,7 @@ case "$COMMAND" in
install_systemd
install_jemalloc
install_logrotate
install_mitmproxy
#socksproxies is to start redsocks stuff
if [ -f /opt/CAPEv2/socksproxies.sh ]; then
crontab -l | { cat; echo "@reboot /opt/CAPEv2/socksproxies.sh"; } | crontab -
Expand Down Expand Up @@ -1501,6 +1513,8 @@ case "$COMMAND" in
librenms_snmpd_config;;
'librenms_sneck_config')
librenms_sneck_config;;
'mitmproxy')
install_mitmproxy;;
'issues')
issues;;
'nginx')
Expand Down
3 changes: 0 additions & 3 deletions lib/cuckoo/common/integrations/file_extra_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@
HAVE_BAT_DECODER = False
print("OPTIONAL! Missed dependency: poetry run pip install -U git+https://github.com/DissectMalware/batch_deobfuscator")

processing_conf = Config("processing")
selfextract_conf = Config("selfextract")

unautoit_binary = os.path.join(CUCKOO_ROOT, selfextract_conf.UnAutoIt_extract.binary)

if processing_conf.trid.enabled:
Expand Down
41 changes: 41 additions & 0 deletions lib/cuckoo/common/integrations/file_extra_info_modules/overlay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import logging
import os

from lib.cuckoo.common.integrations.file_extra_info_modules import (
ExtractorReturnType,
collect_extracted_filenames,
extractor_ctx,
time_tracker,
)
from lib.cuckoo.common.path_utils import path_write_file

# from base64 import b64encode


log = logging.getLogger(__name__)


@time_tracker
def extract_details(file, *, data_dictionary, **_) -> ExtractorReturnType:

if not data_dictionary.get("pe", {}).get("overlay"):
return {}

data = ""
overlay_size = int(data_dictionary["pe"]["overlay"]["size"], 16)
# Extract out the overlay data
try:
with open(file, "rb") as f:
f.seek(-overlay_size, os.SEEK_END)
data = f.read()
# data_dictionary["pe"]["overlay"]["data"] = b64encode(data[: min(overlay_size, 4096)])
except Exception as e:
log.error(e)

with extractor_ctx(file, "overlay", prefix="overlay") as ctx:
if data:
tempdir = ctx["tempdir"]
# You might need to change this 2 lines. See other examples in `file_extra_info.py`
_ = path_write_file(os.path.join(tempdir, "overlay"), data)
ctx["extracted_files"] = collect_extracted_filenames(tempdir)
return ctx
130 changes: 130 additions & 0 deletions modules/auxiliary/Mitmdump.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Copyright (C) 2024 [email protected]
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
# See the file 'docs/LICENSE' for copying permission.
# This module runs mitmdump to get a HAR file
# mitmdump is behind mitmproxy project https://mitmproxy.org/

import logging
import os
import socket
import subprocess
from threading import Thread

from lib.cuckoo.common.abstracts import Auxiliary
from lib.cuckoo.common.config import Config
from lib.cuckoo.common.constants import CUCKOO_ROOT
from lib.cuckoo.core.rooter import rooter

mitmdump = Config("mitmdump")

log = logging.getLogger(__name__)


class Mitmdump(Auxiliary):
"""Module for generating HAR with Mitmdump."""

def __init__(self):
Auxiliary.__init__(self)
Thread.__init__(self)
log.info("Mitmdump module loaded")
self.mitmdump_thread = None

def start(self):
"""Start mitmdump in a separate thread."""

self.mitmdump_thread = MitmdumpThread(self.task, self.machine)
self.mitmdump_thread.start()
return True

def stop(self):
"""Stop mitmdump capture thread."""
if self.mitmdump_thread:
self.mitmdump_thread.stop()


class MitmdumpThread(Thread):
"""Thread responsible for control mitmdump service for each analysis."""

def __init__(self, task, machine):
Thread.__init__(self)
self.task = task
self.machine = machine
self.do_run = True
self.host_ip = mitmdump.cfg.get("host")
self.host_iface = mitmdump.cfg.get("interface")
self.mitmdump_bin = mitmdump.cfg.get("bin")
self.proc = None
self.host_port = self._get_unused_port()
self.mitmdump_path = os.path.join(CUCKOO_ROOT, "storage", "analyses", str(self.task.id), "mitmdump")

def stop(self):
"""Set stop mitmdump capture."""
self.do_run = False

if self.proc and self.proc.poll() is None:
self.proc.terminate()
self.proc.wait()
log.info("Stopping mitmdump")

try:
rooter("disable_mitmdump", self.host_iface, self.machine.ip, self.host_port)
except subprocess.CalledProcessError as e:
log.error("Failed to execute firewall rules: %s", e)

def run(self):
"""Core function to the manage the module"""
if "mitmdump" not in self.task.options:
log.info("Exiting mitmdump. No parameter received.")
return

if self.do_run:
if not self.host_port:
log.exception("All ports in range are in use")
return

try:
rooter("enable_mitmdump", self.host_iface, self.machine.ip, self.host_port)
except subprocess.CalledProcessError as e:
log.error("Failed to execute firewall rules: %s", e)

try:
mitmdump_args = []
os.makedirs(self.mitmdump_path, exist_ok=True)
file_path = os.path.join(self.mitmdump_path, "dump.har")
mitmdump_args.extend(
[
self.mitmdump_bin,
"-q",
"--listen-host",
self.host_ip,
"-p",
str(self.host_port),
"--set",
"hardump=",
file_path,
]
)
mitmdump_args[-2:] = [
"".join(mitmdump_args[-2:])
] # concatenate the last two arguments, otherwise the HAR file will not be created.
self.proc = subprocess.Popen(mitmdump_args, stdout=None, stderr=None, shell=False)
except (OSError, ValueError):
log.exception("Failed to mitmdump (host=%s, port=%s, dump_path=%s)", self.host_ip, self.host_port, file_path)
return

log.info(
"Started mitmdump with PID %d (host=%s, port=%s, dump_path=%s)",
self.proc.pid,
self.host_ip,
self.host_port,
file_path,
)

def _get_unused_port(self) -> str | None:
"""Return the first unused TCP port from the set."""
ports = set(range(8001, 8081))
for port in ports:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
if s.connect_ex((self.host_ip, port)) != 0:
return str(port)
return None
70 changes: 0 additions & 70 deletions modules/processing/overlay.py

This file was deleted.

Loading

0 comments on commit 220b5e9

Please sign in to comment.