template code for exp
Project description
Exploit Utils
本项目的目标是封装编写 exp 时的样板代码, 加快 exp 的开发
功能主要通过实战进行积累, 会选取比较常用到的
作者主要进行 web 漏洞复现与编写批量攻击脚本, 受作者工作习惯影响, 可能有些本应包含的功能没有被封装
另外, 本项目引入的库可能过时, 本着能用就行的原则, 本项目可能不会使用最新的技术
[!important]
该项目针对 python3.12+ 版本设计,所以使用了 3.12 版本才引入的特性
依赖该库的 exp 需要在 python3.12+ 下运行
安装
使用 pip 安装
pip install exploit_utils
功能介绍
本项目各种功能设计得很"散装", 目的是让使用者能负担较小地替换某些模块
| 文件 | 功能 |
|---|---|
| args.py | 命令行参数的相关功能 |
| crypto.py | md5/sha1/aes 等常见加密方式的加解密操作 |
| encode.py | base64/url/html 等常见编码的编解码操作 |
| fs.py | 封装了对于文件系统的操作 |
| http.py | 网络请求的相关功能 |
| log.py | 封装了日志相关的操作 |
| misc.py | 一些杂项 |
| mt.py | 封装了多线程有关的功能 |
| rand.py | 与"随机"相关的功能 |
| sh.py | 封装了执行系统命令相关的操作 |
接下来介绍几个我认为能够明显提升开发效率的功能
配置命令行参数
每次写脚本时都要写一堆类似的样板代码:
import argparse
parser = argparse.ArgumentParser()
# 几乎每个 exp 都会有的选项...
parser.add_argument("--url", "-u", help="目标 URL")
parser.add_argument("--file", "-f", help="从文件批量获取 URL")
parser.add_argument("--threads", "-t", type=int, default=5, help="线程数")
parser.add_argument("--output", "-o", help="输出文件")
parser.add_argument("--debug", action="store_true", help="开启 Debug 模式")
args = parser.parse_args()
现在你只需要:
# step1. 引入 exploit_utils
import exploit_utils as exp
# step2. 使用 args 模块获取 Parser
parser = exp.args.Parser()
# step3. 使用预设, 一键配置常用选项
parser.load_args(exp.args.BASIC_PRESET + [exp.args.DEBUG])
# step4. 对于预设以外的自定义选项, 用原有的方式添加即可
parser.add_argument("--foo", action="store_true", help="foo")
# step5. 解析时也是使用原有方式
args = parser.parse_args()
你可以对 args 模块提供的选项进行细节上的修改
import exploit_utils as exp
# 在预设的 --url 选项基础上添加 required=True 的属性, 以及修改 help 内容
url_option = exp.args.URL({"required": True, "help": "自定义的 url 选项"})
parser = exp.args.Parser()
parser.load_args([url_option])
创建多线程任务
经典多线程样板代码,从文件中读取 url 并创建 5 个线程进行攻击
import threading
import queue
task_queue: queue.Queue[str] = queue.Queue()
def attack(url: str) -> None:
...
def task() -> None:
while not task_queue.empty():
url = task_queue.get()
attak(url)
with open("urls.txt", "r", encoding="utf-8") as file:
for url in file.readlines()
task_queue.put(url.strip())
threads: list[threading.Thread] = []
for _ in range(5):
t = threading.Thread(task)
t.start()
threads.append(t)
for t in threads:
t.join()
python 提供了线程池,可以大大简化代码
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import wait
def attack(url: str) -> None:
...
with open("urls.txt", "r", encoding="utf-8") as file:
urls = [i.strip() for i in file.readlines()]
with ThreadPoolExecutor(max_worker=5) as pool:
wait([pool.submit(attack, url) for url in urls])
现在你只需要:
import exploit_utils as exp
def attack(url: str) -> None:
...
# 这条代码的作用见 "快速获取来自文件的输入"
urls: list[str] = exp.fs.parse_lines("urls.txt")
with exp.mt.ThreadPool(max_workers=5) as pool:
exp.mt.wait([pool.submit(task, url) for url in urls])
# 或者:
# exp.mt.handle_fs([pool.submit(task, url) for url in urls])
获取来自文件的输入
写 exp 时经常有很多 with open()... readlines() 等重复代码
with open("urls.txt", "r", encoding="utf-8") as file:
for url in file.readlines():
if url.strip():
task_queue.put(url.strip())
现在你可以使用下面的方式快速获得来自文件的输入
# step1. 引入 exploit_utils
import exploit_utils as exp
# step2. 直接使用封装好的函数
# 自动处理空行, 自动删除行尾换行符
for url in exp.fs.parse_lines("urls.txt"):
task_queue.put(url)
parse_lines 能使用用户提供的 callback 自动处理数据, 例如
def handler(data: str) -> str:
if data[-1] != "/":
data += "/"
return data
urls: list[str] = exp.fs.parse_lines("urls.txt", parser=handler)
几乎免配置的实时日志系统
对 logging 进行了封装,现在能像 loguru 那样几乎不需要配置
原本要实现一个同时将日志输出到控制台和文件的 logger 要写非常多的样板代码
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter("[%(levelname)s] %(message)s")
# 添加控制台输出
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# 添加文件输出
file_handler = logging.FileHandler("output.log")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
现在你只需要:
# step1. 引入 exploit_utils
import exploit_utils as exp
# step2. 通过 log 模块获取 logger
logger = exp.log.get_logger()
# step3. 使用 log 模块提供的方法一键添加输出文件
exp.log.add_outputfile("output.log")
# logger 自动拥有 ok 方法, 可以输出 SUCCESS 级别的日志
logger.ok("you did it!")
该日志系统是与 tqdm 兼容的, 无需额外代码即可与 tqdm 配合
import exploit_utils as exp
import tqdm
import time
logger = exp.log.get_logger()
for i in tqdm.tqdm(range(100)):
if i % 10 == 0:
logger.info(f"{i=}")
time.sleep(0.1)
自动获取常用 HTTP 配置支持
编写 exp 时经常需要使用随机 ua,也经常要对请求配置超时时间,以及忽略 SSL 证书
为了关闭警告我们还要引入 urllib3
于是一个简单的请求就变成了:
import requests
import urllib3
from fake_useragent import UserAgent
# 禁用警告
urllib3.disable_warnings(urllib3.exceptions.HTTPWarning)
ua = UserAgent()
http = requests.Session()
http.get(
url="http://example.com",
# 随机 UA
headers={"User-Agent": ua.random},
# 设置超时
timeout=5,
# 忽略 SSL 证书
verify=False,
)
现在你只需要:
# step1. 引入 exploit_utils
import exploit_utils as exp
# step2. 通过 http 模块获取 session
http = exp.http.get_session()
# step3. 直接使用 http 模块提供的方法一键关闭警告
exp.http.no_warn()
# step4. 使用 session 发起请求
# 该请求自动获得随机 UA、5s超时时间、忽略 SSL 证书
http.get("http://example.com")
生成随机字符串
编写 exp 时经常会遇到需要生成指定长度的随机字符串的情景,例如生成 session id
import random
import string
sessid = random.choices(string.ascii_letters, k=16)
现在你只需要:
import exploit_utils as exp
# 随机单词 (由大小写字母组成), 长度为 16
a = exp.rand.rand_word(16)
# 随机 16 进制数字, 长度为 10
b = exp.rand.rand_digits(10, base=16)
# 如果你想让长度也随机化, 使用一个元组指定长度的上下界
# 随机单词, 长度为 1~3
c = exp.rand.rand_word((1, 3))
集成 log 的文件服务器
部分漏洞利用需要配合远程服务器提供的恶意文件
如 XXE 漏洞的 dtd 文件, 又如 curl 反弹 shell 的 sh 文件
使用 fs 模块中的 FileServer 类可以快速启动一个文件服务器
import exploit_utils as exp
def attack(url: str) -> None:
...
# 在 0.0.0.0:5000 启动文件服务器
# 其根目录为脚本所在目录下的 files 文件夹
with exp.fs.FileServer("0.0.0.0", 5000, exp.fs.rget("files")):
attack("http://example.com")
该文件服务器会使用 log 模块打印日志
当日志级别为 INFO 时会输出启动和停止消息
当日志级别为 DEBUG 时会输出所有连接信息
其他
使用建议
-
将本项目的源码在
exploit_utils文件夹, 可以提供给 AI 助手以帮助其生成代码
如有必要, 可以将本项目的examples文件夹提供给 AI 助手以优化输出 -
虽然怎样组织代码是您的自由, 但我还是建议编写 exp 时尽量使用类型注解
免责声明
本工具仅限于合法授权的场景中使用, 使用者在借助本工具编写漏洞利用脚本时, 需严格遵守当地法律法规
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file exploit_utils-0.1.0.tar.gz.
File metadata
- Download URL: exploit_utils-0.1.0.tar.gz
- Upload date:
- Size: 19.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16c498b2903acafaa726c6dd3347247b6ce8865369364d14a10c33fae56de0ee
|
|
| MD5 |
70656459549a241d056f8f800ae0d694
|
|
| BLAKE2b-256 |
ed3ca9c02db6b0c327bde361fd2dcbdfd3de6b5d5a588df3fab0a926200674cb
|
File details
Details for the file exploit_utils-0.1.0-py3-none-any.whl.
File metadata
- Download URL: exploit_utils-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0daa4395a59f497912352933abef6e37dfd11361abf0ee4e875ea0cd40a16d0b
|
|
| MD5 |
aeafc42ea18b4eb8caf9b75df6bc8730
|
|
| BLAKE2b-256 |
9266b19da5f652cdf3bef8b1f0bacf7e3287942f174f8a64e96490164209e673
|