【Python】教你一步步编写banner获取脚本

【Python】教你一步步编写banner获取脚本

Hello 各位小伙伴们大家哈好,周末还过的愉快吗?

在这里插入图片描述

今天又是忙碌的周一,工作使我快乐~~

小编今天看了一眼我的公众号,发现脚本模块只挂着孤零零的一篇文章…

好吧,刚好最近学习了使用python编写banner获取脚本,今天就跟大家一起一步一步再学习一遍吧。

在这里插入图片描述

一、什么是banner?

banner可以理解为我们连上服务器后,服务器相应的第一条欢迎语句。通常通过banner我们可以获取到服务器正在运行的服务,以及服务的名称和相关版本。

例如linux下的nc命令,如下:

在这里插入图片描述

又或者是windows下的telnet返回信息:

在这里插入图片描述

由以上两个返回信息,我们可以知道这两台服务器的ftp版本分别为2.3.4和3.0.2,获取服务的版本信息后,我们是不是就可以针对性地进行渗透了呢。

二、代码篇

1、基本代码

首先我们来编写一个简单的基本代码,实现上面所说的功能。

在这里插入图片描述

这里涉及到了socket模块,什么是socket呢?可以简单的理解为一个socket就是一个连接,说明如下:

  • Socket可以通过网络实现不同主机间的进程通信,网络上各种各样的服务大都是基于Socket 来完成通信的。
  • 用“ip地址+协议+端口号”来唯一标识网络中的一个进程,这就是socket
  • 无论使用何种网络协议,最本质上都是在进行数据的接收和发送,“发送”和“接收”这两个动作就是socket处理数据的主要方式。

代码运行结果如下,可以看出对端ftp版本为3.0.2:

在这里插入图片描述

这样基础代码就完成了,关于socket模块的详细使用方法,我将在近期推出。接下来,我们一步一步来完善这个程序。

2、添加漏洞版本判断功能

假设ftp 3.0.2 版本为一个已知漏洞版本,添加if语句来对扫描的IP地址进行判断,判断是否为3.0.2版本,修改代码如下:

在这里插入图片描述

运行结果:

在这里插入图片描述

3、添加异常处理功能

为什么需要添加异常处理功能呢??

  • 程序运行过程中难免出现错误,当Python检测到错误时,解释器就无法继续执行下去,于是抛出相应的信息,这些统称为异常信息。
  • try/except语句:程序执行时,如果try子句中没有异常发生,那么except子句在try语句执行之后被忽略;如果try子句中有异常发生,那么该部分的其他语句将被忽略,直接跳到except部分,执行其后面的子句。
  • except Exception, e:不管什么类别的异常,全部都捕获,并将具体的异常信息保存到变量e里。

修改代码如下:

在这里插入图片描述

4、函数封装

为了方便多次调用,将代码根据功能分成不同的模块,改写代码如下:

在这里插入图片描述

注:if __name__== “__main__”

  • 如果python脚本独立运行,__name__的值就为__main__;如果是被调用,__name__的值就为脚本的文件名
  • 因此,该语句就是用于判断当前的程序是在怎样运行。当脚本被其他脚本调用时,放在它后面的代码是不会执行的,只有当单独执行该脚本时,才会执行这部分代码。

5、添加for循环,对多个IP进行扫描

当前代码仅对192.168.211.168进行判断,我们可以添加for循环,对多IP进行扫描

在这里插入图片描述

其他代码不变,部分输出结果:

在这里插入图片描述

6、从文本中读取ip地址进行扫描

我们也可以从文本中读取指定的IP地址进行扫描,修改代码如下:

在这里插入图片描述

注:文件操作的基本流程:

  • 调用open()函数打开文件,并创建一个File对象。
  • 调用File对象的read()或write()等方法,对文件内容进行读写等操作。a 追加 w覆盖 r只读。使用write()方法不会自动换行。
  • 调用File对象的close()方法,关闭并保存文件内容。

7、为代码添加多线程

经测试,当扫描IP地址为一整个网段时,需要10分钟才能全部扫描完成,这是因为程序需要等待第一个IP扫描完成后,才能扫描第二个IP地址。

此时我们可以为代码添加多线程,对多个IP同时进行扫描,修改代码如下:

在这里插入图片描述

为了让我们自定义的check函数,connect函数,能在相同线程中,对一组数据同步进行处理。我们将connect函数从main()中拿出来,放到check中进行调用:

在这里插入图片描述

connect函数抱持不变,接下来运行代码,不到1分钟即可完成254个IP地址扫描。

