attack_surface_approximation is the CRS module that deals with the approximation of the attack surface in a vulnerable program.
Some input mechanisms are omitted: elements of the user interface, signals, devices and interrupts. At the moment, the supported mechanisms are the following:
- files
- command-line arguments
- standard input
- networking
- environment variables
In addition, a custom fuzzer is implemented to discover arguments that trigger different code coverage. It takes arguments from a dictionary which can be handcrafted or generated with an exposed command, with an implemented heuristic.
Examples of arguments dictionaries can be found in examples/dictionaries:
man.txt: generated with theman_parsingheuristic and having 6605 entriesgeneration.txt: generated with thegenerationheuristic and having 62 entries
- ELF format
- x86 architecture
- dynamic binaries (static binaries are not supported)
- symbols present (namely, no stripping is involved)
- no obfuscation technique involved
The module works by automating Ghidra for static binary analysis. It extracts information and applies heuristics to determine if a given input stream is present.
Examples of such heuristics are:
- for standard input: calls to
getc()andgets() - for networking: calls to
recv()andrecvfrom() - for command-line arguments: occurrences of
argcandargvinmain()
The argument fuzzer uses Docker for running and QBDI to detect basic-block coverage.
-
Make sure you have set up the repositories and Python environment according to the top-level instructions. That is:
-
Docker is installed and is properly running. Check using:
docker version docker ps -a docker run --rm hello-world
These commands should run without errors.
-
The current module repository and all other module repositories (particularly the
datasetrepository and thecommonsrepository) are cloned in the same directory. -
You are running all commands inside a Python virtual environment. There should be
(.venv)prefix to your prompt. -
You have installed Poetry in the virtual environment. If you run:
which poetryyou should get a path ending with
.venv/bin/poetry.
-
-
Disable the Python Keyring:
export PYTHON_KEYRING_BACKEND=keyring.backends.null.KeyringThis is a problem that may occur in certain situations, preventing Poetry from getting packages.
-
Install the required packages with Poetry (based on
pyprojects.toml):poetry install --only main -
Create the
ghidraandqbdi_args_fuzzingDocker images by using the instructions in thecommonsrepository. -
Optionally, generate executables by using the instructions in the
datasetrepository.
You can use the attack_surface_approximation module either standalone, as a CLI tool, or integrated into Python applications, as a Python module.
As a CLI tool, you can either use the cli.py module:
python attack_surface_approximation/cli.pyor the Poetry interface:
poetry run attack_surface_approximation$ poetry run attack_surface_approximation generate --heuristic man_parsing --output args.txt --top 100
Successfully generated dictionary with 10 arguments
$ head args.txt
--allow-unrelated-histories
--analysis-display-unstable-clusters
--auto-area-segmentation
--backup-dir
--callstack-filter
--cidfile
--class
--codename
--column
--containedUse an ELF i386 (32 bit) executable as target for detecting input streams.
For example, you can use one of the executables generated in the dataset repository:
$ ../dataset/executables/toy_test_suite_1.elf
Gimme two lines of input:
aaa
bbbNow, do the attack surface approximation:
$ poetry run attack_surface_approximation detect --elf $(pwd)/../dataset/executables/toy_test_suite_1.elf
Several input mechanisms were detected for the given program:
ββββββββββββββββββββββββ³ββββββββββ
β Stream β Present β
β‘βββββββββββββββββββββββββββββββββ©
β STDIN β Yes β
β ARGUMENTS β Yes β
β FILES β Yes β
β ENVIRONMENT_VARIABLE β Yes β
β NETWORKING β Yes β
ββββββββββββββββββββββββ΄ββββββββββThe executable used uses all potential input streams.
$ poetry run attack_surface_approximation fuzz --elf $(pwd)/../dataset/executables/toy_test_suite_1.elf --dictionary args.txt
Several arguments were detected for the given program:
βββββββββββββββ³βββββββββββββββββ
β Argument β Role β
β‘βββββββββββββββββββββββββββββββ©
β - β FLAG β
β --re β FLAG β
β --re string β STRING_ENABLER β
β -mmusl β FLAG β
βββββββββββββββ΄βββββββββββββββββ$ poetry run attack_surface_approximation
Usage: attack_surface_approximation [OPTIONS] COMMAND [ARGS]...
Discovers the attack surface of vulnerable programs.
Options:
--help Show this message and exit.
Commands:
analyze Analyze with all methods.
detect Statically detect what input streams are used by an executable.
fuzz Fuzz the arguments of an executable.
generate Generate dictionaries with arguments, based on heuristics.from attack_surface_approximation.static_input_streams_detection import \
InputStreamsDetector
detector = InputStreamsDetector(elf_filename)
streams_list = detector.detect_all()from attack_surface_approximation.arguments_fuzzing import ArgumentsFuzzer
fuzzer = ArgumentsFuzzer(elf_filename, fuzzed_arguments)
detected_arguments = fuzzer.get_all_valid_arguments()