Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Python 使用python-nmap模块实现端口扫描器

对线上服务器进行端口扫描是一件很有用的事,可以验证你的防火墙规则,避免暴漏不需要的服务。也可以知道你机器上开了哪些服务,不用等乌云爆出来了才知道,有人黑进内网玩了好几个月。哈哈,真事,服务器被通过zabbix黑进来,开了一个socket5的进程,自由进出。反正,这玩意很有用,本着奉献精神,把代码放出来,共同学习。功能很简单,对服务器进行扫描,生成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 enmscan.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 = ["linuxidc@163.com","linuxidc@qq.com"]
    subject = "服务器端口扫描"
    smtpserver = "smtp.exmail.qq.com"
    smtpuser = "gaochenchao@huoqiu.cn"
    smtppass = "linuxidc163"
    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列表的迭代。多线程,一节更比五节强……#!/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 = "linuxidc@163.com"
    receiver = ["linuxidc@qq.com",]
    subject = "服务器端口扫描"
    smtpserver = "smtp.exmail.qq.com"
    smtpuser = "linuxidc@163.com"
    smtppass = "linuxidc163"
    mailcontent = "<br>".join(results)
    tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)扫描结果:马赛克阻碍了人类文明的进步,尤其是在欣赏岛国动作片的时候,但是,亲,我不能把俺们的服务器给你看的,你懂的!--------------------------------------分割线 --------------------------------------Python 用socket模块实现检测端口和检测web服务  http://www.linuxidc.com/Linux/2013-06/86449.htmCentOS上源码安装Python3.4  http://www.linuxidc.com/Linux/2015-01/111870.htm《Python核心编程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码] http://www.linuxidc.com/Linux/2013-11/92693.htmPython脚本获取Linux系统信息 http://www.linuxidc.com/Linux/2013-08/88531.htm在Ubuntu下用Python搭建桌面算法交易研究环境 http://www.linuxidc.com/Linux/2013-11/92534.htmPython 语言的发展简史 http://www.linuxidc.com/Linux/2014-09/107206.htmPython 的详细介绍:请点这里
Python 的下载地址:请点这里本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-02/113355.htm