Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
doomedraven committed Dec 25, 2023
2 parents 7b984d1 + 69e3b50 commit 1130fed
Show file tree
Hide file tree
Showing 19 changed files with 96 additions and 26 deletions.
4 changes: 0 additions & 4 deletions analyzer/windows/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
from lib.common.exceptions import CuckooError, CuckooPackageError
from lib.common.hashing import hash_file
from lib.common.results import upload_to_host
from lib.core.compound import create_custom_folders
from lib.core.config import Config
from lib.core.packages import choose_package
from lib.core.pipe import PipeDispatcher, PipeForwarder, PipeServer, disconnect_pipes
Expand Down Expand Up @@ -402,9 +401,6 @@ def run(self):
# E.g., for some samples it might be useful to run from %APPDATA%
# instead of %TEMP%.
if self.config.category == "file":
# Try to create the folders for the cases of the custom paths other than %TEMP%
if "curdir" in self.options:
create_custom_folders(self.options["curdir"])
self.target = self.package.move_curdir(self.target)
log.debug("New location of moved file: %s", self.target)

Expand Down
6 changes: 6 additions & 0 deletions analyzer/windows/lib/common/abstracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from lib.api.process import Process
from lib.common.exceptions import CuckooPackageError
from lib.core.compound import create_custom_folders

log = logging.getLogger(__name__)

Expand All @@ -17,6 +18,7 @@ class Package:
"""Base abstract analysis package."""

PATHS = []
default_curdir = None

