设为首页 收藏本站
查看: 4316|回复: 0

[经验分享] Python 使用python-nmap模块实现端口扫描器

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-2-12 08:36:40 | 显示全部楼层 |阅读模式
     对线上服务器进行端口扫描是一件很有用的事,可以验证你的防火墙规则,避免暴漏不需要的服务。也可以知道你机器上开了哪些服务,不用等乌云爆出来了才知道,有人黑进内网玩了好几个月。哈哈,真事,服务器被通过zabbix黑进来,开了一个socket5的进程,自由进出。反正,这玩意很有用,本着奉献精神,把代码放出来,共同学习。


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

mytools.py 这是定义的一个函数库,截取了用到的一个函数,这个sendemail的发邮件的函数,当然当前场景可以定义的一个文件中,不过,对程序按模块拆分是个好的习惯。哈哈,我有点pythonic了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-*- 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 实现端口扫描的程序,单线程版本,代码有点长,慎入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/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[1]
    tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)




mutinmscan.py 端口扫描的多进程版本,比照单线程版本最大的一个变化是nmscan函数的实现上,单线程传递一个服务器列表,在函数内部循环该列表,读取扫描结果,生成报告邮件。mutinmscan版的函数是接受一个ip地址,循环这一部分使用了mutiprocess库的Pool,并使用其map函数实现对服务器ip列表的迭代。多线程,一节更比五节强……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/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)




扫描结果:马赛克阻碍了人类文明的进步,尤其是在欣赏岛国动作片的时候,但是,亲,我不能把俺们的服务器给你看的,你懂的!
QQ截图20150212083336.png


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-42484-1-1.html 上篇帖子: python 下获取系统时间并格式化输出 下篇帖子: python time模块学习 扫描器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表