Nmap Development mailing list archives

Re: DNS fuzzer


From: David Fifield <david () bamsoftware com>
Date: Fri, 2 Apr 2010 14:33:50 -0600

On Mon, Mar 29, 2010 at 03:38:17PM -0400, Michael Pattrick wrote:
On Mon, Mar 29, 2010 at 1:11 PM, David Fifield <david () bamsoftware com> wrote:
On Sat, Mar 27, 2010 at 03:19:02AM -0400, Michael Pattrick wrote:
On Fri, Mar 26, 2010 at 8:46 PM, David Fifield <david () bamsoftware com> wrote:
On Sun, Mar 21, 2010 at 07:28:14PM -0400, Michael Pattrick wrote:
I've been playing with Bind10 lately, I wanted to incorporate fuzz
testing in the mix but could only find one DNS fuzzer[0]. It didn't
really suit my needs and was closed source so I wrote my own. Attached
is my fuzzer.

It's a very naive fuzzer and hasn't found any flaws yet, so I'd
appreciate feedback on it or suggestions on how such a fuzzer could be
improved.

Your script needs some more documentation. I can't tell what it does
from just looking at it. In your "description" field, explain at a high
level what the script is doing and how many packets it's sending.

New version, with docs, attached.

Thanks, this is good.

I understand that since you may be making broken packets, you can't use
the dns library for everything, but if you find a place where you can
make use of it then you should.

The DNS library doesn't appear to support sending compressed DNS
queries. The basic operation of this fuzzer is to induce bit errors.
Sort of like the 'dumb fuzzers' described by Charlie Miller and used
to win this years Pwn2Own.

And just to clarify, I don't think this script should be included by
default with Nmap. Instead I'm leaving it on the mailing list to be
discovered by anyone who needs it.

On the contrary, I think there is a place for scripts like this. "vuln"
category works even though it's testing for a general, not a specific
vulnerability.

I'd like to include this script if it can be made not to run forever,
instead running some fixed number of rounds (controlled by a script
argument).

I've added the option to limit how long this script runs for in
minutes. Unlimited runtime is still available.

I would like to see other fuzzing techniques too, though of
course those can be added incrementally. I'm thinking something like 100
rounds each of:

* Randomly swap bits (like you have now).
* Randomly drop bytes.
* Randomly duplicate bytes.
* Randomly swap bytes.
* Truncate packets at a random location.

Plus:

* A standard battery of invalid compressed names.

I'll have to think about those suggestions a bit more and perhaps some
up with my own new modes.

Here are my results running the script from
http://seclists.org/nmap-dev/2010/q1/1118 (dns-fuzz-1) and
http://seclists.org/nmap-dev/2010/q1/1176 (dns-fuzz-2). I ran this
against the server in my DSL router, which is dproxy. It always quits
with an offending packet in less than a second.

PORT   STATE         SERVICE REASON
53/udp open|filtered domain  no-response
| dns-fuzz-1: Server stopped responding... He's dead, Jim.
|_Offending packet: 
0x4f3500000002000000000000046e756363076a62716671766d04776e767305736f6b627900000100010672626177786804736a6d72066f697965656cc00c00050001

PORT   STATE         SERVICE REASON
53/udp open|filtered domain  no-response
| dns-fuzz-1: Server stopped responding... He's dead, Jim.
|_Offending packet: 0x4f3f0000008200000000000006776166736463036671650000010001076b7074796f7a6206657175767576c00c00050001

PORT   STATE         SERVICE REASON
53/udp open|filtered domain  no-response
| dns-fuzz-2: Server stopped responding... He's dead, Jim.
|_Offending packet: 0x056d000000010000000000000773646d616d6e77056b6a63666a0000014001

PORT   STATE         SERVICE REASON
53/udp open|filtered domain  no-response
| dns-fuzz-2: Server stopped responding... He's dead, Jim.
|_Offending packet: 0xac07000000010000000000000475616f790571726b777a0000010001

The server didn't really crash in any of these cases. This server
doesn't respond to version detection. Probably, the script should send
an initial uncorrupted packet, and only start fuzzing if it receives a
response.

I'm concerned about the lag between the packet that stops the server
stops responding. The script requires three non-responses before it
reports the offending packet, but it changes the packet in between each
non-response. The packet that's printed is not the one that caused the
server to crash, but one even further corrupted. That's going to make it
harder to find the source of a bug. What the script should do, when it
gets a non-response, is to keep sending the same packet three times.

Doing what I suggest above will also fix another problem, which is that
a crash won't be detected if there aren't enough iterations left in the
current round (the j loop) for the count to reach 3. If math.random(10)
returns 5, and the server stops responding at round 4, the round will
expire before three sends happen, a completely new packet will be
generated for the next round, and that's the one that will be printed,
not the one that caused the crash.

Ron suggested a new "fuzzer" cateogry, and Fyodor agreed with that. I
think the right categories for this script are {"fuzzer", "intrusive"}.

Let's change the name of the script argument "fuzztime" to "timelimit".

Other scripts take time arguments in seconds, not minutes. It's not the
best for this script but I'd like it if you make this script work that
way too. In the future we should have a standard function for parsing a
time specification like "60s" or "1m".

Running without the dns-fuzz.fuzztime argument gives
53/udp open|filtered domain  no-response
| dns-fuzz-2: Cannot fuzz for zero minutes, please enter a valid length of time to fuzz for.
|_Or -1 to fuzz for an unlimited amount of time.
Other scripts have the convention that 0 means unlimited. In case the
script argument is not specified, use a default limit of 10 minutes.

David Fifield
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: