Advertisement
opexxx

spoofspotter.py

Jun 24th, 2014
338
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.42 KB | None | 0 0
  1. import logging
  2. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  3. import logging.handlers
  4. import socket
  5. from scapy.all import *
  6. import threading
  7. import SocketServer
  8. import smtplib
  9. from email.mime.text import MIMEText
  10. from email.mime.multipart import MIMEMultipart
  11. import datetime
  12. import random, string
  13. import argparse
  14. import sys
  15. import subprocess
  16. from array import array
  17.  
  18.  
  19. #################################################
  20. # Spoof Sniffer #
  21. # -A tool to catch spoofed NBNS responses #
  22. # Spoofed responses are alerterd on with #
  23. # email and/or SYSLOG #
  24. # #
  25. # Written by Karl Fosaaen #
  26. # Twitter: @kfosaaen #
  27. #################################################
  28.  
  29. #Some static variables
  30. QUERY_NAME = "NETSPITEST"
  31. SENT = 'false'
  32. BADIPs = []
  33.  
  34. #Parser Starter
  35. parser = argparse.ArgumentParser(description='A tool to catch spoofed NBNS responses')
  36.  
  37. #Required Flags
  38. parser.add_argument('-i', action="store", metavar='192.168.1.110', help='The IP of this host', required=True)
  39. parser.add_argument('-b', action="store", metavar='192.168.1.255', help='The Broadcast IP of this host', required=True)
  40.  
  41. #Optional Flags
  42. parser.add_argument('-f','-F', action="store", metavar='/home/nbns.log', help='File name to save a log file')
  43. parser.add_argument('-S', action="store", metavar='true', help='Log to local Syslog - this is pretty beta')
  44. parser.add_argument('-e', action="store", metavar='you@example.com', help='The email to receive alerts at')
  45. parser.add_argument('-s', action="store", metavar='192.168.1.109', help='Email Server to Send Emails to')
  46. parser.add_argument('-n', action="store", metavar='EXAMPLEDOMAIN', help='The string to query with NBNS, this should be unique')
  47. parser.add_argument('-R', action="store", metavar='5', help='The number of Garbage SMB Auth requests to send to the attacker')
  48. parser.add_argument('-c', action="store", metavar='true', help='Continue Emailing After a Detection, could lead to spam')
  49. parser.add_argument('-d', action="store", metavar='5', help='Time delay (in seconds) between NBNS broadcasts, reduces network noise')
  50.  
  51. args = parser.parse_args()
  52.  
  53. #Handle Custom Queries
  54. if args.n:
  55. QUERY_NAME = args.n
  56.  
  57. # Random String Generation
  58. def randomword(length):
  59.    return ''.join(random.choice(string.lowercase) for j in range(length))
  60.  
  61.  
  62. #Scapy broadcast packet creation
  63. pkt = IP(src=args.i,dst=args.b)/UDP(sport=137, dport='netbios_ns')/NBNSQueryRequest(SUFFIX="file server service",QUESTION_NAME=QUERY_NAME, QUESTION_TYPE='NB')
  64.  
  65. #What time is it?
  66. now = datetime.datetime.now()
  67.  
  68. #Email function
  69. def sendEmail(REMAIL, ESERVER, IP, MAC):
  70. me = 'spoofspotter@netspi.com'
  71. you = REMAIL
  72. server = ESERVER
  73.  
  74. msg = MIMEMultipart('alternative')
  75.  
  76. msg['Subject'] = 'A spoofed NBNS response was detected'
  77. msg['From'] = me
  78. msg['To'] = you
  79.  
  80. now1 = datetime.datetime.now()
  81. BODY = 'A spoofed NBNS response for %s was detected by %s at %s from host %s - %s' %(QUERY_NAME, args.i, str(now1), IP, MAC)
  82.  
  83. part1 = MIMEText(BODY, 'plain')
  84.  
  85. msg.attach(part1)
  86.  
  87. s = smtplib.SMTP(server)
  88. s.sendmail(me, [you], msg.as_string())
  89. s.quit()
  90. #Thanks Python Example Code
  91.  
  92. #Flag for preventing email spamming
  93. if not args.c:
  94. global SENT
  95. SENT = 'true'
  96. print "Email Sent"
  97.  
  98. #Sends out the queries
  99. def sender():
  100. while 1:
  101. send (pkt, verbose=0)
  102. # If there's a delay set, then wait
  103. if args.d:
  104. time.sleep(float(args.d))
  105.  
  106. #Handler for incoming NBNS responses
  107. def get_packet(pkt):
  108. if not pkt.getlayer(NBNSQueryRequest):
  109. return
  110. if pkt.FLAGS == 0x8500:
  111. now2 = datetime.datetime.now()
  112. print 'A spoofed NBNS response for %s was detected by %s at %s from host %s - %s' %(QUERY_NAME, args.i, str(now2), pkt.getlayer(IP).src, pkt.getlayer(Ether).src)
  113. logged = 0
  114. for i in BADIPs:
  115. if i == pkt.getlayer(IP).src:
  116. logged = 1
  117. if logged == 0:
  118. BADIPs.append(str(pkt.getlayer(IP).src))
  119. global SENT
  120. SENT = 'false'
  121.  
  122. #if the file flag is set, then write the log
  123. if args.f:
  124. f = open(args.f, 'a')
  125. f.write('A spoofed NBNS response for %s was detected by %s at %s from host %s - %s\n' %(QUERY_NAME, args.i, str(now2), pkt.getlayer(IP).src, pkt.getlayer(Ether).src))
  126. f.close()
  127. #if email flags set, call the email function
  128. if args.e and args.s and SENT=='false':
  129. sendEmail(args.e, args.s, pkt.getlayer(IP).src, pkt.getlayer(Ether).src)
  130. #if syslog flag is set, then log it
  131. if args.S:
  132. NBNSLogger = logging.getLogger('NBNSLogger')
  133. NBNSLogger.setLevel(logging.DEBUG)
  134. #change your syslog stuff here - this is pretty beta, feel free to change this.
  135. handler = logging.handlers.SysLogHandler(address = ('localhost',514), facility=19)
  136. NBNSLogger.addHandler(handler)
  137. NBNSLogger.critical('A spoofed NBNS response for %s was detected by %s at %s from host %s - %s\n' %(QUERY_NAME, args.i, str(now2), pkt.getlayer(IP).src, pkt.getlayer(Ether).src))
  138. #Seriously, I didn't test this with an actual syslog server, please let me know if this works for you
  139. #if the respond flag is set, respond with x number of hashes
  140.  
  141. if args.R:
  142. print 'Sending %d hashes to %s'%(int(args.R), pkt.getlayer(IP).src)
  143. for x in range(0, int(args.R)):
  144. randpass = 'demo/myadmin%%%s'%(randomword(8))
  145. pathstr = '//%s/C$'%(pkt.getlayer(IP).src)
  146. ftpstr = 'ftp://myadmin:%s@%s'%(randomword(8), pkt.getlayer(IP).src)
  147. wwwstr = 'http://myadmin:%s@%s/test'%(randomword(8), pkt.getlayer(IP).src)
  148.  
  149. #Sends SMB, FTP, and WWW Auth
  150. subprocess.Popen(['smbclient', '-U', randpass, pathstr], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
  151. subprocess.Popen(['wget', ftpstr, '-o', '/dev/null'], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
  152. subprocess.Popen(['wget', wwwstr, '-o', '/dev/null'], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
  153.  
  154. def main():
  155. try:
  156. if args.f:
  157. f = open(args.f, 'a')
  158.                         f.write('Starting Server at %s\n' %(str(now)))
  159.                         f.close()
  160. print "Starting NBNS Request Thread..."
  161. thread.start_new(sender,())
  162. try:
  163. print "Starting UDP Response Server..."
  164. sniff(iface='eth0',filter="udp and port 137",store=0,prn=get_packet)
  165. except KeyboardInterrupt:
  166.                         print "\nStopping Server and Exiting...\n"
  167. now3 = datetime.datetime.now()
  168. if args.f:
  169.                          f = open(args.f, 'a')
  170. f.write('Stopping Server at %s\n' %(str(now3)))
  171.          f.close()
  172. except:
  173. print "Server could not be started, confirm you're running this as root.\n"
  174. except KeyboardInterrupt:
  175. exit()
  176. except:
  177. print "Server could not be started, confirm you're running this as root.\n"
  178. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement