使用nmap&输入端口范围optparser

时间:2014-12-17 00:19:49

标签: python ports nmap

这是脚本

import nmap
import optparse

def nmapScan(tgtHost,tgtPort):
    nmScan = nmap.PortScanner()
    nmScan.scan(tgtHost,tgtPort)
    state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
    print "[*] " + tgtHost + " tcp/"+tgtPort +" "+state

def main():
    parser = optparse.OptionParser('-H <target host> -p <target port>')
    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)
    for tgtPort in tgtPorts:
        nmapScan(tgtHost, tgtPort)


if __name__ == '__main__':
    main()

当我尝试在命令行中输入一系列端口时,出现此错误。有人可以帮帮我吗?我是python的新手。在此先感谢!!

    :~$ python nmapScan.py -H 192.168.1.6 -p 20-25
Traceback (most recent call last):
  File "nmapScan.py", line 27, in <module>
    main()
  File "nmapScan.py", line 23, in main
    nmapScan(tgtHost, tgtPort)
  File "nmapScan.py", line 7, in nmapScan
    state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
ValueError: invalid literal for int() with base 10: '20-25'

2 个答案:

答案 0 :(得分:0)

import nmap
import optparse

def nmapScan(tgtHost,tgtPort):
    nmScan = nmap.PortScanner()
    nmScan.scan(tgtHost,tgtPort)
    state = nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
    print "[*] " + tgtHost + " tcp/"+tgtPort +" "+state


def main():
    parser = optparse.OptionParser('-H <target host> -p <target port>')
    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()
    if not options.tgtHost or not options.tgtPort:
        print parser.usage
        exit(0)
    tgtHost = options.tgtHost
    ports = options.tgtPort
    tgtPorts = options.tgtPort.split(',') if "," in options.tgtPort else map(str,range(int(ports.split("-")[0]),int(ports.split("-")[1]+1))) 
    for tgtPort in tgtPorts:
        nmapScan(tgtHost, tgtPort)
if __name__ == '__main__':
    main()

就像我在评论中所说,你应该使用一些try / excepts来避免你的脚本崩溃。

~$ python nm.py -H 10.10.10.100 -p 20-25
[*] 10.10.10.100  tcp/20 closed
[*] 10.10.10.100  tcp/21 closed
[*] 10.10.10.100  tcp/22 open
[*] 10.10.10.100  tcp/23 closed
[*] 10.10.10.100  tcp/24 closed

$ python nm.py -H 10.10.10.100  -p 20,21
[*] 10.10.10.100  tcp/20 closed
[*] 10.10.10.100  tcp/21 closed

~$ python nm.py -H 10.10.10.100 
-H <target host> -p <target port>

根据documentation,您可以使用nmap.PortScanner()获取20-25形式的字符串作为您可以在脚本中使用的范围,解析dict以获取输出并让您的生活更轻松:

In [7]: import nmap

In [8]: nm = nmap.PortScanner()

In [9]: nm = nmap.PortScanner()

In [10]: nm.scan('127.0.0.1', '20-25')

我们可以使用正确的nmap语法缩短您的脚本:

import nmap
import optparse

def main():
    parser = optparse.OptionParser('-H <target host> -p <target port>')
    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()
    if not options.tgtHost or not options.tgtPort:
        print parser.usage
        exit(0)
    tgtHost = options.tgtHost
    tgtPorts = options.tgtPort

    nm = nmap.PortScanner()
    res = nm.scan(tgtHost,tgtPorts)
    for port in nm[tgtHost]["tcp"].keys():
        print "[*]  {} tcp/{} {}".format(tgtHost,port,res["scan"][tgtHost]["tcp"][int(port)]["state"])

if __name__ == '__main__':
    main()


~$ python nm.py -H 10.10.10.100 -p 20-25
[*]  10.10.10.100  tcp/20 closed
[*]  10.10.10.100  tcp/21 closed
[*]  10.10.10.100  tcp/22 open
[*]  10.10.10.100  tcp/23 closed
[*]  10.10.10.100  tcp/24 closed
[*]  10.10.10.100  tcp/25 open

答案 1 :(得分:0)

您需要区分这两种不同的格式,如果使用m-n范围格式,请在&#39; - &#39;要获取边界,请使用range()创建端口列表,并将tgtPorts设置为该范围。

这是实现这一目标的功能。您可以通过执行

将其插入代码中
tgtPorts = parse_port_spec(options.tgtPort)

而不是您当前的tgtPorts = str(options.tgtPort).split(',')

def parse_port_spec(spec):
    if ',' in spec:
        # Port list
        ports = spec.split(',')
    elif '-' in spec:
        # Port range
        start, end = map(int, spec.split('-'))
        ports = range(start, end + 1)
    else:
        # Single port
        ports = [spec]
    return map(int, ports)

但请注意,这仍然不支持完整nmap port range specification syntax。您只能使用逗号分隔列表或m-n定义的范围,但不能同时使用两者。

有关这些功能如何运作的详细信息,请参阅range()map()的文档。