Ten wpis poświęcony jest tworzeniu własnego narzędzia w języku python, który zwykle jest zainstalowany na komputerach z systemem linux. Zwykle najbardziej znanym skanerem portów jest program nmap, który posiada bardzo rozbudowane opcje. Tymczasem wielokrotnie spotkałem się z przypadkami, że taki skaner trzeba było sobie samemu napisać, poniżej przedstawiam najprostszą jego postać wraz ze szczegółowym opisem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#!/usr/bin/python # pierwsza linijka to wskazanie lokalizacji interpretera języka import socket # import biblioteki odpowiedzialnej za komunikację z hostami sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # tutaj tworzę instancję obiektu socket i wskazuję, adres oraz rodzaj # komunikacji na TCP socket.setdefaulttimeout(3) # ustawiam domyślny czas po którym przestaję odpytywać hosta host = raw_input("Podaj hosta: ") # proszę użytkownika o podanie hosta port = 135 # ustawiam zmienną port na wartość 135 def portscanner(port): if sock.connect_ex((host, port)): print "Port %d jest zamkniety" % (port) else: print "Port %d jest otwarty" % (port) # funkcja portscanner przyjmuje jako parametr wartość liczbową portu, # następnie przy pomocy instrukcji warunkowej podaje informacje czy # port danego hosta jest zamknięty czy otwarty portscanner(port) # wywołanie funkcji portscanner z przypisaną wcześniej wartością 135 |
Powyżej najprostsza postać skanera portu, mogę wskazać tylko jeden port w skrypcie. Dlatego też poniżej bardziej rozbudowana wersja skanera, opiszę różnice w programie poniżej:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#!/usr/bin/python import socket from termcolor import colored # import biblioteki odpowiedzialnej za kolorowanie napisów sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.setdefaulttimeout(3) host = raw_input("Podaj hosta: ") def portscanner(port): if sock.connect_ex((host, port)): # pass print(colored("Port %d jest zamkniety" % (port), 'red')) else: print(colored("Port %d jest otwarty" % (port), 'green')) # w funkcji dodano parametr odpowiedzialny za kolor napisu, ponadto # istnieje możliwość wykomentowania linijki odpowiedzialnej za # wypisywanie komunikatu o zamkniętym porcie (usuń komentarz przed pass) # wówczas program wypisze tylko otwarte porty for port in range(1,30): portscanner(port) # pętla for do wykonania iteracji po portach, wartości w polu range # odpowiadają portowi początkowemu i końcowemu |
W tym skrypcie istnieje możliwość zdefiniowania zakresu portów oraz określenie czy ma zostać wypisana kompletna lista czy tylko otwarte porty. Poniżej przykład z wykonania programu w wersji jak powyżej:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
root@kali:~/python# ./scaner1.py Podaj hosta: localhost Port 1 jest zamkniety Port 2 jest zamkniety Port 3 jest zamkniety Port 4 jest zamkniety Port 5 jest zamkniety Port 6 jest zamkniety Port 7 jest zamkniety Port 8 jest zamkniety Port 9 jest zamkniety Port 10 jest zamkniety Port 11 jest zamkniety Port 12 jest zamkniety Port 13 jest zamkniety Port 14 jest zamkniety Port 15 jest zamkniety Port 16 jest zamkniety Port 17 jest zamkniety Port 18 jest zamkniety Port 19 jest zamkniety Port 20 jest zamkniety Port 21 jest zamkniety Port 22 jest otwarty Port 23 jest zamkniety Port 24 jest zamkniety Port 25 jest zamkniety Port 26 jest zamkniety Port 27 jest zamkniety Port 28 jest zamkniety Port 29 jest zamkniety |
Na koniec wpisu przedstawiam najbardziej rozbudowaną wersję skanera portów, który posiada wbudowaną instrukcję użytkowania programu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#!/usr/bin/python from socket import * import optparse from threading import * from termcolor import colored def connScan(tgtHost, tgtPort): try: sock=socket(AF_INET, SOCK_STREAM) sock.connect((tgtHost, tgtPort)) print(colored('[+] %d/tcp Otwarty' % tgtPort, 'green')) except: print(colored('[-] %d/tcp Zamkniety' % tgtPort, 'red')) finally: sock.close() def portScan(tgtHost, tgtPorts): try: tgtIP = gethostbyname(tgtHost) except: print 'Nieznany Host %s ' %tgtHost try: tgtName = gethostbyaddr(tgtIP) print 'Wyniki skanowania dla:' + tgtName[0] except: print 'Wyniki skanowania dla:' + tgtIP setdefaulttimeout(1) for tgtPort in tgtPorts: t=Thread(target=connScan, args=(tgtHost, int(tgtPort))) t.start() def main(): parser = optparse.OptionParser('Podaj parametry: ' + '-H <podaj host> -p <podaj port> lub <podaj port, kolejny port>') parser.add_option('-H', dest='tgtHost', type='string', help='wskaz hosta do skanowania') parser.add_option('-p', dest='tgtPort', type='string', help='wskaz porty do skanowania, oddziel przecinkiem') (options, args) = parser.parse_args() tgtHost = options.tgtHost tgtPorts = str(options.tgtPort).split(',') if (tgtHost == None) | (tgtPorts[0] == None): print parser.usage exit(0) portScan(tgtHost, tgtPorts) if __name__ == '__main__': main() |
Przykłady użycia skanera przedstawiam poniżej:
1 2 3 4 5 6 7 |
root@kali:~/python# ./advscanner.py Podaj parametry: -H <podaj host> -p <podaj port> lub <podaj port, kolejny port> root@kali:~/python# ./advscanner.py -H 192.168.0.103 -p 135,139 Wyniki skanowania dla:192.168.0.103 [+] 135/tcp Otwarty [+] 139/tcp Otwarty |
Wszystkie skrypty były testowane w środowisku KaliLinux na interpreterze języka Python w wersji 2. U mnie działa 🙂