General Purpose Fuzzer.py

Mon, 17 Dec 2007 00:15:42 GMT
by pdp

Fuzzing is a quite important for security researchers mainly because it helps going through the boring stuff quickly. Generally speaking, fuzzers are tools for automation. Unfortunately most moderns fuzzers are a lot more then automation tools. They are big, bloated and most of all, highly unusable, imho. And if you want to do some fuzzing, first of all you have to learn how they were built, and this is not a trivial thing.

Due to my frustration with modern fuzzers and the simple fact that I need them in my day-to-day work, I decided to write my own in Python, because Python rocks. The fuzzer, which I developed this afternoon, is contained within a single python module. This makes it very portable and easy to use. On the other hand, the fuzzing subroutines do not use anything fancy but the standard python functionalities (generators and closures), which improves the learning curve quite drastically. Last but not least it is really fun to use it from the command line. If you don't trust me, just give it a try. The following is the actual source code of the tool:

[/files/2007/12/fuzzer.py](/files/2007/12/fuzzer.py)

When prototyping the fuzzer I realized that I need a very good way to separate generated data from logic. Therefore, I came up with the concepts of generators (the stuff I've used in my [previous work](/blog/web-client-fuzzer_py) on fuzzers) and actuators. Generators simply **yield** data while actuators consume it and do something useful with it. The following is an [example](https://chatbotkit.com/examples) of a dummy generator and actuator, also available within the fuzzer source code. Keep in mind that you can input external modules within the fuzzer by using the `-i` or `--import` command line options and as such modularize your work a bit more:

#
# GENERATORS
#
def generator_dummy(globals):
    """ the dummy generator outputs all numbers between 0 and 99 """

    def run():
        for i in range(0, 100):
            yield i

    return run

#
# ACTUATORS
#
def actuator_dummy(globals):
    """ the dummy actuator returns all supplied values """

    def run(value):
        return value

    return run

As you can see, very simple stuff really. The simpler the better, I say! Unfortunately, the tool is only self documented (check the usage). There is no other external documentation how to use it. If you are willing to help with putting some basic tutorials together, you are more then welcome. Please, let me know. Of course, credits will be given where are due.

So, there you go. General Purpose fuzzing can be actually a simple task.

Archived Comments

nnpnnp
No offence mate but your fuzzer is about 3 years behind the times and not particularly original. There is a reason modern fuzzers have all that extra fluff. Also, a quick google would have saved you the hassle of writing this I think. There are plenty of scripts out there that do the same thing. From what I can see the reason your script is so short is that it basically does nothing. It's a watered down version of peach (which also has the idea of generators etc) without all the useful 'bloat'. Now I'm not saying fuzzers need to be huge behemoths of applications. Obviously experience has shown that often a simple script with a clear aim can find bugs quickly but if you want things like crash detection, logging, monitoring etc then all that bloat is necessary. Fuzzing can have a steep learning curve for a reason, to do it properly is a skill. Sure at the moment any idiot can still fuzz a couple of bugs in some obscure application but to do it properly isn't a 5 minute quick hack. What you have there is pretty much what most hackers had themselves a couple of years ago. I'm not saying it's not useful, just that it's not as much of an original idea as you might think. The only reason I bothered to reply is that I'm kind of surprised as most of the stuff found here is usually pretty cool and off the beaten track ;)
pdppdp
nnp, no one claims to be original, however, what I do claim is that by using something like this, you have a lot better chances to get your head around various problems without becoming a slave of them and wasting your time too much. and this to me matters a lot. many tools out there just try to be too clever, including peach, tools should not be clever. I think that we are clever enough to figure it out on our own. What tools should do is to automate the boring stuff. In my case, repetition is quite boring. so you should really take this tool from that prospective. on your last note, well, I love simplicity. I believe that simple is better and more affective. If I can find a problem, like fuzzing technology, which is extremely bloated and I can simplify it to the extend where it does the same but in a minimalistic way, then I considered it as an accomplishment. it is as simple as that. :) so, although you might not use this fuzzer, I believe that there are tones of people who will use it and will find it very interesting and better suited for the job then peach. They might even use some of the concepts to construct their own fuzzers. There is nothing better then custom tools!
nnpnnp
My point though is that this extra cleverness is what seperates an excellent fuzzer from an average one. Sure your script in its current incarnation could be hacked on to find some bugs but to really exercise a protocol/application you're going to have to put in a lot of work. So while you might be saving yourself effort in the short term, in the long term you would have been better off spending 15 minutes getting to grips with a fuzzing framework like Sulley and working from there. And 15 mins is the most it would take. After that you just map out your protocol in block form and you magically have a much more powerful fuzzer because of all that 'bloat'. Of course if its you're first time fuzzing anything you might wonder about 'block based fuzzing' or whatever but there's the same learning curve with what you have, just less of a pay off at the end. I agree that Peach is over complex. It was after using Peach for the first time that I wrote something quite similar to your script, but I wouldn't be so quick to write off all fuzzing frameworks because of it. There are plenty out there that are easy to understand for beginners yet offer the power a more advanced user might need (Sulley is a perfect example)
Adrian PastorAdrian Pastor
I think writing your own fuzzer is one of those things that every hacker/security enthusiast should do at some point. I do agree with nnp that frameworks sometimes offer fuzzing features that are required. However, after having talked to some guys who have found impressive number of security holes I've learned most holes were found with very simple fuzzing scripts or through source code audits. Not to be biased, but like pdp, I'm in love with simple tools that do something specific.
nnpnnp
Of course making something as simple as possible is desirable but it is possible to whip up a very straight forward fuzzer using Sulley (excuse my overuse of this particular framework as an example but its quite good) which has a massive library of fuzz strings. If that doesn't find any holes you can then easily expand it using Sulley's primitives and modifiers. Using a framework with this kind of support allows you to start out small and simple and work upwards. On the other hand if you start with something small and simple and unfortunately you don't find anything... where to then? Modify your framework? Start from scratch? Sulley also comes with other tools that are very useful such as process monitoring tools which allow you to start/monitor/restart a program as well as logging a memory dump of the process that crashed and the fuzz file that caused it to crash. On top of that it can also chain single fuzz tests to fuzz deep into a protocol. These extras can safely be ignored if you manage to knock over the process initially but if you need their support you have it. I guess in the end your choice of tool comes down to how much resistance the target program puts up weighed against how much you want to kill it via a fuzzer as opposed to getting into a code audit/RE session.
StrongarmStrongarm
pdp! sure Python rocks but Ruby takes drugs and has lots of sex with plenty of women. I'd hope you would have written it in Javascript, js being your baby in all.
pdppdp
hihi