def __init__(self, options=None, config=None):
"""@param options: options dict."""
Expand Down Expand Up @@ -154,8 +156,12 @@ def move_curdir(self, filepath):
"""
if "curdir" in self.options:
self.curdir = os.path.expandvars(self.options["curdir"])
elif self.default_curdir:
self.curdir = os.path.expandvars(self.default_curdir)
else:
self.curdir = os.getenv("TEMP")
# Try to create the folders for the cases of the custom paths other than %TEMP%
create_custom_folders(self.curdir)
newpath = os.path.join(self.curdir, os.path.basename(filepath))
shutil.move(filepath, newpath)
return newpath
Expand Down
9 changes: 9 additions & 0 deletions analyzer/windows/lib/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@
LOADER32_NAME = f"bin\\{random_string(7)}.exe"
LOADER64_NAME = f"bin\\{random_string(8)}.exe"
LOGSERVER_PREFIX = f"\\\\.\\PIPE\\{random_string(8, 12)}"

""" Excel, Word, and Powerpoint won't have macros enabled without interaction for
documents that are outside one of its "Trusted Locations". Unless the user has
provided a 'curdir' option, use MSOFFICE_TRUSTED_PATH as the directory where
the document will be saved and executed from since that is a default trusted
location for all 3 apps. See
https://learn.microsoft.com/en-us/deployoffice/security/trusted-locations
"""
MSOFFICE_TRUSTED_PATH = os.path.join("%SystemDrive%", "Program Files", "Microsoft Office", "root", "Templates")
3 changes: 3 additions & 0 deletions analyzer/windows/modules/packages/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

from lib.common.abstracts import Package
from lib.common.common import check_file_extension
from lib.common.constants import MSOFFICE_TRUSTED_PATH
from lib.common.exceptions import CuckooPackageError


class DOC(Package):
"""Word analysis package."""

default_curdir = MSOFFICE_TRUSTED_PATH

def __init__(self, options=None, config=None):
if options is None:
options = {}
Expand Down
3 changes: 3 additions & 0 deletions analyzer/windows/modules/packages/doc2016.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

from lib.common.abstracts import Package
from lib.common.common import check_file_extension
from lib.common.constants import MSOFFICE_TRUSTED_PATH


class DOC2016(Package):
"""Word analysis package."""

default_curdir = MSOFFICE_TRUSTED_PATH

def __init__(self, options=None, config=None):
if options is None:
options = {}
Expand Down
2 changes: 2 additions & 0 deletions analyzer/windows/modules/packages/doc_antivm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from lib.common.abstracts import Package
from lib.common.common import check_file_extension
from lib.common.constants import MSOFFICE_TRUSTED_PATH
from lib.common.exceptions import CuckooPackageError


Expand All @@ -16,6 +17,7 @@ class DOC_ANTIVM(Package):
("ProgramFiles", "Microsoft Office*", "root", "Office*", "WINWORD.EXE"),
("ProgramFiles", "Microsoft Office", "WORDVIEW.EXE"),
]
default_curdir = MSOFFICE_TRUSTED_PATH

def start(self, path):
# Determine if the submitter wants the sample to be monitored
Expand Down
3 changes: 3 additions & 0 deletions analyzer/windows/modules/packages/ppt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
# See the file 'docs/LICENSE' for copying permission.

from lib.common.abstracts import Package
from lib.common.constants import MSOFFICE_TRUSTED_PATH


class PPT(Package):
"""PowerPoint analysis package."""

default_curdir = MSOFFICE_TRUSTED_PATH

def __init__(self, options=None, config=None):
if options is None:
options = {}
Expand Down
3 changes: 3 additions & 0 deletions analyzer/windows/modules/packages/ppt2016.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
# See the file 'docs/LICENSE' for copying permission.

from lib.common.abstracts import Package
from lib.common.constants import MSOFFICE_TRUSTED_PATH


class PPT2007(Package):
"""PowerPoint analysis package."""

default_curdir = MSOFFICE_TRUSTED_PATH

def __init__(self, options=None, config=None):
if options is None:
options = {}
Expand Down
3 changes: 3 additions & 0 deletions analyzer/windows/modules/packages/xls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

from lib.common.abstracts import Package
from lib.common.common import check_file_extension
from lib.common.constants import MSOFFICE_TRUSTED_PATH


class XLS(Package):
"""Excel analysis package."""

default_curdir = MSOFFICE_TRUSTED_PATH

def __init__(self, options=None, config=None):
if options is None:
options = {}
Expand Down
3 changes: 3 additions & 0 deletions analyzer/windows/modules/packages/xls2016.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

from lib.common.abstracts import Package
from lib.common.common import check_file_extension
from lib.common.constants import MSOFFICE_TRUSTED_PATH


class XLS2207(Package):
"""Excel analysis package."""

default_curdir = MSOFFICE_TRUSTED_PATH

def __init__(self, options={}, config=None):
self.config = config
self.options = options
Expand Down
Empty file added docs/book/src/_static/.gitkeep
Empty file.
2 changes: 2 additions & 0 deletions docs/book/src/installation/host/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ The *conf/routing.conf* file contains information about how the guest VM is conn

Please see the latest version of routing.conf here: `routing.conf`_.

.. _`routing.conf`: https://github.com/kevoreilly/CAPEv2/blob/master/conf/routing.conf

You can read more about the *routing.conf* file and its options in the :ref:`routing` chapter and more about the ``rooter.py`` utility in the :ref:`rooter` chapter.


Expand Down
2 changes: 1 addition & 1 deletion docs/book/src/installation/host/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ Debugging ``iptables`` rules

Every single time the :ref:`rooter` brings up or down any route (assuming it works as expected) or you do so by using the `router_manager.py <https://github.com/kevoreilly/CAPEv2/blob/master/utils/router_manager.py>`_ utility, your iptables set of rules is modified in one way or another.

To inspect the changes being made and verify them, you can use the ``watch`` utility preinstalled in the vast majority of *nix systems. For example, to view rules created by CAPE-rooter or the utility you can run the following command::
To inspect the changes being made and verify them, you can use the ``watch`` utility preinstalled in the vast majority of \*nix systems. For example, to view rules created by CAPE-rooter or the utility you can run the following command::

$ sudo watch -n 1 iptables -L -n -v

Expand Down
8 changes: 7 additions & 1 deletion docs/book/src/usage/monitor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Depth
In single-step mode, the behaviour of a trace can be characterised in terms of whether it steps into a call, or over it. From this comes the concept of depth; the debugger will trace at the same depth in a trace by stepping-over calls to deeper functions. Thus if we set a depth of zero (which is also the default) the behaviour will be to step over all the subsequent calls (at least until a ret is encountered):

* ``depth=0``

If we set a depth of, say, three, then the debugger will step into calls into further levels of depth three times:

* ``depth=3``
Expand All @@ -31,9 +32,11 @@ Count
Another important characteristic of a trace is its length or count of instructions. This is set with the count option, for example:

* ``count=10000``

The count may also be specified as hexadecimal:

* ``count=0xff00``

The default count is 0x4000.

Break-on-return
Expand Down Expand Up @@ -118,9 +121,12 @@ br0, br1, br2, br3
Fake-rdtsc
==========
This advanced feature is there for interacting with the TSC register. To learn more on it and what it's used for see: https://en.wikipedia.org/wiki/Time_Stamp_Counter.

* To 'emulate' (skip and fake) the rdtsc instruction, the option fake-rdtsc=1 may be set. This will only have an affect on rdtsc instructions that are traced over by the debugger. If the debugger is not tracing at the time the CPU executes the instruction, it cannot of course fake the return value.
* The effect of this setting is to allow the first traced rdtsc instruction to execute normally, but thereafter to fake the return value with the original return value plus whatever value is specified in the option. For example:
* 'rdtsc=0x1000'

* 'rdtsc=0x1000'

* This will result in each subsequent rdtsc instruction after the first being faked with a value that has incremented by 0x1000.

Practical examples
Expand Down
26 changes: 20 additions & 6 deletions docs/book/src/usage/start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,19 @@ If you used poetry to install dependencies, you should launch cape with the foll

$ sudo -u cape poetry run python3 cuckoo.py

If you get any dependency-related error, make sure you execute the **extra/libvirt_installer.sh** script.::
If you get any dependency-related error, make sure you execute the **extra/libvirt_installer.sh** script::

$ sudo -u cape poetry run extra/libvirt_installer.sh

Troubleshooting
===============

If you wanted to launch CAPE and received an error like ``PermissionError: [Errno 13] Permission denied: '/opt/CAPEv2/log/cuckoo.log'`` it means that you are not executing the CAPE (cuckoo.py) file with the appropriate user. Remember that the user meant to execute CAPE is the `cape` user. In fact, after installing CAPE with ``cape2.sh``, the directory should look similar to the following structure:
``PermissionError: [Errno 13] Permission denied: '/opt/CAPEv2/log/cuckoo.log'``
-------------------------------------------------------------------------------
You are not executing the CAPE (``cuckoo.py``) file with the appropriate user.

Remember that the user meant to execute CAPE is the `cape` user.
In fact, after installing CAPE with ``cape2.sh``, the directory should look similar to the following structure:

.. image:: ../_images/screenshots/troubleshooting_0.png
:align: center
Expand All @@ -64,15 +69,22 @@ In order to execute CAPE as the ``cape`` user you can either launch a shell or e

$ sudo -u cape poetry run python3 cuckoo.py

If you get an error saying ``CuckooCriticalError: Cannot bind ResultServer on port 2042 because it was in use, bailing`` it means that the cape is already running in the background as ``cape.service``
``CuckooCriticalError: Cannot bind ResultServer on port 2042 because it was in use, bailing``
---------------------------------------------------------------------------------------------
CAPE is already running in the background as ``cape.service``

If you want to see the logs in realtime printed to stdout, stop the service by running the following command::

$ sudo systemctl stop cape.service

and run ``cuckoo.py`` again

If you get an error saying ``CuckooCriticalError: Unable to bind Result server on <IP> [Errno 99]`` check the ``cuckoo.conf`` configuration file again. You will have to provide the host IP for the ``[resultserver]``, not the guest IP.
======================================================
``CuckooCriticalError: Unable to bind Result server on <IP> [Errno 99]``
------------------------------------------------------------------------
Check the ``cuckoo.conf`` configuration file again.

You will have to provide the host IP for the ``[resultserver]``, not the guest IP.

Starting processing data generated by virtual machine
======================================================

Expand Down Expand Up @@ -100,4 +112,6 @@ See ``-h`` for all latest options, for better customization::
-pt PROCESSING_TIMEOUT, --processing-timeout PROCESSING_TIMEOUT
Max amount of time spent in processing before we fail a task

$ python3 utils/process.py -p7 auto
Command example::

$ python3 utils/process.py -p7 auto
16 changes: 11 additions & 5 deletions docs/book/src/usage/web.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,18 @@ To get rid of many bots/scrappers so we suggest deploying this amazing project `

Best practices for production
=============================
**Gunicorn + NGINX** is the recommended way of serving the CAPE web UI.

Gunicorn + NGINX is the recommended way of serving the CAPE web UI.

Gunicorn
--------
First, configure the ``cape-web`` service to use Gunicorn

Modify ``/lib/systemd/system/cape-web.service`` so the ``ExecStart``
setting is set to
``/usr/bin/python3 -m poetry run gunicorn web.wsgi -w 4 -t 200 --capture-output --enable-stdio-inheritance``.
setting is set to:

.. code:: systemd
ExecStart=/usr/bin/python3 -m poetry run gunicorn web.wsgi -w 4 -t 200 --capture-output --enable-stdio-inheritance
Run

Expand All @@ -131,6 +135,8 @@ Run
sudo systemctl daemon-reload
sudo service cape-web restart
NGINX
-----
Next, install NGINX and configure it to be a reverse proxy to Gunicorn.

.. code:: bash
Expand Down Expand Up @@ -257,7 +263,7 @@ Then restart NGINX
Add the following lines to the NGINX configuration, just below the ``client_max_body_size`` line.

.. code-block :: nginx
.. code-block:: nginx
auth_basic "Authentication required";
auth_basic_user_file /opt/CAPEv2/web/.htpasswd;
Expand Down
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ django-allauth = "0.54.0" # https://django-allauth.readthedocs.io/en/latest/con
# bingraph = {git = "https://github.com/CAPESandbox/binGraph.git", rev = "552d1210ac6770f8b202d0d1fc4610cc14d878ec"}
psycopg2-binary = "^2.9.5"
ruff = "0.0.290"
paramiko = "3.3.1"
paramiko = "3.4.0"

Werkzeug = "3.0.1"
packaging = "23.1"
Expand Down
Loading

0 comments on commit 1130fed

Please sign in to comment.