summaryrefslogtreecommitdiff
path: root/tmap
diff options
context:
space:
mode:
Diffstat (limited to 'tmap')
-rwxr-xr-xtmap115
1 files changed, 82 insertions, 33 deletions
diff --git a/tmap b/tmap
index cddb178..b9473ba 100755
--- a/tmap
+++ b/tmap
@@ -1,12 +1,14 @@
#!/usr/bin/python3
+import sys
from socket import *
import socks
import argparse
import time
from ipaddress import *
+import threading
-## This function tries to open a connection on a specific port, returns True if successful
-def connScan(host, port, wait, notor):
+## Receive first 80 bytes from port, return string of received data
+def getBanner(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)
@@ -14,10 +16,31 @@ def connScan(host, port, wait, notor):
sckt = socks.socksocket()
sckt.settimeout(wait)
- ## Try to connect, return True on success and False on failure
+ ## connect and return banner
try:
sckt.connect((host, port))
+ banner = sckt.recv(80)
sckt.close()
+ return banner.decode().replace('\n','')
+ except KeyboardInterrupt:
+ exit()
+ except:
+ return "banner_error"
+
+## Open connection on specific port, return True if successful
+def connScan(host, port, wait, notor, openports):
+ ## 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 add to openports, return False on failure
+ try:
+ sckt.connect((host, port))
+ sckt.close()
+ openports.append(port)
return True
except KeyboardInterrupt:
exit()
@@ -25,18 +48,31 @@ def connScan(host, port, wait, notor):
return False
-## This function goes throgh all ports and calls connScan for each one, returns list of open ports
-def portScan(host, ports, wait, notor):
+## Go through all ports and call connScan for each, return list of open ports
+## If more threads than JOBS, wait until they finish
+def portScan(host, ports, wait, notor, jobs):
openports = list()
+ threads = list()
+
for p in ports:
if p > 65535:
return openports
- elif connScan(host, p, wait, notor):
- openports.append(p)
+
+ while threading.activeCount() >= jobs + 1:
+ pass
+
+ thread=threading.Thread(target=connScan,args=(host, p, wait, notor, openports))
+ threads.append(thread)
+ thread.start()
+
+ ## Wait until all threads are done
+ for thread in threads:
+ thread.join()
+
return openports
-## This function goes throgh all hosts and calls portScan for each one, returns dictionary of hosts with open ports
-def hostScan(host, ports, wait, notor):
+## Go through all hosts and call portScan for each one, return dictionary of hosts with their open ports
+def hostScan(host, ports, wait, notor, jobs):
ret = dict()
## Check if python version 3
try:
@@ -50,20 +86,20 @@ def hostScan(host, ports, wait, notor):
if ips.num_addresses > 1:
for ip in ips.hosts():
if ip.is_private:
- ret[str(ip)] = portScan(str(ip), ports, wait, True)
+ ret[str(ip)] = portScan(str(ip), ports, wait, True, jobs)
else:
- ret[str(ip)] = portScan(str(ip), ports, wait, notor)
+ ret[str(ip)] = portScan(str(ip), ports, wait, notor, jobs)
else:
if ips.is_private:
- ret[str(host)] = portScan(str(host), ports, wait, True)
+ ret[str(host)] = portScan(str(host), ports, wait, True, jobs)
else:
- ret[str(host)] = portScan(str(host), ports, wait, notor)
+ ret[str(host)] = portScan(str(host), ports, wait, notor, jobs)
## Otherwise scan host as usual
except:
if host == 'localhost':
- ret[str(host)] = portScan(str(host), ports, wait, True)
+ ret[str(host)] = portScan(str(host), ports, wait, True, jobs)
else:
- ret[str(host)] = portScan(str(host), ports, wait, notor)
+ ret[str(host)] = portScan(str(host), ports, wait, notor, jobs)
return ret
@@ -79,7 +115,9 @@ def main():
parser.add_argument("-p", "--ports", metavar="PORTS", dest="tgtPort", help="ports to scan, seperated by a comma", 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=3)
parser.add_argument("--clearnet", dest="clearnet", help="don't use Tor for scanning, connect directly instead", action="store_true")
+ parser.add_argument("--banner", dest="banner", help="print data received from open ports", action="store_true")
parser.add_argument("--torport", metavar="TORPORT", dest="torPort", type=int, help="port on which Tor is listening on", default="9050")
+ parser.add_argument("-j", "--jobs", metavar="JOBS", dest="jobs", type=int, help="maximum number of open connections at the same time", default="8")
parser.add_argument("--output", metavar="OUTFILE", dest="outFile", help="write scan results to output file", default="empty_outfile")
args = parser.parse_args()
@@ -140,14 +178,20 @@ def main():
HOSTS = args.HOSTS.split(",")
WAIT_TIME = args.sockTimeout
CLEARNET = False
+ BANNER = False
OUTFILE = args.outFile
+ JOBS = args.jobs
if args.clearnet:
CLEARNET=True
- ## Check if Tor is running if CLEARNET is False
+ if args.banner:
+ BANNER=True
+
+ ## Check if Tor is running
+ emptylist=list()
if CLEARNET == False:
- if connScan("127.0.0.1", args.torPort, 3, True):
+ if connScan("127.0.0.1", args.torPort, 3, True, emptylist):
pass
else:
print("Tor is not running on port {}.".format(args.torPort))
@@ -156,36 +200,41 @@ def main():
## Checking for file output
if OUTFILE != "empty_outfile":
f = open(OUTFILE, "w")
+ else:
+ f = sys.stdout
## Display message that scan is starting
- print("Starting a scan...")
+ f.write("Starting a scan...\n")
## Scan each host in HOSTS list
r = dict()
for h in HOSTS:
- r = hostScan(h, PORTS, WAIT_TIME, CLEARNET)
- if OUTFILE == "empty_outfile":
- print("Results for: {}".format(h))
- else:
- f.write("Results for: {}".format(h))
+ r = hostScan(h, PORTS, WAIT_TIME, CLEARNET, JOBS)
for i in r.keys():
if len(r[i]) != 0:
- if OUTFILE == "empty_outfile":
- print('{} open ports: {}'.format(i, str(r[i])))
- else:
- f.write('{} open ports: {}\n'.format(i, str(r[i])))
+ f.write('Tmap scan report for {}\n'.format(i))
+ if BANNER == False:
+ f.write('PORT\tSTATE\n')
+ for j in r[i]:
+ f.write('{}\topen\n'.format(j))
+ if BANNER:
+ f.write('PORT\tSTATE\tBANNER\n')
+ for j in r[i]:
+ banner = getBanner(i,j,WAIT_TIME, CLEARNET)
+ if banner == "banner_error":
+ f.write('{}\topen\n'.format(j))
+ else:
+ f.write('{}\topen\t{}\n'.format(j,banner))
## Record time of program stopping and display the time running to the user
endTime = time.time()
totalTime = round(endTime - startTime, 2)
- if OUTFILE == "empty_outfile":
- print("Scan done in {} seconds".format(totalTime))
- else:
- f.write("Scan done in {} seconds\n".format(totalTime))
- f.close()
- print("Results written to {}".format(OUTFILE))
+ f.write("Scan done in {} seconds\n".format(totalTime))
+ if OUTFILE != "empty_outfile":
+ print("Results written to {}".format(OUTFILE))
+ f.close()
if __name__ == "__main__":
main()