#!/usr/bin/env python3 """ SMTP Fuzzer using JRSFuzz by Javantea Oct 11, 2015 Based on SMTP Grammar Fuzzer by Javantea Sept 14, 2015 For STARTTLS, see smtp_starttls_jrsfuzz1.py TODO: HELO DATA Headers Body MIME advanced SMTP commands. Handle errors returned by the server. Monitors with GDB and ASAN integration. """ import jrsfuzz import sys import socket def main(): # This works on any server except those that require STARTTLS (suzy) data = b'EHLO a.altsci.com\r\nMAIL FROM: jvoss@altsci.com\r\nRCPT TO: jvoss@altsci.com\r\nQUIT\r\n' host, port = 'localhost', 25 if len(sys.argv) > 1: host = sys.argv[1] #end if if len(sys.argv) > 2: port = int(sys.argv[2]) #end if dest = (host, port) family, socktype = socket.AF_UNSPEC, socket.SOCK_STREAM gai = socket.getaddrinfo(host, port, family, socktype) if len(sys.argv) > 3: data = sys.argv[3] #end if lines_output = len(data) * 256 print("%i outputs, %3.3f MB" % (lines_output, lines_output*len(data)/(1<<20)), file=sys.stderr) our_data = None for family, socktype, proto, canonname, addr in gai: try: s = socket.socket(family, socktype, proto) s.connect(addr) except Exception as e: print(e,) continue #end try our_data = (family, socktype, proto, canonname, addr) break #next family, socktype, proto, canonname, addr if our_data == None: print("Can't connect to dest", dest) #end if family, socktype, proto, canonname, addr = our_data header = s.recv(1024) print(header) prevResp = None for i in range(lines_output): x = jrsfuzz.JRSFuzz(data, i) # We might be sending 2 commands, but let it be. s = socket.socket(family, socktype, proto) s.connect(addr) header = s.recv(1024) print(header) try: s.send(x) except BrokenPipeError: print("Broken Pipe.", i, x) except ConnectionResetError: print("Conn Reset.", i, x) #end try try: resp = s.recv(1024) except ConnectionResetError: print("Conn Reset on recv.", i, x) resp = b'' #end try print(resp) if resp != prevResp: print(i, x) prevResp = resp s.close() #next i #end def main() if __name__ == '__main__': main() #end if