君は春の中にいる、かけがえのない春の中にいる.

你驻足于春色中,于那独一无二的春色之中.

python-nmap与python-libnmap对比

写一个小项目时的对比,项目地址:

Cynops

0x01 简介

写的练手项目中用到了python调用nmap的情景,对比使用了两款常见的python库

  • python-nmap
  • python-libnmap

两种库各有各的优点,可以考虑在不同的环境下使用。

0x02 源码分析

首先,我们从源码的角度来分析两个库:

  1. py-nmap

它的代码统一写在一个单文件中,主要定义了三种扫描类、一个目标字典类和一个扫描错误类。

基础类PortScanner,该类主要提供扫描方法、扫描结果xml输出、扫描CSV结果的文本输出功能。

异步扫描类PortScannerAsync,该类主要提供异步扫描功能。

生成扫描类PortScannerYield提供一种作为生成器的扫描方式。

从源码可以看出,它主要就是通过python调用nmap进行扫描,并没有太多其他的实现,所有的nmap需求通过nmap自身的参数来实现。

  1. py-libnmap

相比之下,libnmap的函数实现就要复杂一些,它定义了包括对象、插件和基础功能在内的多个函数。

基础功能包process,主体类NmapProcess,在该类中,定义类包括扫描行为、输出结果、后台执行、sudo执行、执行时间状态等多种方法。

结果解析包Parser,能够对输出的文本结果进行多种来源格式的解析,但是在实际运行过程中会发现对于一些特殊的请求结果,解析效果不是很令人满意,而且用起来没有自己写解析器顺手。

对象模块负责定义各种不同的Nmap对象体

插件模块提供了数据库和后台的功能插件。

从这里看到libnmap的实现更加庞大,不只是单单调用nmap,还对nmap中的交互对象进行了类定义,从插件模块可以看出,该库还试图通过插件来不断丰富自己功能。

0x03 实际测试

实际测试中,选取默认扫描、使用nse脚本扫描和traceroute扫描三种方式来比对它们的扫描的结果差异。统一用我的博客作为扫描目标。

默认扫描

直接调用扫描类,只提供目标IP,其他参数缺省。

  1. py-nmap

    nmap -oX - -sV 123.207.68.169
    

这一条是该库调用Nmap时使用到的参数

可以看到结果是一个字典,提供扫描状态、扫描信息、扫描结果的查询。

  1. py-libnmap

    nmap -oX - -vvv --stats-every 1s -sT 123.207.68.169
    

libnmap的默认扫描更加复杂。

默认能够获取到的是标准的文本格式Nmap xml结果,需要使用上面提到的Parser进行解析。

脚本调用

我们对特定的80端口使用http-enum,查看结果。

  1. py-nmap

    'script': {'http-enum': '\n  /atom.xml: RSS or Atom feed\n  
                        /test/: Test page\n  
                        /test.html: Test page\n  
                        /archives/: Potentially interesting folder\n  
                        /css/: Potentially interesting folder\n  
                        /images/: Potentially interesting folder\n
    

可以看到可以使用脚本的输出结果。

  1. py-libnmap,同时在这里使用Parser来解析结果。

同样通过xml输出了脚本的结果,解析后的结果需要参照对象模块里不同的对象类来输出用户需要的结果,这里用起来觉得它的封装不是很清晰,不如py-nmap的结果更加友好。

traceroute

这里分别再次用两个包执行nmap的traceroute对比结果,之所以单独测试了traceroute,是因为我的项目里用到了这项功能。

  1. py-nmap

在获取traceroute时,通过nm.analyse_nmap_xml_scan()是无法获取到跳转的结果,这时需要nm.get_nmap_last_output()来获取xml的结果。

  1. py-libnmap

由于lib的基本输出方式是输出xml,但是它的解析函数用起来也不方便,所以还是推荐自己编写解析器。

0x03 对比

作为调用原理相同,甚至实现方法也相近的两个库,有一个最明显的区别就是py-nmap趋向于简洁,而py-libnmap趋向于功能完整。对于快捷的扫描,推荐使用nmap包,而对于拥有入库、高级对象封装等功能的项目则可以使用libnmap。