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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#!/usr/bin/python
from socket import *
import socks
import argparse
import time
from ipaddress import *
## This function tries to open a connection on a specific port
def connScan(host, port, wait, notor):
## If notor is set to True, it doesn't use the socks proxy
if notor:
sckt = socket(AF_INET, SOCK_STREAM)
else:
sckt = socks.socksocket()
sckt.settimeout(wait)
## Try to connect, return True on success and False on failure
try:
sckt.connect((host, port))
sckt.close()
return True
except KeyboardInterrupt:
exit()
except:
return False
## This function goes throgh all ports and calls connScan for each one
def portScan(host, ports, wait, notor):
openports = list()
for p in ports:
if connScan(host, p, wait, notor):
openports.append(p)
return openports
## This function goes throgh all hosts and calls portScan for each one
def hostScan(host, ports, wait, notor):
ret = dict()
## Check if python version 3
try:
host = unicode(host)
except:
pass
## Check if host is a network range, don't use tor for private IPs
try:
ips = ip_network(host)
if ips.num_addresses > 1:
for ip in ips.hosts():
if ip.is_private:
ret[str(ip)] = portScan(str(ip), ports, wait, True)
else:
ret[str(ip)] = portScan(str(ip), ports, wait, notor)
else:
if ips.is_private:
ret[str(host)] = portScan(str(host), ports, wait, True)
else:
ret[str(host)] = portScan(str(host), ports, wait, notor)
## Otherwise scan host as usual
except:
if host == 'localhost':
ret[str(host)] = portScan(str(host), ports, wait, True)
else:
ret[str(host)] = portScan(str(host), ports, wait, notor)
return ret
def main():
startTime = time.time()
## Define and parse the arguments
parser = argparse.ArgumentParser(description="Simple port scanner that works over Tor")
parser.add_argument("--version", dest="version", help="print version info and exit", action="store_true")
parser.add_argument("HOSTS", help="IP or domain to scan", default="empty_host", nargs="?")
parser.add_argument("-H", "--hosts", metavar="HOSTS", dest="tgtHost", help="IP or domain to scan", default="empty_host_option")
parser.add_argument("-p", "--ports", metavar="PORTS", dest="tgtPort", help="ports to scan", default="20-25,53,80-85,443-445,8080,8333,9050,9150")
parser.add_argument("-t", "--timeout", metavar="TIMEOUT", dest="sockTimeout", type=int, help="seconds to wait before connection timeout for each port", default=2)
parser.add_argument("--clearnet", dest="clearnet", help="don't use Tor for scanning", action="store_true")
parser.add_argument("--torport", metavar="TORPORT", dest="torPort", type=int, help="port for Tor proxy", default="9050")
args = parser.parse_args()
## Version argument
if args.version:
print("Tmap 1.0.0")
print("License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>")
print("This is free software: you are free to change and redistribute it.")
print("There is NO WARRANTY, to the extent permitted by law.")
exit()
## Combine HOST and --hosts values
if args.HOSTS == "empty_host":
if args.tgtHost == "empty_host_option":
parser.print_help()
print ("Host must be specified")
exit()
else:
args.HOSTS = args.tgtHost
else:
if args.tgtHost != "empty_host_option":
args.HOSTS = args.HOSTS + "," + args.tgtHost
## Set Tor as default Tor proxy for the scanner
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", args.torPort)
## Load specified ports into PORTS list
PORTS = list()
for p in args.tgtPort.split(","):
if "-" not in p:
try:
p = int(p)
PORTS.append(p)
except:
parser.print_help()
exit()
else:
try:
p = list(map(int, p.split("-")))
except:
parser.print_help()
exit()
if len(p) != 2 or p[0]>p[1]:
parser.print_help()
exit()
else:
p = list(range(p[0],p[1]+1))
PORTS += p
## Load other variables
HOSTS = args.HOSTS.split(",")
WAIT_TIME = args.sockTimeout
CLEARNET = False
if args.clearnet:
CLEARNET=True
if CLEARNET == False:
if connScan("127.0.0.1", args.torPort, 3, True):
pass
else:
print("Tor is not running on port {}.".format(args.torPort))
exit()
## Scan each host in HOSTS list
r = dict()
for h in HOSTS:
r = hostScan(h, PORTS, WAIT_TIME, CLEARNET)
for i in r.keys():
if len(r[i]) != 0:
print('{} open ports: {}'.format(i, str(r[i])))
endTime = time.time()
totalTime = endTime - startTime
print("Scan done in {} seconds".format(round(totalTime, 2)))
if __name__ == "__main__":
main()
|