For the letter c we chose Cherokee project. It is a web server written mainly in C language. What’s interesting, this server may be met on IoT devices including GoPro cameras.
Our approach to find bugs was quite similar to the previous ones, but we decided to extend it in some ways.
Preparing
We started with preparing the environment for fuzzing.
During building we encountered a problem:
which was solved by setting ac_cv_func_realloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes.
So finally, we were able to build with:
After building:
Run the main server
and administration panel (with an option to listen on all network interfaces)
Fuzzing
Our idea was to test all handlers offered by the server. We enabled and made them available under paths /test1, /test2, …, /test19. Backed up configuration file is also available here.
Radamsa was run from a custom script. A few HTTP requests were taken as an input and after modification were sent to all handlers.
Additional tools
To improve result analysis we set up two additional tools. The first one - gcov, was already configured during the building (with compiler flags -fprofile-arcs -ftest-coverage). This tool helps in measuring code coverage. After some time of fuzzing it was beneficial to verify through how many code paths we went through.
While the application was running, special files *.gcda were created. They can be converted to HTML files with ease to read statistics.
As the result, coverage report in form of HTML document will appear in out directory.
The second tool - OpenGrok, was set up to help reading the code. It’s a source code browser, supporting cross-reference navigation and search options in a browser. Its installation and configuration process is well documented on the project’s page.
Results
By fuzzing we discovered several crashes in various handlers. All were reported on the Cherokee’s GitHub.
One of the interesting findings was in code responsible for handling headers before passing them to the CGI.
Structure cherokee_handler_cgi_t has fixed size array for environmental variables including request headers. When the handler processes a request it adds entries without checking whether boundary value was reached.
So, sending a request with enough headers causes writing outside the array.
XSS
Despite the bugs discovered by fuzzing, two reflected XSS vulnerabilities were found manually:
The first one affects only 400 Bad Request responses, thus it seems hard to be used against the user. The second one was found in the administration handler. This handler is used by default in the administration panel but also can be set up as a handler in the main server. The problem lies in copying the invoked URL to a response. The URL is not encoded before put in HTML, CSS and JavaScript code, so special characters can be placed by an attacker.
As an authenticated administrator has access to powerful options in the panel, we created a Proof of Concept exploit to show how this vulnerability can be used to achieve Remote Code Execution.
After opening the URL all actions are executed by the exploit, no further user interaction was required. For easier development this exploit simulates filling proper inputs in the panel which is quite slow, thus some parts of the video are sped up.
Summary
Utilizing fuzzing adjusted to the project’s features and additionally extending our approach with manual testing, several crashes and XSS vulnerabilities were found. One of them directly lead to RCE.
All reported bugs have been fixed.
Written on November 15, 2019 by
Mateusz Kocielski, Michał Dardas