您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

如何编写Python漏洞验证脚本(单线程和多线程)

时间:2022-02-07 10:17:15  来源:  作者:老贤带你玩Python

我们实战经常会遇到以下几个问题:

1、遇到一个利用步骤十分繁琐的漏洞,中间错一步就无法利用

​ 2、挖到一个通用漏洞,想要批量刷洞小赚一波,但手动去测试每个网站工作量太大

这个时候编写一个poc脚本将会减轻我们很多工作。本文将以编写一个高效通用的poc脚本为目的,学习一些必要的Python/ target=_blank class=infotextkey>Python知识,这周也是拒绝做工具小子努力学习的一周

如何编写Python漏洞验证脚本(单线程和多线程)

 

 

 

requests模块使用技巧

Requests是Python中一个常用的HTTP请求库,使用Requests库来发起网络请求非常简单,具体的使用方法这里就不多介绍了,这里只提几个Requests模块的使用技巧,请收好

 

取消重定向

Requests 会自动处理所有重定向,但有时我们并不需要重定向,可以通过 allow_redirects 参数禁用重定向处理:

r = requests.get('http://github.com', allow_redirects=False)

 

SSL 证书验证

Requests在请求https网站默认会验证SSL证书,可有些网站并没有证书,可增加 verify=False 参数忽略证书验证,但此时可能会遇到烦人的 InsecureRequestWarning 警告消息。最终能没有警告消息也能访问无证书的https网站的方法如下:

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests.get('https://github.com', verify=False)

 

代理

使用代理的目的就不说了,使用方法如下:

# http代理,需要指定访问的http协议和https协议两种
proxies = {
  "http": "http://127.0.0.1:8080",
  "https": "http://127.0.0.1:1080",
}
# socks5代理
proxies = {
    'http': 'socks5://user:pass@host:port',
    'https': 'socks5://user:pass@host:port'
}
requests.get("http://example.org", proxies=proxies)

有个使用技巧就是代理到burp中,检查一下python发包。如我本地抓到requests请求包如下,可以发现特征十分明显,所以我们在实战使用时尽量修改User-Agent

如何编写Python漏洞验证脚本(单线程和多线程)

 

 

保持cookie

使用session会话对象,向同一主机发送多个请求,底层的 TCP 连接将会被重用,不仅能提性能还能保持cookie

s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")

在编写poc脚本时我们只需要利用Requests模块发送带有payload的数据即可,配合上这里的小技巧可能会有更好的体验

 

验证结果

发送带有payload的请求后,我们需要通过分析响应包判断是否存在漏洞。往往存在漏洞的响应包都有一些特殊值,我们只需要在响应包中找到这样的特殊值即可证明存在漏洞,所以这里我们通常有两种写法

如何编写Python漏洞验证脚本(单线程和多线程)

 

 

 

成员运算符 - in

if 'xxx' in r.text:
  	print('存在漏洞')
else:
  	print('不存在漏洞')

 

正则匹配 - re.search()

if re.search('xxx',r.text):
  	print('存在漏洞')
else:
  	print('不存在漏洞')

这两种写法差不多,不过re.search()有个好处是可以使用正则表达式,在漏洞特征是动态变化的情况时也能有效地捕捉

 

单线程poc脚本

此时我们已经能写一个单线程poc脚本了,我对单线程的poc脚本的要求十分简单,就是简单,在面对不同的漏洞时简单修改几行代码就可以了。这里提供一个我自己写的单线程poc脚本,大概意思就是这样

import requests
import re
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def Poc(url):
    proxy = {
            'http':'http://127.0.0.1:8080',
            'https':'http://127.0.0.1:8080'
    }
    headers = {
        'User-Agent':'Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
        'Connection':'close'
    }
    data = {'name':'xxxx','value':'xxxx'}
    try:
        response = requests.post(url=url,headers=headers,data=data,verify=False,proxies=proxy,timeout=10)
        if 'baidu' in response.text:
            print('存在漏洞')
        else:
            print('none')
    except Exception as e:
        print(f'请求失败:{e}')

if __name__ == '__main__':
    url = 'https://www.baidu.com'
    Poc(url)

 

使用多线程

