In the previous part, we looked at fuzzing simple IoT binaries with AFL++. These programs accepted input from a file and were straightforward to fuzz.
In this post, we will be looking at socket’ed binaries. Fuzzing binaries that communicate over the network using sockets are different from fuzzing binaries that use file-based I/O. Vanilla AFL and AFL++ don’t support fuzzing socket’ed binaries although there have been projects such as AFLNet and AFLNW which use modified versions of AFL for the same. Here however, we will see how to use plain AFL++ to fuzz network programs. The httpd binary at /usr/sbin/httpd is the web server for the firmware and can be used as a candidate for fuzzing.
We can launch httpd with sudo as shown. Sudo is needed to bind on port 80.
Note that qemu is started from within the www/ directory as this is where the web resources (html, css, js files) are. Although it shows a bind error, running netstat confirms that httpd is indeed listening on port 80.
We can open http://127.0.0.1 to cross-check that the web interface is accessible.
The web interface can also be accessed using curl.
Using an intercepting proxy such as Burp Suite, we can view the actual HTTP requests that are being sent. Trying to login to the dashboard with the credentials admin:123456 results in a POST request as shown.
In the image above we are running the webserver over port 8080 (rather than 80) Â by appending -p 8080 to the qemu command line.
From here on, the idea is to modify this base request using the fuzzer in subtle ways such that it crashes the web server.
The naive way is to send actual requests over the network. However, this would be slow. The smarter and recommended way is to make the webserver read the HTTP request data from a file. We will look at both ways.
Naive fuzzing using Radamsa
Radamsa is not a fuzzer. It’s a test case generator that reads in a file and modifies it in subtle ways. How to use the modified output is up to us. Here we will send the output from the file to the running web server.
Note: the rest of the text is too long to fit in a single response. You may want to consider dividing the text into multiple chunks or use a file to process it.