Detecting W32/SQLSlammer with python
I'm throwing this bit of code out there, just to show how easy it can be to write nifty little scripts in python. Use this script for detecting the SQL slammer worm(or rather the exploit it uses). The SQLSlammer worm is a really neat little creature (if rather archaic). By neat and little, I mean all contained in a single UDP packet and able to make a MSsql server cry.
I had a look at the payload contained in the UDP packet and illustrate how to detect if the buffer overflow exploit for a vulnerable MSsql server is present.
And now I present to you the crude but effective python script I wrote to inspect traffic on a interface and alert you once a MSsql server buffer overflow exploit (the one used by Slammer) has been detected.
from pcapy import open_live from impacket import ImpactDecoder class Slammer: def __init__(self): max_bytes = 1024 read_timeout = 100 # in milliseconds # Open live capture on eth0 reader = open_live('eth0', max_bytes, True, read_timeout) reader.setfilter('udp') # Run the packet capture loop reader.loop(0, self.callback) def callback(self, hdr, data): # Parse the Ethernet packet decoder = ImpactDecoder.EthDecoder() ether = decoder.decode(data) # Parse the IP packet inside the Ethernet packet iphdr = ether.child() # we only ude the udphdr but set the rest if # you might want to use them later tcphdr = icmphdr = udphdr = iphdr.child() #if iphdr.get_ip_p() == ImpactPacket.UDP.protocol: self.handle_udp(iphdr, udphdr) def handle_udp(self, iphdr, udphdr): try: print "[Inspecting UDP]" # We dont use most of these, but left them for refrence srcp = udphdr.get_uh_sport() dstp = udphdr.get_uh_dport() ip = iphdr.get_ip_src() len = udphdr.get_uh_ulen() chksum = udphdr.get_uh_sum() data = udphdr.get_data_as_string() # MS sql server port if dstp == 1434: print "srcport: %s | destport: %s | len: %s |"%(srcp, dstp, len) self.ident_slammer(data, ip) except: failed = "I dont care" def ident_slammer(self, payload, ip): # set if 0x04 is found, which means its performing # a query to find a database on the given host query = 0 # length of the db name the query is asking for # if this is larger than 16 bytes, # it triggers the exploit. The name string should be terminated # before the 16th byte with a 0x00 length = 0 index = 0 for b in payload: h = ord(b) # read these three IF statements from the bottem up to get the logic if length > 16 and query == 1: print "DB namestring longer than 16 bytes" print "[SQL buffer overflow exploit] FOUND, incomming from: %s"%ip break; if query == 1: if h == 0: break; else: length += 1 if h == 4 and index == 0: query = 1 print "Sql database search query..." index += 1 def main(): print "--[Listening on eth0]--" slammer = Slammer() if __name__ == "__main__": main()