当我们想批量验证数个网站是否存在漏洞时,就需要多线程来提升效率了。关于Python多线程的详细知识这里就不是这里的重点了。这里我们将利用Threading和queue做一个多线程poc脚本,我计划的流程如下

把所有目标url放到queue队列中;

启动多线程从queue队列中获取目标并执行;

保存执行结果。

具体代码最后会给出

 

颜色标记

我在使用多线程时就遇到一个问题,因为多线程处理的数据比较多,终端瞬间会输出大量信息,很容易就会忽略一些关键的信息

如何编写Python漏洞验证脚本(单线程和多线程)

 

然后我就想用颜色来区分不同的信息,在linux终端中使用 33[显示方式;前景色;背景色m 的格式就能输出各个颜色的字体。这里推荐python第三方库:colorama

colorama是一个可以跨多终端显示不同颜色字符与背景的第三方库,在linux终端上,使用ANSI转义字符来实现彩色字体的输出。在windows的终端上,通过包装stdout实现。在windows和linux上有不同的实现方案,从而达到跨平台的效果

安装第三方库的命令各位应该都会吧

pip install colorama

具体使用参考官方文档:
https://pypi.org/project/colorama/

我的使用习惯就是报错信息的字体使用红色,发现漏洞的字体使用绿色,此时部分代码如下:

from colorama import init,Fore
init(autoreset=True)
print(Fore.GREEN + '[+]存在漏洞')
print(Fore.RED + '[!]连接错误')

使用颜色后的终端输出如下,现在使用体验上明显会更好一点,大家也可以根据自己的喜好去设置

如何编写Python漏洞验证脚本(单线程和多线程)

 

添加进度条

我们使用多线程的目的就是为了更快地处理更多的url,但目标过多,我们还是免不了更长时间的等待。我们经常会把脚本挂在那里跑,然后呆呆的等着。然后我就想做一个进度条,根据进度条能大概地去预估时间,然后安排自己的工作,提升工作效率,这不就是使用脚本的意义吗

我首先就找到了很多人推荐的第三方库: tqdm ,在多线程中使用时可以使用手动更新进度

import time
from tqdm import tqdm

with tqdm(total=200) as pbar:
    pbar.set_description('Processing:')
    for i in range(20):
        time.sleep(0.1)
        pbar.update(10)

但我这里就遇到一个问题,很多人使用tqdm时只输出一个Progress bar任务条,但我们的需求是希望同时输出每次漏洞探测结果和任务条,这会导致这两者在终端中显示的混乱,如下图所示

如何编写Python漏洞验证脚本(单线程和多线程)

 

有没有一种办法能让任务条一直固定输出在终端的末尾呢,这样两个信息都能很清晰地显示

我找了好久解决方法,但官方似乎说没有找到在多个平台上平等使用tqdm的方法,就没有这个功能。

不过我最终找到官方提供了一个tqdm.write()方法,似乎能解决这个问题,只需要把脚本中所有print()方法换成tqdm.write()方法

如何编写Python漏洞验证脚本(单线程和多线程)

 

到这里我们就成功地拥有了一个进度条

 

多线程poc脚本

我最终写好的多线程poc脚本如下,中间还有很多可以优化的地方,希望能得到大家的指点

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import threading
import queue
from colorama import init,Fore
from tqdm import tqdm
init(autoreset=True)
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
global_file_target_url = 'url.txt'
global_file_result = 'right.txt'
global_threads_num = 12
global_q = queue.Queue()
global_list_result = []
# 目标uri
global_where = ''
# payload 成功时页面标志信息
global_payload = 'test'
global_request_proxy = {
            'http':'socks5://127.0.0.1:8080',
            'https':'socks5://127.0.0.1:8080'
}
global_request_headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
        'cookie':'xxxxxxxxxxxxxx',
        'Connection':'close'   #关闭多余的连接请求
}
global_request_data = {'name':'xxxx','value':'xxxx'}   #POST传递的数据
global_error = 0
def req(url):
    global global_error
    i = 0
    while i<3:
        if i>0:
            #print(f'[!]第{i}次重试请求{url}')
            tqdm.write(f'[!]第{i}次重试请求{url}')
        try:
            response = requests.get(url=url,headers=global_request_headers,verify=False,timeout=10)
            response.encoding = response.apparent_encoding
            text = response.text
            if global_payload in text:
                return True
            else:
                return False
        except Exception as e:
            if i==0:
                global_error +=1
            i = i+1
            #print(Fore.RED+f'[!]{url}请求失败')
            tqdm.write(Fore.RED+f'[!]{url}请求失败')
