The code and dataset of the paper are at https://github.com/Siyuan-Li201/TransferFuzz.
We introduce TransferFuzz, a novel vulnerability verification framework, to verify whether vulnerabilities propagated through code reuse can be triggered in new software.
- Input: A fuzz driver script of the target binary. A basic binary with PoC.
- Output: The PoCs of the target binary.
We have enhanced the code and documentation to automate all steps:
- Function-level Trace Extraction. We wrote Python scripts to automate calls to GDB to extract function call stacks after crashes.
- Key-bytes Trace Extraction. We use PIN \cite{pin} for taint analysis and judge whether tainted bytes come directly from POC bytes.
- Trace Guided Fuzzing: We wrap the modified code parts in macro definitions, enabling easy migration to new fuzzing technologies.
- Crash Classification. We wrote a shell script to automatically determine whether the fuzzing process is finished by viewing the crash address through GDB.
- code: The sourcecode of TransferFuzzt
- bin: The 76 binaries used in the paper (along with two .so file). Since Git LFS is not easily accessible, you can download all binaries from bin here.
- poc: The 53 POCs of the 15 CVE vulnerabilities. Since Git LFS is not easily accessible, you can download all POCs from poc here.
- Download the binaries and POCs from
/bin
and/poc
. - Execute the binaries with poc by the harness below. (To meet environment dependencies, it is recommended to run in the provided Docker container.)
- tiffsplit-2016-10095: tiffsplit @@
- tiffsplit-2016-5318: tiffsplit @@
- thumbnail-2016-10095: thumbnail @@
- thumbnail-2016-5318: thumbnail @@
- tiffcmp-2016-10095:tiffcmp @@ @@
- tiffcmp-2016-5318: tiffcmp @@ @@
- cxxfilt-2016-4487: cxxfilt < @@
- cxxfilt-2016-4489: cxxfilt < @@
- cxxfilt-2016-4490: cxxfilt < @@
- cxxfilt-2016-4491: cxxfilt < @@
- cxxfilt-2016-4492: cxxfilt < @@
- cxxfilt-2016-6131: cxxfilt < @@
- objdump-2016-4487: objdump -t -C @@
- objdump-2016-4489: objdump -t -C @@
- objdump-2016-4490: objdump -t -C @@
- objdump-2016-4491: objdump -t -C @@
- objdump-2016-4492: objdump -t -C @@
- objdump-2016-6131: objdump -t -C @@
- nm-new-2016-4487: nm-new -C @@
- nm-new-2016-4489: nm-new -C @@
- nm-new-2016-4490: nm-new -C @@
- nm-new-2016-4491: nm-new -C @@
- nm-new-2016-4492: nm-new -C @@
- nm-new-2016-6131: nm-new -C @@
- addr2line-2016-4487: addr2line -e @@ -C -f 0x3dc8
- addr2line-2016-4489: addr2line -e @@ -C -f 0x3dc8
- addr2line-2016-4490: addr2line -e @@ -C -f 0x3dc8
- addr2line-2016-4491: addr2line -e @@ -C -f 0x0000
- addr2line-2016-4492: addr2line -e @@ -C -f 0x3dc8
- addr2line-2016-6131: addr2line -e @@ -C -f 0x0000
- strip-2017-7303: strip -o /dev/null @@
- objcopy-2017-7303: objcopy @@
- swftophp-2017-11733: swftophp @@
- swftophp-2018-8807: swftophp @@
- swftophp-2018-8962: swftophp @@
- swftoperl-2017-11733: swftoperl @@
- swftoperl-2018-8807: swftoperl @@
- swftoperl-2018-8962: swftoperl @@
- swftocxx-2017-11733: swftocxx @@
- swftocxx-2018-8807: swftocxx @@
- swftocxx-2018-8962: swftocxx @@
- swftopython-2017-11733: swftopython @@
- swftopython-2018-8807: swftopython @@
- swftopython-2018-8962: swftopython @@
- swftotcl-2017-11733: swftotcl @@
- swftotcl-2018-8807: swftotcl @@
- swftotcl-2018-8962: swftotcl @@
- libav-2018-11102: avconv -y -i @@
- ffmpeg-2018-11102: ffmpeg -y -i @@
- libjpeg-turbo-2018-20330: tjbench @@ 90
- mozjpeg-2018-20330: tjbench @@ 90
- poppler-2017-18267: poppler @@
- xpdf-2017-18267: xpdf @@
TransferFuzz is built on SelectFuzz. Since SelectFuzz's Docker image is relatively large, TransferFuzz is also large. For a more flexible build, you can also compile it yourself.
1 sudo docker pull anonymous4paper/transferfuzz
# You need to execute "echo core >/proc/sys/kernel/core_pattern" on the host to support AFL fuzzing.
Place the /code
directory in the root (/
) of the SelectFuzz environment and rename it to /transferfuzz
.
You can ignore error messages when executing "make" commands in /transferfuzz/llvm_mode
.
1 cd /transferfuzz
2 make clean all
3 cd llvm_mode
4 make clean all
You can quickly verify the data in the paper with the following command.
1 cd /transferfuzz/scripts/evaluation/
2 ./tiffcmp-2016-10095.sh
# When "Hamed: Finished PAG initialization..." is displayed, it may take some time (especially for a large project like binutils, which may take 10-20 minutes). This is the static analysis step of SelectFuzz, has nothing to do with the technology of this paper, and the time is acceptable.
Many crashes will be generated during the fuzzing process. The auto_verify.sh script can be used to determine whether the expected POC is generated in the current crashes directory.
the string "poc" in <command>
will be replaced by POCs in <crash_dir>
, which is similar to the "@@" used in AFL.
Usage:
1 cd /transferfuzz/scripts/verify
2 ./auto_verify.sh <binary_path> <command> <crash_dir> <crash_address>
3 cat ./result.txt
# Due to different project version, some vuls automatic verification may fail. You can read the crash_report.txt and check whether the verification is successful by function sequence.
Example:
1 cd /transferfuzz/scripts/verify
2 ./auto_verify.sh /transferfuzz/scripts/evaluation/tiffcmp-2016-10095/obj-dist/tools/tiffcmp "poc poc" /transferfuzz/scripts/evaluation/tiffcmp-2016-10095/obj-dist/out/crashes "tif_dir.c:1056"
3 cat ./result.txt
We use another binary objdump as an example too to demonstrate the usage:
1 ./auto_verify.sh /data/bin/binutils_2.26/objdump "-t -C poc" /result/objdump-2016-4487/crashes "cplus-dem.c:4319"
You can run the complete TransferFuzz with the following command. (e.g. Use tiffsplit as basic binary and tiffcmp as target binary)
Automatically generate the cve-2016-10095-functrace.txt
file.
Put the basic binary and poc into the directory /data/bin/
and /data/poc/
(The basic binary tiffsplit can be found at /bin of github and the poc tiffsplit-2016-10095-poc can be found at /poc or generated by Directed Fuzzing)
1 cd /transferfuzz/scripts/func_trace
2 ./get_trace.sh /data/bin/tiffsplit "poc" /data/poc ./result.txt
3 python3 ./deal_trace.py ./result.txt cve-2016-10095-functrace.txt
Automatically generate the cve-2016-10095-keybytes.txt
file.
Put the basic binary and poc into the directory ./bin/
and ./poc/
(The basic binary tiffsplit can be found at /bin of github and the poc tiffsplit-2016-10095-poc can be found at /poc or generated by Directed Fuzzing)
1 cd /transferfuzz/scripts/keybytes_trace
2 pin -t ./taint_test.so -i ./poc/tiffsplit-2016-10095-poc -v tiffcp -- ./bin/tiffsplit ./poc/tiffsplit-2016-10095-poc
3 python3 get_fuzz_dict.py ./taint_trace.out ./cve-2016-10095-keybytes.txt
put the cve-2016-10095-functrace.txt
to /transferfuzz/scripts/fuzz_functrace/
and rename it to cve-2016-10095.txt
.
put the cve-2016-10095-keybytes.txt
to /transferfuzz/scripts/fuzz_dict/
and rename it to cve-2016-10095.txt
.
1 cd /transferfuzz/scripts/evaluation
2 ./tiffcmp-2016-10095.sh
1 cd /transferfuzz/scripts/verify
2 ./auto_verify.sh /transferfuzz/scripts/evaluation/tiffcmp-2016-10095/obj-dist/tools/tiffcmp "poc poc" /transferfuzz/scripts/evaluation/tiffcmp-2016-10095/obj-dist/out/crashes "tif_dir.c:1056"
3. cat ./result.txt
- Prepare a basic binary and a target binary that reuses the code from the basic binary.
- Prepare a basic poc or generate poc by Directed Fuzzing.
- Run the Function-level Trace Extraction module and the Key-bytes Trace Extraction module to extract traces.
- Run Trace Guided Fuzzing for the target binary.
- Run the Auto crash classification to check vulnerability propagation.
35 of the 38 new vuls in the paper were successful. In addition to the three unverified vulnerabilities presented in the paper, we also discovered two others (CVE-2022-34526 and CVE-2017-9147) that also could not be verified. We analyzed these bad cases to inform future research. The main reasons for the unverifiable vulnerabilities are as follows:
- Existing methods are prototypes and require additional engineering efforts, such as in-process instrumentation, to adapt to more software (For three unverified vulnerabilities presented in the paper).
- Some vulnerabilities are difficult to trigger by fuzzing, and there are no key bytes to bypass the conditional branch (For CVE-2022-34526 and CVE-2017-9147).
We use macro definitions in /code
to wrap all the code that needs to be modified.
We have successfully implemented TransferFuzz based on AFLGo, WindRanger and SelectFuzz. If you want to support more frameworks, please contact us.