1594714443
This is the very long tale of my adventures in fuzzing FastCGI with AFL-Fuzz. If you’re interested in fuzzing a FastCGI binary, look no further.
FastCGI is a binary protocol. In most cases a user interacts with a web server such as nginx or lighttpd, which in turn communicates with FastCGI through a named pipe or TCP connection. FastCGI then executes code.
I had access to a binary written in C/C++ which used FastCGI. In fact, FastCGI is used in almost every embedded device. The most popular version is FCGI 2.4.0 by OpenMarket, which is 17 years old.
There is also no documentation or research regarding fuzzing FastCGI(except this one).
According to RFC 3875, a FCGX_Request is mainly two parts:
You can’t just send HTTP Requests to FastCGI, it’s a binary protocol. The hexdump of a FastCGI request looks like this:
Top = envp. Bottom = params
The above request was captured during research by copying the named pipe, and using socat to intercept requests using the following command:
socat -t100 -v -x UNIX-LISTEN:fcgi_sock,mode=777,reuseaddr,fork UNIX-CONNECT:fcgi_sock2,raw
#iot #security #hacking
1594714443
This is the very long tale of my adventures in fuzzing FastCGI with AFL-Fuzz. If you’re interested in fuzzing a FastCGI binary, look no further.
FastCGI is a binary protocol. In most cases a user interacts with a web server such as nginx or lighttpd, which in turn communicates with FastCGI through a named pipe or TCP connection. FastCGI then executes code.
I had access to a binary written in C/C++ which used FastCGI. In fact, FastCGI is used in almost every embedded device. The most popular version is FCGI 2.4.0 by OpenMarket, which is 17 years old.
There is also no documentation or research regarding fuzzing FastCGI(except this one).
According to RFC 3875, a FCGX_Request is mainly two parts:
You can’t just send HTTP Requests to FastCGI, it’s a binary protocol. The hexdump of a FastCGI request looks like this:
Top = envp. Bottom = params
The above request was captured during research by copying the named pipe, and using socat to intercept requests using the following command:
socat -t100 -v -x UNIX-LISTEN:fcgi_sock,mode=777,reuseaddr,fork UNIX-CONNECT:fcgi_sock2,raw
#iot #security #hacking
1613706044
I was recently looking through some of Google’s open source repositories on their GitHub. And I saw that they had a repository for continuous fuzzing. I had no idea what fuzzing even was, let alone continuous fuzzing.
Fuzzing (sometimes called fuzz testing) is a way to automatically test software. Generally, the fuzzer provides lots of invalid or random inputs into the program. The test tries to cause crashes, errors, memory leaks, and so on.
Normally, fuzzing works best on programs that take inputs, like websites that might ask for your name and age as an input.
We could try all sort of different strings to try and cause issues, maybe something like: “Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗” (this crashed iOS in the past), “Ṯ̤͍̥͇͈h̲́e͏͓̼̗̙̼̣͔ ͇̜̱̠͓͍ͅN͕͠e̗̱z̘̝̜̺͙p̤̺̹͍̯͚e̠̻̠͜r̨̤͍̺̖͔̖̖d̠̟̭̬̝͟i̦͖̩͓͔̤a̠̗̬͉̙n͚͜ ̻̞̰͚ͅh̵͉i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟”, “😍” or “undefined”.
The whole idea behind fuzzing is to try and find edge cases in a codebase. You use it to make sure that all the parsing you do, acceptance of the data, storing of the data, and reading the data causes no bugs.
It’s quite an integrated test, too, as you can test the complete flow of storing something like a zero-width space (U+200B in Unicode) in your site to check for issues.
Some people try to inject code into the input fields (this is a part of fuzzing referred to as code injection) like <script>alert(123)</script>
as a name input.
Malicious hackers don’t want you to test non-standard input, as you might have application breaking bugs – and they can utilise this to steal data or repeatedly crash your application/servers.
Have a look at this GitHub called the Big List of Naughty Strings. It is a list of strings that have a high probability of causing issues.
You can have a look at some of the .json
and .txt
files to see what has caused issues in the past, and read some of the comments to learn exactly why they are problematic.
For example, there are some strings that are written upside-down “uʍopǝpᴉsd∩” which you can do here. There are strings that may be flagged as profanity or inappropriate but are actually innocent (this is called the Scunthorpe problem). Or even strings that can reveal system files if they are parsed by a poorly configured XML parser.
#testing #fuzzing #developer
1589790988
In the last months I’ve been working developing fuzzing targets to find bugs and create patches for the Wasmer WebAssembly runtime.
In this post we will learn what is fuzzing, why it is important for WebAssembly runtimes and what kind of bugs fuzzing helped to detect.
#webassembly #development #testing #fuzzing #security
1633938606
Fuzzing the Kernel using UnicornAFL and AFL++. For details, skim through the WOOT paper or watch this talk at CCCamp19.
yes.
./setup.sh
, preferrably inside a Virtualenv (else python deps will be installed using --user
). During install, afl++ and uDdbg as well as python deps will be pulled and installed.ucf
When upgrading from an early version of ucf:
ucf spec
to output a commented config.py
spec-like element.probe_wrapper.py
is now ucf attach
.harness.py
is now named ucf emu
.cat /proc/modules
to find out the base address of the module location. Use this as the offset for the function where you want to break. If you specify MODULE
and BREAK_OFFSET
in the config.py
, it should use ./get_mod_addr.sh
to start it automated.gdb vmlinux
. After having loaded other modules you can use the lx-symbols
command in gdb to load the symbols for the other modules (make sure the .ko files of the modules are in your kernel folder). This way you can just use something like break function_to_break
to set breakpoints for the required functions.DEBUG_KERNEL=y
, DEBUG_INFO=y
, GDB_SCRIPTS=y
(for convenience), KASAN=y
, KASAN_EXTRA=y
. For convenience, we added a working example_config that can be place to the linux dir.lsmod > mylsmod
and copy the mylsmod file to your host system into the linux kernel folder that you downloaded. Then you can use make LSMOD=mylsmod localmodconfig
to only make the kernel modules that are actually needed by the guest system. Then you can compile the kernel like normal with make
. Then mount the guest file system to /mnt
and use make modules_install INSTALL_MOD_PATH=/mnt
. At last you have to create a new initramfs, which apparently has to be done on the guest system. Here use mkinitcpio -k <folder in /lib/modules/...> -g <where to put initramfs>
. Then you just need to copy that back to the host and let qemu know where your kernel and the initramfs are located.BREAKADDR
in the config.py
instead.sudo ./setaflops.sh
to initialize your system for fuzzing../startvm.sh
config.py
:place_input
func config.py
ucf attach
, it will (try to) connect to gdb.ucf fuzz
. Make sure afl++ is in the PATH. (Use ./resumeafl.sh
to resume using the same input folder)Putting afl's input to the correct location must be coded invididually for most targets. However with modern binary analysis frameworks like IDA or Ghidra it's possible to find the desired location's address.
The following place_input
method places at the data section of sk_buff
in key_extract
:
# read input into param xyz here:
rdx = uc.reg_read(UC_X86_REG_RDX)
utils.map_page(uc, rdx) # ensure sk_buf is mapped
bufferPtr = struct.unpack("<Q",uc.mem_read(rdx + 0xd8, 8))[0]
utils.map_page(uc, bufferPtr) # ensure the buffer is mapped
uc.mem_write(rdx, input) # insert afl input
uc.mem_write(rdx + 0xc4, b"\xdc\x05") # fix tail
A few general pointers. When using ./startvm.sh
, the VM can be debugged via gdb. Use
$gdb
>file ./linux/vmlinux
>target remote :1234
This dynamic method makes it rather easy to find out breakpoints and that can then be fed to config.py
. On top, startvm.sh
will forward port 22 (ssh) to 8022 - you can use it to ssh into the VM. This makes it easier to interact with it.
You can step through the code, starting at the breakpoint, with any given input. The fancy debugging makes use of uDdbg. To do so, run ucf emu -d $inputfile
. Possible inputs to the harness (the thing wrapping afl-unicorn) that help debugging:
-d
flag loads the target inside the unicorn debugger (uDdbg) -t
flag enables the afl-unicorn tracer. It prints every emulated instruction, as well as displays memory accesses.
A few things to consider.
Unicorn did not offer a way to directly set model specific registers directly. The forked unicornafl version of AFL++ finally supports it. Most ugly code of earlier versions was scrapped.
Right now, the Unicorefuzz ucf attach
harness might need to be manually restarted after an amount of pages has been allocated. Allocated pages should propagate back to the forkserver parent automatically but might still get reloaded from disk for each iteration.
It's generally a good idea to nop out kprintf or kernel printing functionality if possible, when the program is loaded into the emulator.
If you got trouble running unicorefuzz, follow these rulse, worst case feel free to reach out to us, for example to @domenuk on twitter. For some notes on debugging and developing ucf and afl-unicorn further, read DEVELOPMENT.md
Run the harness without afl (ucf emu -t ./sometestcase
). Make sure you are not in a virtualenv or in the correct one. If this works but it still crashes in AFL, set AFL_DEBUG_CHILD_OUTPUT=1
to see some harness output while fuzzing.
Make sure ucf attach
is running, in the same folder, and breakpoint has been triggered.
Author: fgsect
Download Link: Download The Source Code
Official Website: https://github.com/fgsect/unicorefuzz
License: Apache-2.0 License
1650951264
Fuzz testing is a software testing technique used to find security and stability issues by providing pseudo-random data as input to the software. AFLplusplus is a popular, effective, and modern fuzz testing tool based on AFL. This library, afl.rs, allows one to run AFLplusplus on code written in the Rust programming language.
Documentation can be found in the Rust Fuzz Book.
Screen recording of AFL running on Rust code.
lazy_static
variableslazy_static
variables present problems for AFL's persistent mode, which afl.rs uses. Such variables can cause AFL to give incorrectly low stability reports, or fail to report timeouts, for example.
To address such problems, rust-fuzz provides a "resettable" version of lazy_static
. To use it, make the following two changes to your target's Cargo.toml
file.
[patch.crates-io]
section and override the lazy_static
dependency with the rust-fuzz version:[patch.crates-io]
lazy_static = { git = "https://github.com/rust-fuzz/resettable-lazy-static.rs" }
2. Enable the reset_lazy_static
feature on afl.rs:
[dependencies]
afl = { version = "*", features = ["reset_lazy_static"] }
Download Details:
Author: rust-fuzz
Source Code: https://github.com/rust-fuzz/afl.rs
License: Apache-2.0 License