-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathidentify-hosts.py
executable file
·138 lines (123 loc) · 4.89 KB
/
identify-hosts.py
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#! /usr/bin/python
# (c) 2015 Veit Hailperin
# PoC Network Layout Information Gathering with TCP timestamps
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
import xml.sax
import sys
from colorama import init, Fore
# There might be better values in different scenarios. Feel free to play with the value
MAX_DIFFERENCE = 5000
def validate_ip(ip):
a = ip.split('.')
if len(a) != 4:
return False
for x in a:
if not x.isdigit():
return False
i = int(x)
if i < 0 or i > 255:
return False
return True
class NmapHandler(xml.sax.ContentHandler):
"""parses an nmap xml output"""
def __init__(self):
self.host = "0.0.0.0"
self.open_ports = []
self.port = 0
def startElement(self, name, attrs):
if name == "address":
ip = attrs.getValue("addr")
if validate_ip(ip):
self.host = ip
if name == "port":
self.port = attrs.getValue("portid")
if name == "state":
if attrs.getValue("state") == "open":
self.open_ports.append(int(self.port))
def endElement(self, name):
if name == "port":
self.port = 0
def banner():
""" banner() - prints banner """
print("")
print(" ")
print(".___ __ .__ _____ .__ __ ")
print("|__| __| _/____ _____/ |_|__|/ ____\__.__. | |__ ____ _______/ |_ ______ ______ ___.__.")
print("| |/ __ |/ __ \ / \ __\ \ __< | | ______ | | \ / _ \/ ___/\ __\/ ___/ \____ < | |")
print("| / /_/ \ ___/| | \ | | || | \___ | /_____/ | Y ( <_> )___ \ | | \___ \ | |_> >___ |")
print("|__\____ |\___ >___| /__| |__||__| / ____| |___| /\____/____ > |__| /____ > /\ __// ____|")
print(" \/ \/ \/ \/ \/ \/ \/ \/__| \/ ")
print("")
def usage():
""" usage() - print usage """
print("Usage: python identify-hosts.py nmap-output.xml")
print("Note: Nmap file is expected to contain a single host")
print("Note: This PoC won't work if any of the services is active-active load-balanced")
def __main__():
""" main() - runs identify-hosts.py """
print("This is a PoC script")
print("(c) 2015 Veit Hailperin\n")
print("Note: This might take a minute, depending on how many ports are open")
init()
if len(sys.argv) != 2:
usage()
exit()
nmap_file = sys.argv[1]
parser = xml.sax.make_parser()
r_handler = NmapHandler()
parser.setContentHandler(r_handler)
try:
parser.parse(open(nmap_file, "r"))
except IOError:
print("Couldn't open nmap xml file: "+nmap_file+"\n")
exit(1)
target = r_handler.host
hosts = []
open_ports = r_handler.open_ports
timestamps = {} # {portnr:[timestamps]}
timestamp = 0
for port in open_ports:
timestamps[port] = []
counter = 0
while counter < 10:
timestamp = 0
try:
ans, unans = sr(IP(dst=target)/TCP(sport=40123,
dport=port,
flags="S",
options=[('Timestamp', (0, 0))]),
verbose=False, multi=True, timeout=1)
if len(ans) > 0:
try:
for snd, rcv in ans:
if TCP in rcv:
timestamp = rcv[TCP].options[3][1][0]
break
if timestamp != 0:
timestamps[port].append(timestamp)
else:
print("Info: There was no TCP packet in the responses")
except TypeError:
print("ERROR: Something went wrong when reading TS")
else:
print("Info: Did not receive an answer")
except IndexError, KeyError:
print("ERROR: Something went wrong!")
counter += 1
while len(open_ports) > 0:
c_port = open_ports.pop()
hosts.append([str(c_port)+" ["+str(timestamps[c_port][0])+"]"])
for port in open_ports:
if abs(timestamps[port][0] - timestamps[c_port][0]) < MAX_DIFFERENCE:
hosts[len(hosts)-1].append(str(port)+" ["+str(timestamps[port][0])+"]")
open_ports.remove(port)
print("The following ports seem to belong to the same host:")
i = 1
for host in hosts:
print(('\033[31m'+ "Host "+str(i)+":"+'\033[32m'))
print((", ".join([str(x) for x in host])))
print("")
i += 1
__main__()