def poc(pbar):
    while not global_q.empty():
        target_url = global_q.get()
        url = target_url+global_where
        if req(url):
            #print(Fore.GREEN+'[+]存在漏洞:'+target_url)
            tqdm.write(Fore.GREEN+'[+]存在漏洞:'+target_url)
            global_list_result.append(target_url)
        else:
            #print('[-]未发现漏洞')
            tqdm.write('[-]未发现漏洞')
        pbar.update(1)
def main():
    # 1、添加目标url队列
    with open(global_file_target_url,'r') as f:
        urls = f.readlines()
    for url in urls:
        url = url.strip()
        global_q.put(url)
    num_url = global_q.qsize()
    pbar = tqdm(total=num_url)
    pbar.set_description('Processing:')
    tqdm.write('url总数:'+str(num_url))
    # 2、启动多线程poc验证
    threads = []
    for _ in range(global_threads_num):
       t = threading.Thread(target=poc,args=(pbar,))
       threads.append(t)
       t.start()
    for t in threads:
        t.join()
    # 3、保存结果到文件 global_file_result
    if global_list_result:
        file = open(global_file_result,'w')
        for res in global_list_result:
            file.write(res+"n")
        file.close()
    tqdm.write(f'失败请求数{global_error}')
if __name__ == '__main__':
    main()

原文链接:
https://www.tuicool.com/articles/Y3Mvuuz



