Home page logo

nmap-dev logo Nmap Development mailing list archives

Fix for stack overflow in dns.lua
From: David Fifield <david () bamsoftware com>
Date: Wed, 19 Nov 2008 13:41:35 -0700


I found that a function in dns.lua could recurse infinitely (until it
overflowed the stack) when given a specially crafted message. DNS
message can employ a kind of compression as described in section 4.1.4
of RFC 1035. A message may end with a pointer to another index in the
message; the decoder follows the pointer to get the rest of the message.

When the function dns.decStr finds a pointer in a message it calls
itself to recursively get the rest of the message. If the pointer is set
up so as to create a loop, the function calls itself until the stack

You can reproduce the crash before r11129 with the file dns.bytes
(attached). Its hexadecimal contents are

1234 8180 0001 0000 0000 0000 C00C

The C00C is a pointer that points to itself. You can feed this data to
dns.lua by setting up a fake DNS server with Ncat:

        ncat -u -l localhost 53 < dns.bytes

Then run

        nmap -d -sP --script=asn-query.nse --script-args dns=localhost scanme.nmap.org

The script output will be

SCRIPT ENGINE: Initiating script scanning.
SCRIPT ENGINE: Script scanning scanme.nmap.org (
SCRIPT ENGINE: Initialized 1 rules
SCRIPT ENGINE: Matching rules.
SCRIPT ENGINE: Will run /usr/share/nmap/scripts/asn-query.nse against
SCRIPT ENGINE: Running scripts.
SCRIPT ENGINE: Runlevel: 1.000000
Initiating SCRIPT ENGINE at 15:34
SCRIPT ENGINE: /usr/share/nmap/nselib/dns.lua:486: stack overflow
Completed SCRIPT ENGINE at 15:34, 0.09s elapsed
SCRIPT ENGINE: Script scanning completed.

Looping a pointer to itself isn't the only way to do this. A pointer
could refer to itself minus a few bytes, or two pointers could link to
each other.

I fixed the problem by setting a limit on the number of pointers to
follow--currently set at 1. This is still more capable than
advance_past_dns_name in nmap_dns.cc, which follows only one pointer and
only if it's the very first thing in the message (if I understand the
code correctly). djbdns uses a limit of 1000; see dns_packet.c. That
seems excessive for our UDP packets which will usually be much smaller
than 512 bytes.

I was made aware of this class of vulnerability by my former professor
Steve Beaty. Here are some more links on it.


David Fifield

Attachment: dns.bytes

Sent through the nmap-dev mailing list
Archived at http://SecLists.Org

  By Date           By Thread  

Current thread:
  • Fix for stack overflow in dns.lua David Fifield (Nov 19)
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]