Z1d10tのBlog

A note for myself,have fun!

  1. 1. 碎碎念:
  2. 2. 解题:

[HITCON 2017]SSRFme

碎碎念:

这是一道ssrf 也就是服务器端请求伪造的题目 发现这样的题目常常会有 $_SERVER数组的应用,还是蛮不错的qwq

解题:

进入题目给出源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
10.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];
}

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作用就是获取我们的ip

然后第二部分 根据我们的ip创建一个由md5加密的沙盒 然后选择它

第三部分 shell_exec 执行我们的 get到的 GET+url的命令

这里用到了linux中 GET命令

GET 这个命令的一个命令执行漏洞,主要是 perl 的一个特点,在 open 可以执行命令并且还支持file协议。

注意:file 协议利用 open 命令执行,要执行的命令先前必须要有以命令为文件名的文件存在

img

这里以命令为文件名的文件必须加上管道符| 否则不行,不太明白这里为什么不加就不行

pathinfo — 返回文件路径的信息

img

也就是创建一个我们传入filename的文件 然后选择它

file_put_contents — 将数据写入文件

这里也就是把$data的内容写入 我们的filename的文件中

构造payload:?url=file:ls /|&filename=ls /| 这里要执行两次才能成功 也就是提交两次 为什么要提交两次呢

因为前面说过 file 协议利用 open 命令执行,要执行的命令先前必须要有以命令为文件名的文件存在

然后这里为什么要加反斜杠呢 因为管道符需要我们去转义一下

因此第一次提交 是让去创建一个以命令为文件的文件 第二次才去执行并且将执行结果写入到文件中去

然后再根据我们的ip 去构造沙盒路径

img

构造payload访问:/sandbox/2eeed2f9aeae6311b507ada8fb98809e/ls \|

img

看到有个readflag 理论来说直接执行./readflag就可以了 但是这里不行 我们要通过构造一个以命令为文件名的文件然后去访问 如果这里构造:/readflag文件是执行不了的 因为这里必须是/readflag| 才能成功执行 但是readflag| 不是readflag文件就算执行了也没用

再说一句 一般见到readflag这样的文件名字 直接去执行 而不是去通过cat这样的命令去读 因为readflag里面是代码 直接./执行就行了

构造:?url=file:bash -c /readflag|&filename=bash -c /readflag| 也是和上面一样执行两次然后通过路径去访问就可以拿到flag了

这里用的bash -c 也就是将后面字符串当作命令读入执行 然后输出

img img

成功!

本文最后更新于 天前,文中所描述的信息可能已发生改变