8、optparse模块,通过选项向脚本传递所需的参数

(1)当我们运行一些软件时,如sqlmap,可以向脚本传递一些参数,接下来利用optparse模块,为我们的脚本也添加此功能。

添加-f 选项,让脚本扫描指定的模块。

添加-i 选项,让脚本扫描指定的IP地址所在的整个网段。

该部分代码构想如下:

在这里插入图片描述

注释:

  • 第一行,导入optparse模块中的类OptionParser。

  • 第二行,将类实例化成对象。

  • 第三行,利用add_option()方法添加选项。-f和–file分别表示长短选项名,长选项可以省略。type指定了参数类型,默认为string,dest指定将参数赋值给哪个变量。

  • 第四行,利用add_option()方法添加选项-i和–ip。

  • 第五行,利用parse_args()方法来获取定义的选项和参数,可以视作一种固定用法。parse_args()方法返回两个值,其中options对象保存了所传递进来的参数值。

  • 第六、七行,通过options.filename和options.address的方式调用参数值。

(2)接下来,再添加 help功能,为我们设置的选项提供说明,修改代码如下:

在这里插入图片描述

  • 增加帮助信息,%prog表示当前脚本文件的名字
  • 第三行,新增usage=usage -h就会显示help信息

尝试使用-h功能:

在这里插入图片描述

好了,接下来将以上构想放进我们的代码中,我们就可以使用选项,对指定文件或者是IP网段进行扫描了,代码说明如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

接下来对我们的脚本进行测试

(1)不传入任何参数,运行结果:

在这里插入图片描述

(2)传入错误的文件名

在这里插入图片描述

(3)-f 传入正确的文件,进行扫描

在这里插入图片描述

(4)-i 传入一个ip地址,对所在网段进行扫描,部分截图如下:

在这里插入图片描述

好啦,自此我们的代码就全部完成了,涉及了大量python基础知识,没看明白的小伙伴,可以针对不明白的函数在百度查询,可以轻松获取解答哦。

也可以在公众号给我留言,我看到会直接回复的~~

最后附上完整代码:

#!/usr/bin/python
#coding:utf8
import os
import sys
import socket
from threading import Thread
from optparse import OptionParser

def connect(host,port):       #connect函数,用于连接目标IP进程,获取banner
    socket.setdefaulttimeout(2)
    s = socket.socket()
    try:
        s.connect((host, port))
        ans = s.recv(1024)
        s.close()
        print ans,
        return ans
    except:
        pass

def check(host,port):     #判断是否为漏洞版本
    banner = connect(host, port)    #将host和port传入connect函数,并接收banner信息
    if banner:   #返回banner信息,则判断是否为漏洞版本
        print host
        if "3.0.2" in banner:
            print "this host is vulnerable."
        else:
            print 'unvulnerable.'
    else:         #没返回banner,则提示连接失败
        host= host+" connect faild! \n"
        print host

def main():
    usage = "Usage: %prgo -f <filename> -i <ip address>"    #配置选项功能
    parser =OptionParser(usage=usage)
    parser.add_option("-f",'--file',type='string',dest='filename',help='specify the Ip address file ')
    parser.add_option("-i",'--ip', type='string', dest='address', help='specify the Ip address')
    (options,args)=parser.parse_args()

    filename = options.filename    #接收-f选项传入的文件
    address = options.address      #接收-i选项指定的ip地址

    if (filename==None and address==None):      #判断是否至少传入一种参数
        print "please enter an Ip address file OR an Ip address"
        sys.exit()  #既没有传入文件,也没有传入地址则报错,退出程序

    if filename:
        if not os.path.exists(filename):   #如果传入文件,检查文件是否存在
            print "the file is not exist"
            sys.exit()          #文件不存在,则报错直接退出
        else:
            f = open(filename, 'r')             #文件存在,则开始读取文件中的ip地址进行扫描
            for i in f.readlines():
                host = i.strip("\n")
                port = 21
                t = Thread(target=check, args=(host, port))  #多线程扫描
                t.start()
            f.close()

    if address:                                 #如果传入IP地址,则通过下面的语句提取网络号
        prefix=address.split(".")[0]+"."+address.split(".")[1]+"."+address.split(".")[2]+"."
        for i in range(1,255):
            host= prefix+str(i)                 #拼接该网段所有的ip地址
            port = 21
            t = Thread(target=check, args=(host, port))     #使用多线程进行扫描
            t.start()

if __name__ == '__main__':
    main()

欢迎关注我的公众号~

Peace !

在这里插入图片描述

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值