Python编写渗透工具学习笔记一 | 0x04 nmap实现端口扫描(准确性更高)

0x04 nmap实现端口扫描

在windows下安装nmap模块会遇到一些障碍,主要是路径的一些问题,在linux下会比较容易。

#实现功能 端口扫描

先介绍一下nmap在这个脚本中用到的方法

nmScan = nmap.PortScanner()#创建一个portscanner()类对象
nmScan.scan(tgtHost,tgtPort)#进行基本的nmap扫描
state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']#获取扫描状态

附上一个描述和一个使用例子

例子

实现思路:

用sys模块接受命令行参数,使得用户可以自定义扫描的主机和端口

具体实现脚本

import nmap
import optparse
#扫描
def nmapScan(tgtHost,tgtPort):
    nmScan = nmap.PortScanner()#创建一个portscanner()类对象
    nmScan.scan(tgtHost,tgtPort)#进行基本的nmap扫描
    state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']#获取扫描状态
    print "[*] " + tgtHost + " tcp/"+tgtPort +" "+state
def main():
    parser = optparse.OptionParser('usage %prog '+\
                                   '-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()

进一步优化脚本

这里的逻辑较为简单易懂,上面的脚本中用户需要自己用逗号一个一个地输入端口,但如果当端口数量比较大的时候,这明显就会非常不方便了,所以下面优化一下脚本,让这个脚本可以实现对一个特定范围的端口扫描或者对自己自定义的特定某几个端口进行扫描

具体代码如下

以下为源码:

端口扫描

可以实现对一个特定范围的端口扫描或者

对自己自定义的特定某几个端口进行扫描

import nmap
import optparse
def nmapScan(tgtHost,tgtPort):
    nmScan = nmap.PortScanner()#创建一个portscanner()类对象
    nmScan.scan(tgtHost,tgtPort)#进行基本的nmap扫描
    state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']#获取扫描状态
    print "[*] " + tgtHost + " tcp/"+tgtPort +" "+state
def main():
    #定义说明等
    parser = optparse.OptionParser('usage %prog -H <target host> -p <target port> -prange <target ports>')
    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') 
    parser.add_option('-P',dest='prange',type='string',help='define ports')
    (options, args) = parser.parse_args()
    tgtHost = options.tgtHost
    tgtPorts = str(options.tgtPort).split(',')
    prange=str(options.prange).split('-')
    #参数为空则打印使用方法
    if prange[0]==None:
        if (tgtHost == None) | (tgtPorts[0] == None):
            print parser.usage
            print '[#]example:'
            print 'python 2-nmapScan.py -H 127.0.0.1 -p 21,22,23,25,80,8001,8010,8080,1433,3389,445'
            print 'python 2-nmapScan.py -H 127.0.0.1 -prange 1-65535'
            exit(0)
        for tgtPort in tgtPorts:
            nmapScan(tgtHost, tgtPort)
    else:
        if tgtHost==None:
            print parser.usage
            print '[#]example:'
            print 'python 2-nmapScan.py -H 127.0.0.1 -p 21,22,23,25,80,8001,8010,8080,1433,3389,445'
            print 'python 2-nmapScan.py -H 127.0.0.1 -P 1-65535'
            exit(0)
        low=int(prange[0])
        height=int(prange[1])
        for i in range(low,height+1):
            tgtPort=str(i)
            nmapScan(tgtHost, tgtPort)
if __name__ == '__main__':
    main()
'''

先创建一个portscanner()类对象,这使我们能用这个对象完成扫描操作

该类有个scan()函数,它可以将目标和端口的列表作为参数输入,

并对它们进行基本的nmap扫描

需安装python_nmap包,支持2.x以及3.x

python_nmap包提供了python调用nmap的一系列接口

(一)重要类及方法:

1.创建nmap扫描器

class PortScanner()

__init__(self, nmap_search_path=('nmap', '/usr/bin/nmap', '/usr/local/bin/nmap', '/sw/bin/nmap', '/opt/local/bin/nmap'))

Initialize PortScanner module

* detects nmap on the system and nmap version

* may raise PortScannerError exception if nmap is not found in the path

:param nmap_search_path: tupple of string where to search for nmap executable. Change this if you want to use a specific version of nmap.

:returns: nothing

2.扫描器方法

scan(self, hosts='127.0.0.1', ports=None, arguments='-sV', sudo=False)
    Scan given hosts
    May raise PortScannerError exception if nmap output was not xml
    Test existance of the following key to know if something went wrong : ['nmap']['scaninfo']['error']
    If not present, everything was ok.
    :param hosts: string for hosts as nmap use it 'scanme.nmap.org' or '198.116.0-255.1-127' or '216.163.128.20/20'
    :param ports: string for ports as nmap use it '22,53,110,143-4564'
    :param arguments: string of arguments for nmap '-sU -sX -sC'
    :param sudo: launch nmap with sudo if True
    :returns: scan_result as dictionnary

(二)例子

import nmap
scanner = nmap.PortScanner()    #nmap_search_path已包含了nmap所在路径,若默认路径中没有nmap,则需指出
results = scanner.scan(hosts='192.168.2.1',ports='80')
print results
{'nmap': {'command_line': 'nmap -oX - -p 80 -sV 192.168.2.1',
          'scaninfo': {'tcp': {'method': 'syn', 'services': '80'}},
          'scanstats': {'downhosts': '0',
                        'elapsed': '11.59',
                        'timestr': 'Thu Jul 21 10:08:34 2016',
                        'totalhosts': '1',
                        'uphosts': '1'}},
 'scan': {'192.168.2.1': {'addresses': {'ipv4': '192.168.2.1',
                                        'mac': 'D0:C7:C0:6A:F6:A0'},
                          'hostnames': [],
                          'status': {'reason': 'arp-response',
                                     'state': 'up'},
                          'tcp': {80: {'conf': '3',
                                       'cpe': '',
                                       'extrainfo': '',
                                       'name': 'http',
                                       'product': '',
                                       'reason': 'no-response',
                                       'state': 'filtered',
                                       'version': ''}},
                          'vendor': {'D0:C7:C0:6A:F6:A0': 'Tp-link '
                                                          'Technologies'}}}}
root@kali64:~# python test.py
{'nmap':
 {
  'scanstats': 
  { 'uphosts': '1', 
    'timestr': 'Mon Nov 20 22:26:21 2017', 
    'downhosts': '0', 
    'totalhosts': '1', 
    'elapsed': '9.09'}, 
    'scaninfo': 
     {'tcp': 
       {'services': '80', 
        'method': 'syn'
       }
     }, 
    'command_line': 'nmap -oX - -p 80 -sV 10.10.10.1'
  }, 
  'scan': 
   {'10.10.10.1': 
     {'status': 
        {'state': 'up', 
         'reason': 'arp-response'
        }, 
      'hostnames': [{'type': '', 'name': ''}], 
      'vendor': {'00:50:56:C0:00:08': 'VMware'}, 
      'addresses': {'mac': '00:50:56:C0:00:08', 'ipv4': '10.10.10.1'}, 
      'tcp': {80: 
                { 'product': 'Apache httpd', 
                  'state': 'open', 
                  'version': '2.4.18', 
                  'name': 'http', 
                  'conf': '10', 
                  'extrainfo': '(Win32) OpenSSL/1.0.2e PHP/5.5.30', 
                  'reason': 'syn-ack', 
                  'cpe': 'cpe:/a:apache:http_server:2.4.18'
                }
             }
      }
    }
}
'''

先创建一个portscanner()类对象,这使我们能用这个对象完成扫描操作

该类有个scan()函数,它可以将目标和端口的列表作为参数输入,

并对它们进行基本的nmap扫描

需安装python_nmap包,支持2.x以及3.x

python_nmap包提供了python调用nmap的一系列接口

(一)重要类及方法:

1.创建nmap扫描器

class PortScanner()
    __init__(self, nmap_search_path=('nmap', '/usr/bin/nmap', '/usr/local/bin/nmap', '/sw/bin/nmap', '/opt/local/bin/nmap'))
    Initialize PortScanner module
    * detects nmap on the system and nmap version
    * may raise PortScannerError exception if nmap is not found in the path
    :param nmap_search_path: tupple of string where to search for nmap executable. Change this if you want to use a specific version of nmap.
    :returns: nothing

2.扫描方法

scan(self, hosts='127.0.0.1', ports=None, arguments='-sV', sudo=False)
    Scan given hosts
    May raise PortScannerError exception if nmap output was not xml
    Test existance of the following key to know if something went wrong : ['nmap']['scaninfo']['error']
    If not present, everything was ok.
    :param hosts: string for hosts as nmap use it 'scanme.nmap.org' or '198.116.0-255.1-127' or '216.163.128.20/20'
    :param ports: string for ports as nmap use it '22,53,110,143-4564'
    :param arguments: string of arguments for nmap '-sU -sX -sC'
    :param sudo: launch nmap with sudo if True
    :returns: scan_result as dictionnary

(二)例子

import nmap
scanner = nmap.PortScanner()    #nmap_search_path已包含了nmap所在路径,若默认路径中没有nmap,则需指出
results = scanner.scan(hosts='192.168.2.1',ports='80')
print results
{'nmap': {'command_line': 'nmap -oX - -p 80 -sV 192.168.2.1',
          'scaninfo': {'tcp': {'method': 'syn', 'services': '80'}},
          'scanstats': {'downhosts': '0',
                        'elapsed': '11.59',
                        'timestr': 'Thu Jul 21 10:08:34 2016',
                        'totalhosts': '1',
                        'uphosts': '1'}},
 'scan': {'192.168.2.1': {'addresses': {'ipv4': '192.168.2.1',
                                        'mac': 'D0:C7:C0:6A:F6:A0'},
                          'hostnames': [],
                          'status': {'reason': 'arp-response',
                                     'state': 'up'},
                          'tcp': {80: {'conf': '3',
                                       'cpe': '',
                                       'extrainfo': '',
                                       'name': 'http',
                                       'product': '',
                                       'reason': 'no-response',
                                       'state': 'filtered',
                                       'version': ''}},
                          'vendor': {'D0:C7:C0:6A:F6:A0': 'Tp-link '
                                                          'Technologies'}}}}
root@kali64:~# python test.py
{'nmap':
 {
  'scanstats': 
  { 'uphosts': '1', 
    'timestr': 'Mon Nov 20 22:26:21 2017', 
    'downhosts': '0', 
    'totalhosts': '1', 
    'elapsed': '9.09'}, 
    'scaninfo': 
     {'tcp': 
       {'services': '80', 
        'method': 'syn'
       }
     }, 
    'command_line': 'nmap -oX - -p 80 -sV 10.10.10.1'
  }, 
  'scan': 
   {'10.10.10.1': 
     {'status': 
        {'state': 'up', 
         'reason': 'arp-response'
        }, 
      'hostnames': [{'type': '', 'name': ''}], 
      'vendor': {'00:50:56:C0:00:08': 'VMware'}, 
      'addresses': {'mac': '00:50:56:C0:00:08', 'ipv4': '10.10.10.1'}, 
      'tcp': {80: 
                { 'product': 'Apache httpd', 
                  'state': 'open', 
                  'version': '2.4.18', 
                  'name': 'http', 
                  'conf': '10', 
                  'extrainfo': '(Win32) OpenSSL/1.0.2e PHP/5.5.30', 
                  'reason': 'syn-ack', 
                  'cpe': 'cpe:/a:apache:http_server:2.4.18'
                }
             }
      }
    }
}

未完待续

原文发布于微信公众号 - 安恒网络空间安全讲武堂(gh_fa1e45032807)

原文发表时间:2017-12-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java学习123

Python3.4+Django1.7+SQLite3实现增删改查

3765
来自专栏Java架构师学习

成为顶尖程序员不得不经历的面试题

一、数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度。 · 用Java写一个冒泡排序算法 · 描述一下链式存储结构。 · 如何遍历一棵二叉树? ·...

45211
来自专栏Seebug漏洞平台

D-Link DIR-605L 拒绝服务错误报告 (CVE-2017-9675)

原文:http://hypercrux.com/bug-report/2017/06/19/DIR605L-DoS-BugReport/ 译者:Serene ...

3896
来自专栏王磊的博客

Java核心(三)并发中的线程同步与锁

乐观锁、悲观锁、公平锁、自旋锁、偏向锁、轻量级锁、重量级锁、锁膨胀...难理解?不存的!来,话不多说,带你飙车。

1312
来自专栏码洞

Java高阶必备之Netty基础原理

Netty是Java程序员通向高阶之路必须要过的门槛之一。干了几年的Java程序员发现业务开发似乎就是在SSH的世界里摸滚打爬的时候,会开始感到迷茫,难道程序员...

1032
来自专栏腾讯数据库技术

比ls快8倍?百万级文件遍历的奇技淫巧

1.3K4
来自专栏Seebug漏洞平台

Spring MVC 目录穿越漏洞(CVE-2018-1271)分析

2018年04月05日,Pivotal公布了Spring MVC存在一个目录穿越漏洞(CVE-2018-1271)。Spring Framework版本5.0到...

4462
来自专栏orientlu

UNIX IPC

管道一般为有亲缘关系进程提供单路数据流, 通过pipe(int fd[2])创建, 返回两个文件描述符, fd[0] 用于读,fd[1]用于写。 通过 read...

1622
来自专栏zingpLiu

再议Python协程——从yield到asyncio

协程,英文名Coroutine。 前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章【浅析Python多线程】),今天介绍的协程也是常用的并发手段...

2506
来自专栏Java帮帮-微信公众号-技术文章全总结

JavaWeb13-设计模式案例实现(Java真正的全栈开发)

? JavaWeb设计模式&案例 一.JavaWeb的设计模式 1. jsp模式介绍 SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一...

3336

扫码关注云+社区

领取腾讯云代金券