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 f78a9bb + da36b34 commit db495ec
Show file tree
Hide file tree
Showing 73 changed files with 1,429 additions and 1,378 deletions.
4 changes: 2 additions & 2 deletions .github/actions/python-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ runs:
- name: Install poetry
shell: bash
run: pip install poetry
run: PIP_BREAK_SYSTEM_PACKAGES=1 pip install poetry

- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@v5
Expand All @@ -27,4 +27,4 @@ runs:
- name: Install requirements
shell: bash
run: |
poetry install --no-interaction --no-root
PIP_BREAK_SYSTEM_PACKAGES=1 poetry install --no-interaction --no-root
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ A huge thank you to @D00m3dR4v3n for single-handedly porting CAPE to Python 3.
* Replace `<username>` with a real pattern.
* You need to replace all `<WOOT>` inside!
* Read it! You must understand what it does! It has configuration in header of the script.
* `sudo ./kvm-qemu.sh all <username> | tee kvm-qemu.log`
* `sudo ./kvm-qemu.sh all <username> 2>&1 | tee kvm-qemu.log`
4. To install CAPE itself, [cape2.sh](https://github.com/kevoreilly/CAPEv2/blob/master/installer/cape2.sh) with all optimizations
* Read and understand what it does! This is not a silver bullet for all your problems! It has configuration in header of the script.
* `sudo ./cape2.sh base | tee cape.log`
* `sudo ./cape2.sh base 2>&1 | tee cape.log`
5. After installing everything save both installation logs as gold!
6. Configure CAPE by doing mods to config files inside `conf` folder.
7. Restart all CAPE services to pick config changes and run CAPE properly!
Expand Down
16 changes: 16 additions & 0 deletions analyzer/windows/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,21 @@ def run(self):
except ImportError as e:
log.warning('Unable to import the auxiliary module "%s": %s', name, e)

def configure_aux_from_data(instance):
# Do auxiliary module configuration stored in 'data/auxiliary/<package_name>'
_class = type(instance)
try:
log.debug("attempting to configure '%s' from data", _class.__name__)
instance.configure_from_data()
except ModuleNotFoundError:
# let it go, not every module is configurable from data
log.debug("module %s does not support data configuration, ignoring", _class.__name__)
except ImportError as iexc:
# let it go but emit a warning; assume a dependency is missing
log.warning("configuration error for module %s: %s", _class.__name__, iexc)
except Exception as exc:
log.error("error configuring module %s: %s", _class.__name__, exc)

# Walk through the available auxiliary modules.
aux_modules = []

Expand All @@ -517,6 +532,7 @@ def run(self):
aux = module(self.options, self.config)
log.debug('Initialized auxiliary module "%s"', module.__name__)
aux_modules.append(aux)
configure_aux_from_data(aux)
log.debug('Trying to start auxiliary module "%s"...', module.__module__)
aux.start()
except (NotImplementedError, AttributeError) as e:
Expand Down
9 changes: 5 additions & 4 deletions analyzer/windows/data/yara/Formbook.yar
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ rule FormhookB
meta:
author = "kevoreilly"
description = "Formbook Anti-hook Bypass"
cape_options = "clear,bp0=$decode,action0=scan,hc0=1,bp1=$remap_ntdll+6,action1=setdst:ntdll,count=0,force-sleepskip=1"
cape_options = "clear,bp0=$entry,action0=scan,hc0=1,bp1=$new_remap+6,action1=setdst:ntdll,count=0,force-sleepskip=1"
packed = "08c5f44d57f5ccc285596b3d9921bf7fbbbf7f9a827bb3285a800e4c9faf6731"
strings:
$decode = {55 8B EC 83 EC 24 53 56 57 [480-520] 8B E5 5D C3}
$remap_ntdll = {90 90 90 90 90 90 8B (86 [2] 00 00|46 ??|06) 5F 5E 5B 8B E5 5D C3}
$remap_ntdll = {33 96 [2] 00 00 8D 86 [2] 00 00 68 F0 00 00 00 50 89 [2-5] E8 [4-10] 6A 00 6A 0? 8D 4D ?? 51 6A}
$entry = {55 8B EC 83 EC ?4 53 56 57 [480-520] 8B E5 5D C3}
$new_remap = {90 90 90 90 90 90 8B (86 [2] 00 00|46 ??|06) 5F 5E 5B 8B E5 5D C3}
condition:
any of them
2 of them
}

