Fuzzing Web Sockets With ZAP
Mon 15 July 13
The following article is part two of my introduction to ZAP and testing web sockets, in this episode I'll cover fuzzing. If you've not used ZAP before I suggest you look at some of the official tutorials first - ZAP home page, Videos. You can find my first part here OWASP ZAP and Web Sockets.
The testing is being done against a small web sockets based app I wrote called SocketToMe which has a few published services along with a few unpublished ones. In this article we are going to look at one of the published ones and try to identify some of the unpublished ones.
The first feature I'll investigate is the number guessing game. Here the system picks a random number between 1 and 100 and you have to guess it. I'm going to cheat and see if I can get ZAP to play all 100 numbers for me to go for a quick win.
The first thing to do is to find how the guesses are sent to the server. With ZAP intercepting, make a few guesses and watch the traffic. Looking in the WebSockets tab you should see the guesses and, unless you are really lucky, the rejection messages from the server.
To start the fuzzing you need to tell ZAP the injection point you want to fuzz. To do this select a message from the bottom window and it will appear in the window top right. In this case the message is "G:42" so I would assume that the G is the command, : is the separator and 42 is the guess I made. To tell ZAP where you want to inject simply highlight it, right click and choose fuzz. Here it is the 42 as that is the specific bit of data I want to alter.
If you are a Burp user coming across to ZAP for the first time then there is a big difference between how Burp's intruder handles fuzzing and how ZAP handles it. I think Burp does it a lot better, offering much more choice and flexibility but that may just be because I'm missing something in ZAP. I can't find any tutorials on fuzzing beyond those that simply select existing data so if I am missing something feel free to tell me I'm wrong and explain why.
One of the main differences between Burp and ZAP is that where Burp has all the different options of how to generate the list of values to fuzz, ZAP only allows you to select from pre-generated lists. There are a lot of lists built in and I initially looked in the "jbrofuzz / Number Systems" category from where I chose "Base10 (DEC)". I was expecting a second dialog asking start and end values but the fuzz started straight away and ran through the values 0 to 9. This is the fixed list idea, "Base10 (DEC)" is stored in ZAP as a list of numbers 0 to 9, if you want to run through a different range then you have to generate it yourself, import it and then select that from the "Custom fuzzers" category.
So, I brought up a shell and generated a list of numbers from 1 through to 100 and stored them in a text file. To import the file go to the Tools menu, then options and in the dialog choose Fuzzer. Here you see an option to add a custom fuzz file, use the "Select File..." to import the file. When the file is added to the list of fuzzers it is done so by name so make sure that you make the name descriptive, "fuzz_guesses" may mean something now but in a months time when you come back to it it won't mean much. I've not seen any way to look inside an already imported list so the only way you'll be able to see what it contains is to run it against something.
Once this is added you can go back to the message, highlight the 42, tell it you want to fuzz it and this time choose the "Custom fuzzers" category. The list imported should be shown here identified by its filename.
The fuzzing should then start, by default using a single thread and so making one request at a time. For now this is fine but if you want to alter this it can be done in the same dialog box as used to add the custom fuzz list.
Beyond showing whether the request was successful or not, the fuzz pane doesn't show much information about the request, this is because the web socket calls aren't like a normal HTTP request, they don't have to have a response so there is no response code, no size of response, to filter on. The best thing I found to do was to get the fuzzing running then switch to the WebSockets tab and watch the messages. As we know the server responds with a failure message for a wrong guess we can assume that there is some kind of success message for a right guess. I simply watched the response payloads till I saw the message then stopped the fuzzer.
In case you care, as the fuzzer was running single threaded the guess above the message will be the correct one, in this case 38.
As I said at the start, SocketToMe has a few unpublished features, if you want to practice fuzzing have a look at the features that are published and see if you can spot a theme on how the requests that go to the server are made. Once you've spotted it you should be able to generate a fuzz list which will try all possible commands. Hint, there are 5 in total.
So, that is a walk through of how to do a custom fuzz against a web socket based application. The process is fairly simple and while I'm not keen on having to upload a static list of data for each different custom fuzz I want to do, it isn't that hard to generate most lists. The fact you can't see the contents of a list, or, that I can find, delete a list, could mean that the custom category could easily get clogged up very quickly if you are regularly using this feature. I would strongly suggest using very informative filenames.
The time to create this project was kindly sponsored by the BruCON 5x5 award.