Tags:Python   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1、让我们一起来看下吧,直接上图。 第一眼看到是不是觉得很高逼格,暗黑画风,这很大佬。其实它就是------AidLearning。一个运行在安卓平台的linux系统,而且还包含了许多非常强大...【详细内容】
2022-07-15  Tags: Python  点击:(2)  评论:(0)  加入收藏
真正的大师,永远都怀着一颗学徒的心! 一、项目简介 今天说的这个软件是一款基于Python+vue的自动化运维、完全开源的云管理平台。二、实现功能 基于RBAC权限系统 录像回放 ...【详细内容】
2022-07-14  Tags: Python  点击:(3)  评论:(0)  加入收藏
前言今天笔者想和大家来聊聊python接口自动化的MySQL数据连接,废话不多说咱们直接进入主题吧。 一、什么是 PyMySQL?PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库,P...【详细内容】
2022-07-11  Tags: Python  点击:(19)  评论:(0)  加入收藏
aiohttp什么是 aiohttp?一个异步的 HTTP 客户端\服务端框架,基于 asyncio 的异步模块。可用于实现异步爬虫,更快于 requests 的同步爬虫。安装pip install aiohttpaiohttp 和 r...【详细内容】
2022-07-11  Tags: Python  点击:(15)  评论:(0)  加入收藏
今天我们学习下 Queue 的进阶用法。生产者消费者模型在并发编程中,比如爬虫,有的线程负责爬取数据,有的线程负责对爬取到的数据做处理(清洗、分类和入库)。假如他们是直接交互的,...【详细内容】
2022-07-06  Tags: Python  点击:(34)  评论:(0)  加入收藏
继承:是面向对象编程最重要的特性之一,例如,我们每个人都从祖辈和父母那里继承了一些体貌特征,但每个人却又不同于父母,有自己独有的一些特性。在面向对象中被继承的类是父类或基...【详细内容】
2022-07-06  Tags: Python  点击:(25)  评论:(0)  加入收藏
点击上方头像关注我,每周上午 09:00准时推送,每月不定期赠送技术书籍。本文1553字,阅读约需4分钟 Hi,大家好,我是CoCo。在上一篇Python自动化测试系列文章:Python自动化测试之P...【详细内容】
2022-07-05  Tags: Python  点击:(27)  评论:(0)  加入收藏
第一种方式:res = requests.get(url, params=data, headers = headers)第二种方式:res = requests.get(url, data=data, headers = headers)注意:1.url格式入参只支持第一种方...【详细内容】
2022-07-05  Tags: Python  点击:(19)  评论:(0)  加入收藏
什么是python类的多态python的多态,可以为不同的类实例,或者说不同的数据处理方式,提供统一的接口。用比喻的方式理解python类的多态比如,同一个苹果(统一的接口)在孩子的眼里(类实...【详细内容】
2022-07-04  Tags: Python  点击:(28)  评论:(0)  加入收藏
假设某日我开了一家空调公司,暂且就叫他天强空调安装设备公司吧,假装自己有公司,接了一单大生意,就是给甘肃省的各个高校安装空调(其实这边的气候基本用不到空调,就是假想一下),那么...【详细内容】
2022-07-01  Tags: Python  点击:(33)  评论:(0)  加入收藏
▌简易百科推荐
近几年 Web3 被炒得火热,但是大部分人可能还不清楚什么是 Web3,今天就让w3cschool编程狮小师妹带你了解下 Web3 是什么?与我们熟知的 Web1 和 Web2 又有什么区别呢?web3.0什么是...【详细内容】
2022-07-15  编程狮W3Cschool    Tags:Web3.0   点击:(2)  评论:(0)  加入收藏
1、让我们一起来看下吧,直接上图。 第一眼看到是不是觉得很高逼格,暗黑画风,这很大佬。其实它就是------AidLearning。一个运行在安卓平台的linux系统,而且还包含了许多非常强大...【详细内容】
2022-07-15  IT智能化专栏    Tags:AidLearning   点击:(2)  评论:(0)  加入收藏
真正的大师,永远都怀着一颗学徒的心! 一、项目简介 今天说的这个软件是一款基于Python+vue的自动化运维、完全开源的云管理平台。二、实现功能 基于RBAC权限系统 录像回放 ...【详细内容】
2022-07-14  菜鸟程序猿    Tags:Python   点击:(3)  评论:(0)  加入收藏
前言今天笔者想和大家来聊聊python接口自动化的MySQL数据连接,废话不多说咱们直接进入主题吧。 一、什么是 PyMySQL?PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库,P...【详细内容】
2022-07-11  测试架构师百里    Tags:python   点击:(19)  评论:(0)  加入收藏
aiohttp什么是 aiohttp?一个异步的 HTTP 客户端\服务端框架,基于 asyncio 的异步模块。可用于实现异步爬虫,更快于 requests 的同步爬虫。安装pip install aiohttpaiohttp 和 r...【详细内容】
2022-07-11  VT漫步    Tags:aiohttp   点击:(15)  评论:(0)  加入收藏
今天我们学习下 Queue 的进阶用法。生产者消费者模型在并发编程中,比如爬虫,有的线程负责爬取数据,有的线程负责对爬取到的数据做处理(清洗、分类和入库)。假如他们是直接交互的,...【详细内容】
2022-07-06  VT漫步    Tags:Python Queue   点击:(34)  评论:(0)  加入收藏
继承:是面向对象编程最重要的特性之一,例如,我们每个人都从祖辈和父母那里继承了一些体貌特征,但每个人却又不同于父母,有自己独有的一些特性。在面向对象中被继承的类是父类或基...【详细内容】
2022-07-06  至尊小狸子    Tags:python   点击:(25)  评论:(0)  加入收藏
点击上方头像关注我,每周上午 09:00准时推送,每月不定期赠送技术书籍。本文1553字,阅读约需4分钟 Hi,大家好,我是CoCo。在上一篇Python自动化测试系列文章:Python自动化测试之P...【详细内容】
2022-07-05  CoCo的软件测试小栈    Tags:Python   点击:(27)  评论:(0)  加入收藏
第一种方式:res = requests.get(url, params=data, headers = headers)第二种方式:res = requests.get(url, data=data, headers = headers)注意:1.url格式入参只支持第一种方...【详细内容】
2022-07-05  独钓寒江雪之IT    Tags:Python request   点击:(19)  评论:(0)  加入收藏
什么是python类的多态python的多态,可以为不同的类实例,或者说不同的数据处理方式,提供统一的接口。用比喻的方式理解python类的多态比如,同一个苹果(统一的接口)在孩子的眼里(类实...【详细内容】
2022-07-04  写小说的程序员    Tags:python类   点击:(28)  评论:(0)  加入收藏
站内最新
站内热门
站内头条