#!/usr/bin/python # -*- coding: iso-8859-15 -*- __author__ = 'Jesus Olmos (jolmos[4t]isecauditors[d0t]com,sha0[4t]badchecksum[d0t]net)' __version__ = '0.1' #UDP is quick to scan and bruteforce, next version with threads :) import socket import sys import os import re class TftpClient: def __init__(self,timeout): #Opcodes self.PRQ = '\x00\x01' #Read request self.WRQ = '\x00\x02' #Write request self.DATA = '\x00\x03' #Data self.ACK = '\x00\x04' #ACK self.ERR = '\x00\x05' #Error #Data self.header='' self.OK = '\x00\x03\x00\x01' self.ERR = '\x00\x05\x00\x02' #Error Codes self.UNDEFINED = '\x00\x00' self.NOT_FOUND = '\x00\x01' self.ACCESS_VIOLATION = '\x00\x02' self.DISK_FULL = '\x00\x03' self.ILLEGAL = '\x00\x04' self.UNKNOWN_ID = '\x00\x05' self.ALREADY_EXISTS = '\x00\x06' self.NO_SUCH_USER = '\x00\x07' self.NO_RESPONSE = '\x7a\x69' #Response self.ack = 0 self.resp_error = 0 self.resp_msg = '' #UDP Socket self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) self.sock.settimeout(timeout) def get(self,filename,host): self.send(self.PRQ,filename,host) def put(self,filename,host): self.send(self.WRQ,filename,host) def send(self,opcode,filename,host): #packet = opcode+filename+'\x00NETASCII\x00' packet = opcode+filename+'\x00octet\x00blksize\x00512' self.sock.sendto(packet,(host,69)) try: self.header = self.sock.recv(4) except: self.ack = 0 self.resp_error = self.NO_RESPONSE def parse(self,data): pass def end(self): self.sock.close() class TftpAudit: def __init__(self,timeout): self.tftp = TftpClient(timeout) self.NON_EXISTENT_FILENAME = 'adh4g21n' sys.stdout.flush() self.retorno = re.compile('\x0d|\x0a') def speech(self,msg): try: os.popen('echo '+msg+' | festival --tts','r') except: pass def check(self,host): sys.stdout.write('>> '+host) self.tftp.get(self.NON_EXISTENT_FILENAME, host) if self.tftp.resp_error != self.tftp.NO_RESPONSE: self.speech('Service identified') sys.stdout.write('\tTFTP identified') if self.tftp.resp_error == self.tftp.ACCESS_VIOLATION: print '\tbut Denied!' elif self.tftp.ack: print '\tand is Readable!!' else: print '\tbut with errors!!' else: self.speech('No response') print '\tNo response.' def scan(self,net): for octet in range(0,255): host = net+'.'+str(octet) sys.stdout.write('>> '+host) self.tftp.get(self.NON_EXISTENT_FILENAME, host) if self.tftp.resp_error != self.tftp.NO_RESPONSE: self.speech('Service detected at '+host) sys.stdout.write('\tTFTP identified') if self.tftp.resp_error == self.tftp.ACCESS_VIOLATION: print '\tbut Denied!' elif self.tftp.ack: print '\tand is Readable!!' else: print '\tbut with errors!!' else: print '\tNo response.' def brute(self,host,wordlist): f = open(wordlist,'r') words = f.readlines() f.close() for w in words: w = self.retorno.sub('',w) print w self.tftp.get(w,host) if self.tftp.header == self.tftp.OK: print host+'/'+w def bof(self,host): evil='' for i in range(1,666): evil+='666' self.tftp.get(evil,host) def end(self): self.tftp.end() def usage(self): print sys.argv[0]+' ' print ' ej: '+sys.argv[0]+' s 192.168.3' print ' ej: '+sys.argv[0]+' c 192.168.3.44' print ' '+sys.argv[0]+' b 191.168.3.5 nombreficheros.txt' self.end() sys.exit(-1) audit = TftpAudit(1) if len(sys.argv) > 2: if sys.argv[1] == 's': if len(sys.argv) == 3: audit.scan(sys.argv[2]) else: audit.usage() elif sys.argv[1] == 'c': if len(sys.argv) == 3: audit.check(sys.argv[2]) else: audit.usage() elif sys.argv[1] == 'b': if len(sys.argv) == 4: audit.brute(sys.argv[2],sys.argv[3]) else: audit.usage() else: audit.usage() else: audit.usage() audit.end()