美文网首页大数据 爬虫Python AI SqlPython小哥哥
如何利用 Python 实现快速端口扫描?

如何利用 Python 实现快速端口扫描?

作者: 14e61d025165 | 来源:发表于2019-04-19 15:18 被阅读0次

对线上服务器进行端口扫描是一件很有用的事,可以验证你的防火墙规则,避免暴漏不需要的服务。也可以知道你机器上开了哪些服务,不用等乌云爆出来了才知道,有人黑进内网玩了好几个月。哈哈,真事,服务器被通过zabbix黑进来,开了一个socket5的进程,自由进出。反正,这玩意很有用,本着奉献精神,把代码放出来,共同学习。

image

功能很简单,对服务器进行扫描,生成html格式的扫描结果,对扫描结果发邮件。格式方面做了点处理,定义端口白名单,正常端口显示绿色,异常端口显示红色。算是一种告警。对服务器进行全端口扫描是很耗时的一件事,每台6万多个端口,而且还取决于扫描机器到目标机的网络连接情况。受不了这个蜗牛速度,开发了第一版的单线程版本后,又实现了一个多进程的版本,果然爽了好多。整个人都好了……

mytools.py 这是定义的一个函数库,截取了用到的一个函数,这个sendemail的发邮件的函数,当然当前场景可以定义的一个文件中,不过,对程序按模块拆分是个好的习惯。哈哈,我有点pythonic了。

-- coding:utf-8 --

import smtplib

from email.mime.text import MIMEText

from email.header import Header

def sendemail(sender,receiver,subject,content,smtpserver,smtpuser,smtppass):

msg = MIMEText(content,'html','utf-8')#中文需参数‘utf-8',单字节字符不需要

msg['Subject'] = Header(subject, 'utf-8')

msg['From'] = '<%s>' % sender

msg['To'] = ";".join(receiver)

try:

    smtp = smtplib.SMTP()

    smtp.connect(smtpserver)

    smtp.login(smtpuser, smtppass)

    smtp.sendmail(sender, receiver, msg.as_string())

    smtp.quit()

except Exception,e:

    print e

nmscan.py 实现端口扫描的程序,单线程版本,代码有点长,慎入

!/usr/bin/python

-- coding:utf-8 --

import nmap

import re

import mytools as tool

import sys

reload(sys)

sys.setdefaultencoding('utf8')

def nmScan(hostlist,portrange,whitelist):

    p = re.compile("^(\d*)\-(\d*)$")

if type(hostlist) != list:

        help()

    portmatch = re.match(p,portrange)

if not portmatch:

        help()

    l = []

    for host in hostlist:

        result = ''

nm = nmap.PortScanner()

        tmp = nm.scan(host,portrange)

        result = result + "<h2>ip地址:%s 主机名:[%s]  ......  %s</h2><hr>" %(host,tmp['scan'][host]['hostname'],tmp['scan'][host]['status']['state'])

        try:

            ports = tmp['scan'][host]['tcp'].keys()

        except KeyError,e:

            if whitelist:

                whitestr = ','.join(whitelist)

                result = result + "未扫到开放端口!请检查%s端口对应的服务状态" %whitestr 

            else:

                result = result + "扫描结果正常,无暴漏端口"

                continue

        for port in ports:

           info = ''

           if port not in whitelist:

               info = '<strong><font color=red>Alert:非预期端口</font><strong>&nbsp;&nbsp;' 

           else:

               info = '<strong><font color=green>Info:正常开放端口</font><strong>&nbsp;&nbsp;'

           portinfo = "%s <strong>port</strong> : %s &nbsp;&nbsp;<strong>state</strong> : %s &nbsp;&nbsp;<strong>product<strong/> : %s <br>" %(info,port,tmp['scan'][host]['tcp'][port]['state'],

                                                                    tmp['scan'][host]['tcp'][port]['product'])

           result = result + portinfo

        l.append([host,str(result)])

