How I built a lightweight MITM-based web-app fuzzer
Since a year ago, I’ve spent most of my working time on doing blackbox pen-test websites, and there I felt too lazy to have a look at every request in the Burp Target (I am a big fan of Burp Suite), I started to build a MITM-based web-app fuzzer, that names “midf”. This article is my share about mechanisms and ideas inside that project. If you want to discuss or have any idea, please feel free to send me a DM via my twitter @tungpun_ or reach me at firstname.lastname@example.org.
The midf’s mission is to detect automatically common security issues, that took me much time in Burp Repeater. So far, they are Reflected Cross-site Scripting (XSS), SQL Injection, RFI, Command Injection, CLRF, SSI and some Information Disclosure cases.
It has two main parts: an agent and a server.
The agent actually is a Burp Suite extension, and it will send every request’s headers transmitted to the server. I used Java because Burp Suite has been developed by Java also.
The sending data includes hostname’s information and request headers. I encrypted them using a symmetric-key algorithm.
The second part, server has been structured as follow:
| +--- configuration files
| +--- Logs // a class defines how to handle logs (HTTP and message)
| +--- Net // a class that has function to send requests
| +--- Notifier // a class, whose purpose is to send message to users
| +--- Parser // contains other stuffs, that parse/convert datas
| +--- Scanner // main class, that calls aboves class based on specific case
| +--- csrf
| +--- generic
| +--- rfi
| +--- sqli
| +--- xss
In this case, Flask stands as a web-server, which receives requests from the above agent, decrypts, then pushes to a Redis queue. Each Redis worker inits an object from Scanner class. Then, this object assigns the requests to plugins for scanning.
If is there anything found, Notifier class will be called, then send a message to my channel on Slack. I have to pay attention to False/Positive cases, or the fuzzer will fill my Slack with dummy messages. One of my efforts to reduce the F/P rate and improve midf’s performance is to build a hashmap of requests using Redis keys. The hashmap’s purpose is to ensure that every individual request only is sent once in a specific time-delta (2 days in detail).
The programming language, which has been chosen to implement the server, is python because of its powerfulness and simplicity.
Dig deeper into the plugins
When developing the plugin, I tried to make it easy to read, maintain and improve. To add a new test case, the developer only need pay attention to the payloads, and specific response in the vulnerable case. The hard thing is how to avoid redundant signatures, or how to make the minimum number of payloads in the signature list, which could detect many cases as possible.
So far, plugins only inject payloads into 3 points: path, GET and POST data. I’m thinking about some other injecting points in the request header as User-Agent.
After discovering some information leak signatures from Google Dork, Shodan…, I use them to build the generic plugin, that ensure every public .git/.svn/… repo directory and .htaccess/info.php/server-status… files in the target website will be caught.
With SQL Injection, I spent my effort to try to detect Blind SQLi case mainly. As this plugin ofter brings me so much F/P case, heuristics computation will be needed in the future.
I have to say CRLF detection in midf is naive. The only payload is:
Then the plugin will check if the header midfheader exists in the response or not.
Inspired from Burp Suite’s Collaborator, this project has a module named midf_collaborator, that check access log in the honeypot server and will notify us if is there any other entry found.
I understand that there is so much thing that could be implemented into this project, and hope so it could be received the comment/suggestion to be much more efficient.