对目录穿越的一次小研究

最近重新刷一遍 BUU,也是做了第一道热身题嗷 —— 2018 HCTF 的 WarmUp,算是把目录穿越给整了个明白,心情很舒畅 👍

实验环境:Windows 下 phpstudy

实验目录树:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
D:.
| secret.txt
|
└─ │ flag.php
│ index.php

├─.idea
│ first.iml
│ misc.xml
│ modules.xml
│ workspace.xml

├─css
│ login-.css
│ register.css
│ such.css

├─file
│ flag.txt

└─js
│ next.js

└─layer

我们的关键在于 index.php、flag.php、file 文件夹下的 flag.txt 以及根目录下的 secret.txt

让我们看下其中的内容:

index.php:

1
2
3
4
<?php
if(isset($_GET['file'])) {
include("file/" . $_GET['file']);
}

flag.php:

1
flag{I_love_YJ}

file / flag.txt:

1
flag{you_are_so_foolish}

.. / secret.txt:

1
I love YJ, but it isn't a secret

可以看到 index.php 是接受一个名为 file 的 GET 参数并用 include 包含 file 文件夹下的名为 file 的文件,这里由于没有过滤 .. 这一类的字符导致我们可以利用以实现目录穿越

当我们传入 flag.txt 的时候没啥问题:

然后我们尝试输入 ../flag.php 以读取 file 文件夹的上层目录中的文件:

发现成功读取,我们可以再深一步,读取根目录下的 secret:

这些是目录穿越的前提,我们的 ../ 这些跳目录的字符不能被过滤,这个时候发现了一个很骚的操作,就比如 a/../flag.txt 这个名为 a 文件或者文件夹并不存在,那么它会与后面的 ../ 相抵消掉,最后读取 file 文件夹下的 flag.txt:

我们可以解释为:如果读取的文件或者文件夹并不存在,则会将其暂时解释为一个文件夹(虽然它),然后继续看后面的路径,然后 ../ 使得路径从这个文件夹中退出,所以就不会报错

然而,如果我们输入的文件存在,那么就会报错:

然后我们在文件名后面再加个 1,就不报错了,并且读出了文件,进一步证明了我们的解释:

同时,如果我们在其中输入特殊字符,像 ? \ * 这一类的,也会直接报错,因为文件中不允许有这类特殊字符:

再提一嘴,Linux 中允许 ? 在路径中存在,Windows 和 Linux 的这个细节区别一定要注意

差不多就这么多了,继续努力,啊哈哈哈

From:堆堆
记得注明出处嗷


评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×