releases the lock. By utilizing this semaphore, we now ensure only one thread can print to the screen at any given point in time. In our exception handling code, the keyword finally executes the following code before terminating the block.
screenLock = Semaphore(value=1)
def connScan(tgtHost, tgtPort):
try:
connSkt = socket(AF_INET, SOCK_STREAM)
connSkt.connect((tgtHost, tgtPort))
connSkt.send(‘ViolentPython\r\n’)
results = connSkt.recv(100)
screenLock.acquire()
print ‘[+]%d/tcp open’% tgtPort
print ‘[+] ’ + str(results)
except:
screenLock.acquire()
print ‘[-]%d/tcp closed’% tgtPort
finally:
screenLock.release()
connSkt.close()
Placing all other functions into the same script and adding some option parsing, we produce our final port scanner script.
import optparse
from socket import ∗
from threading import ∗
screenLock = Semaphore(value=1)
def connScan(tgtHost, tgtPort):
try:
connSkt = socket(AF_INET, SOCK_STREAM)
connSkt.connect((tgtHost, tgtPort))
connSkt.send(‘ViolentPython\r\n’)
results = connSkt.recv(100)
screenLock.acquire()
print ‘[+]%d/tcp open’% tgtPort
print ‘[+] ’ + str(results)
except:
screenLock.acquire()
print ‘[-]%d/tcp closed’% tgtPort
finally:
screenLock.release()
connSkt.close()
def portScan(tgtHost, tgtPorts):
try:
tgtIP = gethostbyname(tgtHost)
except:
print “[-] Cannot resolve ‘%s’: Unknown host”%tgtHost
return
try:
tgtName = gethostbyaddr(tgtIP)
print ‘\n[+] Scan Results for: ’ + tgtName[0]
except:
print ‘\n[+] Scan Results for: ’ + tgtIP
setdefaulttimeout(1)
for tgtPort in tgtPorts:
t = Thread(target=connScan, args=(tgtHost, int(tgtPort)))
t.start()
def main():
parser = optparse.OptionParser(‘usage%prog ’+\
‘-H -p ’)
parser.add_option(‘-H’, dest=‘tgtHost’, type=‘string’, \
help=‘specify target host’)
parser.add_option(‘-p’, dest=‘tgtPort’, type=‘string’, \
help=‘specify target port[s] separated by comma’)
(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()
Running the script against a target, we see it has an Xitami FTP server running on TCP port 21 and that TCP port 1720 is closed.
attacker:∼# python portScan.py -H 10.50.60.125 -p 21, 1720
[+] Scan Results for: 10.50.60.125
[+] 21/tcp open
[+] 220- Welcome to this Xitami FTP server
[-] 1720/tcp closed
Integrating the Nmap Port Scanner
Our preceding example provides a quick script for performing a TCP connect scan. This might prove limited as we may require the ability to perform additional scan types such as ACK, RST, FIN, or SYN-ACK scans provided by the Nmap toolkit ( Vaskovich, 1997 ). The de facto standard for a port scanning toolkit, Nmap, delivers a rather extensive amount of functionality. This begs the question, why not just use Nmap? Enter the true beauty of Python. While Fyodor Vaskovich wrote Nmap and its associated scripts in the C and LUA programming languages, Nmap is able to be integrated rather nicely into Python. Nmap produces XML based output. Steve Milner and Brian Bustin wrote a Python library that parses this XML based output. This provides us with the ability to utilize the full functionality of Nmap within a Python script. Before starting, you must install Python-Nmap, available at http://xael.org/norman/python/python-nmap/ . Ensure you take into consideration the developer’s notes regarding the different versions of