rule FormconfA
Expand Down
26 changes: 26 additions & 0 deletions analyzer/windows/lib/common/abstracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,29 @@ def add_pid(self, pid):

def del_pid(self, pid):
pass

def configure_from_data(self):
"""Do private auxiliary module-specific configuration.
Auxiliary modules can implement this method to perform pre-analysis
configuration based on runtime data contained in "data/auxiliary/<package_name>".
This method raises:
- ImportError when any exception occurs during import
- AttributeError if the module configure function is invalid
- ModuleNotFoundError if the module does not support configuration from data
"""
package_module_name = self.__class__.__module__.split(".")[-1]
module_name = f"data.auxiliary.{package_module_name}"
try:
mod = importlib.import_module(module_name)
except ModuleNotFoundError as exc:
raise exc
except Exception as exc:
raise ImportError(f"error importing {module_name}: {exc}") from exc

spec = inspect.getfullargspec(mod.configure)
if len(spec.args) != 1:
err_msg = f"{module_name}.configure: expected 1 arguments, got {len(spec.args)}"
raise AttributeError(err_msg)
mod.configure(self)
12 changes: 0 additions & 12 deletions analyzer/windows/modules/auxiliary/browsermonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ def __init__(self, options=None, config=None):
self.startupinfo = subprocess.STARTUPINFO()
self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
self.browser_logfile = ""
self.last_modification = 0.0
self._is_first_save = True

def _find_browser_extension(self):
temp_dir = tempfile.gettempdir()
Expand All @@ -54,22 +52,12 @@ def _find_browser_extension(self):
time.sleep(1)

def _collect_browser_logs(self):
if not self._is_first_save and self.last_modification != os.path.getmtime(self.browser_logfile):
return
self.last_modification = os.path.getmtime(self.browser_logfile)
upload_to_host(self.browser_logfile, "browser/requests.log")
self._is_first_save = False

def run(self):
self.do_run = True
if self.enabled:
self._find_browser_extension()
self.last_modification = os.path.getmtime(self.browser_logfile)
while self.do_run:
self._collect_browser_logs()
time.sleep(1)
return True
return False

def stop(self):
if self.enabled:
Expand Down
6 changes: 4 additions & 2 deletions analyzer/windows/modules/auxiliary/disguise.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,11 @@ def randomizeUUID(self):
SetValueEx(key, "MachineGuid", 0, REG_SZ, createdUUID)

def add_persistent_route(self):
self.run_as_system(["C:\\Windows\\System32\ROUTE.exe", "-p", "add", "0.0.0.0", "mask", "0.0.0.0", PERSISTENT_ROUTE_GATEWAY])
self.run_as_system(
["C:\\Windows\\System32\ROUTE.exe", "-p", "change", "0.0.0.0", "mask", "0.0.0.0", PERSISTENT_ROUTE_GATEWAY]
["C:\\Windows\\System32\\ROUTE.exe", "-p", "add", "0.0.0.0", "mask", "0.0.0.0", PERSISTENT_ROUTE_GATEWAY]
)
self.run_as_system(
["C:\\Windows\\System32\\ROUTE.exe", "-p", "change", "0.0.0.0", "mask", "0.0.0.0", PERSISTENT_ROUTE_GATEWAY]
)

def start(self):
Expand Down
48 changes: 0 additions & 48 deletions analyzer/windows/modules/packages/Shellcode-Unpacker.py

This file was deleted.

42 changes: 0 additions & 42 deletions analyzer/windows/modules/packages/Unpacker.py

This file was deleted.

64 changes: 0 additions & 64 deletions analyzer/windows/modules/packages/Unpacker_dll.py

This file was deleted.

47 changes: 0 additions & 47 deletions analyzer/windows/modules/packages/Unpacker_js.py

This file was deleted.

37 changes: 0 additions & 37 deletions analyzer/windows/modules/packages/Unpacker_ps1.py

This file was deleted.

Loading

0 comments on commit db495ec

Please sign in to comment.