return l

def help():

print "Usage: nmScan(['127.0.0.1',],'0-65535')"

if name == "main":

hostlist = ['10.10.10.10','10.10.10.11']

portrange = '0-65535'

whitelist = [80,443]

l = nmScan(hostlist,portrange,whitelist)

sender = 'douniwan@qq.com'

receiver = ['gccmx@163.com','gccmx@qq.com']

subject = '服务器端口扫描'

smtpserver = 'smtp.exmail.qq.com'

smtpuser = 'gaochenchao@huoqiu.cn'

smtppass = 'gccmx163'

mailcontent = ''

for i in range(len(l)):

    mailcontent = mailcontent + l[i][1]

tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)

mutinmscan.py 端口扫描的多进程版本,比照单线程版本最大的一个变化是nmscan函数的实现上,单线程传递一个服务器列表,在函数内部循环该列表,读取扫描结果,生成报告邮件。mutinmscan版的函数是接受一个ip地址,循环这一部分使用了mutiprocess库的Pool,并使用其map函数实现对服务器ip列表的迭代。多线程,一节更比五节强……源代码加群!欢迎加入新手技术交流基地:*1004391443 群里有大牛解答,有资源,有源码,学不学的会就看你了!

!/usr/bin/python

-- coding:utf-8 --

import nmap

import re

import mytools as tool

import sys

from multiprocessing import Pool

from functools import partial

reload(sys)

sys.setdefaultencoding('utf8')

def nmScan(host,portrange,whitelist):

    p = re.compile("^(\d*)\-(\d*)$")

    # if type(hostlist) != list:

    #     help()

    portmatch = re.match(p,portrange)

    if not portmatch:

        help()

    if host == '121.42.32.172':

        whitelist = [25,]

    result = ''

    nm = nmap.PortScanner()

    tmp = nm.scan(host,portrange)

    result = result + "<h2>ip地址:%s 主机名:[%s]  ......  %s</h2><hr>" %(host,tmp['scan'][host]['hostname'],tmp['scan'][host]['status']['state'])

    try:

        ports = tmp['scan'][host]['tcp'].keys()

        for port in ports:

            info = ''

            if port not in whitelist:

               info = '<strong><font color=red>Alert:非预期端口</font><strong>&nbsp;&nbsp;'

            else:

               info = '<strong><font color=green>Info:正常开放端口</font><strong>&nbsp;&nbsp;'

            portinfo = "%s <strong>port</strong> : %s &nbsp;&nbsp;<strong>state</strong> : %s &nbsp;&nbsp;<strong>product<strong/> : %s <br>" %(info,port,tmp['scan'][host]['tcp'][port]['state'],                                                                       tmp['scan'][host]['tcp'][port]['product'])

            result = result + portinfo

    except KeyError,e:

        if whitelist:

            whitestr = ','.join(whitelist)

            result = result + "未扫到开放端口!请检查%s端口对应的服务状态" %whitestr                

        else:

            result = result + "扫描结果正常,无暴漏端口"           

    return result

def help():

    print "Usage: nmScan(['127.0.0.1',],'0-65535')"

    return None

if name == "main":

hostlist = ['10.10.10.1','10.10.10.2']

pool = Pool(5)

nmargu = partial(nmScan,portrange='0-65535',whitelist=[])

results = pool.map(nmargu,hostlist)

#send email

sender = 'gccmx@163.com'

receiver = ['gccmx@qq.com',]

subject = '服务器端口扫描'

smtpserver = 'smtp.exmail.qq.com'

smtpuser = 'gccmx@163.com'

smtppass = 'gccmx163'

mailcontent = '<br>'.join(results)

tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)

扫描结果在本文开篇就展示了的~~

相关文章

网友评论

    本文标题:如何利用 Python 实现快速端口扫描?

    本文链接:https://www.haomeiwen.com/subject/tfaqgqtx.html