用PYTHON解析MASSCAN/NMAP的扫描结果

做安全常使用Nmap和Masscan进行端口扫描,小范围扫描首选Nmap,大范围扫描则选速度快的Masscan,二者都支持输出XML格式结果。本文聚焦扫描结果解析,介绍了用Python解析Masscan和Nmap的XML格式扫描结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

做安全的一般都会用到Nmap进行端口扫描,在小范围内进行扫描时Nmap绝对是首选——丰富的扫描选项/模块、较高的准确度;在大范围的扫描中,你应该选择Masscan,因为它速度奇快,而且准确率还可以接受。它们都支持自定义结果的输出格式,其中比较通用的就是XML格式(Masscan为了尽量和Nmap做到兼容,除了扫描选项比较像之外,输出结果的XML格式也基本兼容)。扫描完了之后需要对结果进行解析,这就是本文的具体场景需求。

解答:

1.解析Masscan的XML格式扫描结果

#!/usr/bin/env python
# coding=utf-8

import sys, time
import xmltodict

def main():
    with open('./masscan_result.xml') as fp:
        xml_obj = xmltodict.parse(fp.read())
        nmaprun = xml_obj['nmaprun']
        host = nmaprun['host']
        for entry in host[:10]:  #调试阶段只打印前10条记录
            port = entry['ports']['port']
            if int(port['@portid']) == 80:
                name = entry['address']['@addr']
                print 'http://' + name + '/'
            elif int(port['@portid']) == 443:
                name = entry['address']['@addr']
                print 'https://' + name + '/'
            elif int(port['@portid']) == 21:
                name = entry['address']['@addr']
                print 'ftp://' + name + '/'
            else:
                name = entry['address']['@addr']
                print 'http://' + name + ':' + str(port['@portid']) + '/'

if __name__ == '__main__':
    time_start = time.time()
    try:
        main()
    except KeyboardInterrupt:
        print 'Killed by user'
        sys.exit(0)
    print "Spend {0} seconds.\n".format(time.time() - time_start)



2.解析Nmap的XML格式扫描结果

#!/usr/bin/env python
# coding=utf-8

import sys, time
import xmltodict

def main():
    fp_content = ''
    try:
        with open(sys.argv[1]) as fp:
            fp_content = fp.read().replace('\n', '')
    except IOError:
        print 'File IO Error'
        sys.exit(-1)

    nmap_xml = xmltodict.parse(fp_content)
    nmaprun = nmap_xml['nmaprun']
    scanhost = nmaprun['host']
    for i in scanhost:
        address = i['address']['@addr']
        port1 = dict(i)
        try:
            if int(port1['ports']['port']['@portid']) > 0:
                port2 = port1['ports']['port']['@portid']
                if port2 == '80':
                    print 'http://'+address+'/'
                elif port2 == '443':
                    print 'https://'+address+'/'
                else:
                    print 'http://'+address+':'+port2+'/'
        except:
            port2 = i['ports']['port']
            for z in port2:
                x = z['@portid']
                if x == '80':
                    print 'http://'+address+'/'
                elif x == '443':
                    print 'https://'+address+'/'
                else:
                    print 'http://'+address+':'+x+'/'

if __name__ == '__main__':
    time_start = time.time()
    try:
        main()
    except KeyboardInterrupt:
        print 'Killed by user'
        sys.exit(0)
    print "Spend {0} seconds.\n".format(time.time() - time_start)

参考链接:
https://github.com/maK-/scantastic-tool
https://github.com/martinblech/xmltodict

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿啄debugIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值