其他的没看,就看了misc的取证看了一天没做出来,看了wp发现思路是对的,但是没错,又是差那么一点点。。。

Writeup部分

Misc

VN_Lang

丢进IDA就能看到flag

image-20250208131104698

Crypto

easymath

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from Crypto.Util.number import *
from secret import flag
flag=bytes_to_long(flag)
l=flag.bit_length()//3 + 1
n=[]
N=1
while len(n) < 3:
p = 4*getPrime(l)-1
if isPrime(p):
n.append(p)
N *= p

print(f'c={flag*flag%N}')

from sympy import symbols, expand
x = symbols('x')
polynomial = expand((x - n[0]) * (x - n[1]) * (x - n[2]))

print(f'{polynomial=}')
# c=24884251313604275189259571459005374365204772270250725590014651519125317134307160341658199551661333326703566996431067426138627332156507267671028553934664652787411834581708944
# polynomial=x**3 - 15264966144147258587171776703005926730518438603688487721465*x**2 + 76513250180666948190254989703768338299723386154619468700730085586057638716434556720233473454400881002065319569292923*x - 125440939526343949494022113552414275560444252378483072729156599143746741258532431664938677330319449789665352104352620658550544887807433866999963624320909981994018431526620619

exp

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
from libnum import n2s
import gmpy2
n0, n1, n2 = var('n0 n1 n2')
equations = [
n0 + n1 + n2 == 15264966144147258587171776703005926730518438603688487721465,
n0*n1*n2 == 125440939526343949494022113552414275560444252378483072729156599143746741258532431664938677330319449789665352104352620658550544887807433866999963624320909981994018431526620619,
n0*n1 + n0*n2 + n1*n2 == 76513250180666948190254989703768338299723386154619468700730085586057638716434556720233473454400881002065319569292923
]
solutions = solve(equations, n0, n1, n2)

enc=24884251313604275189259571459005374365204772270250725590014651519125317134307160341658199551661333326703566996431067426138627332156507267671028553934664652787411834581708944
ls=[5487564316951417093934647798659941512646442958127439071827, 3868765709106144154703556118635822400623994075212553582411, 5908636118089697338533572785710162817248001570348495067227]
a,b,c=ls[0],ls[1],ls[2]
N=a*b*c
x=int(Mod(enc,a).sqrt())
y=int(Mod(enc,b).sqrt())
z=int(Mod(enc,c).sqrt())
print(n2s(int(crt([x,y,z],[a,b,c]))))
print(n2s(int(crt([x,-y,z],[a,b,c]))))
print(n2s(int(crt([x,y,-z],[a,b,c]))))
print(n2s(int(crt([-x,y,z],[a,b,c]))))
print(n2s(int(crt([-x,-y,z],[a,b,c]))))
print(n2s(int(crt([-x,y,-z],[a,b,c]))))
print(n2s(int(crt([x,-y,-z],[a,b,c]))))
print(n2s(int(crt([-x,-y,-z],[a,b,c]))))

image-20250208131326192

ss0Hurt!

题目

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
from Crypto.Util.number import *
from flag import flag

class DaMie:
def __init__(self, flag , n = None):
self.m = ZZ(bytes_to_long(flag))
self.n = n if n else getPrime(1024)
self.P = Zmod(self.n)
print(f'n = {self.n}')

def process(self, x, y, z):

return vector([5 * x + y - 5 * z, 5 * y - z, 5 * z])

def Mat(self, m):
PR = self.P['x,y,z']
x,y,z = PR.gens()

if m != 0:
plana = self.Mat(m//2)
planb = plana(*plana)
if m % 2 == 0:
return planb
else:
return self.process(*planb)
else:
return self.process(*PR.gens())

def hash(self, A, B, C):
return self.Mat(self.m)(A, B, C)

if __name__ == '__main__':

Ouch = DaMie(flag)
result = Ouch.hash(2025,208,209)
print(f'hash(A,B,C) = {result}')

丢给ai一把梭了

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

# 已知的n和result(示例值,需替换为实际数据)
n = 106743081253087007974132382690669187409167641660258665859915640694456867788135702053312073228376307091325146727550371538313884850638568106223326195447798997814912891375244381751926653858549419946547894675646011818800255999071070352934719005006228971056393128007601573916373180007524930454138943896336817929823
result = (17199707718762989481733793569240992776243099972784327196212023936622130204798694753865087501654381623876011128783229020278210160383185417670794284015692458326761011808048967854332413536183785458993128524881447529380387804712214305034841856237045463243243451585619997751904403447841431924053651568039257094910, 62503976674384744837417986781499538335164333679603320998241675970253762411134672614307594505442798271581593168080110727738181755339828909879977419645331630791420448736959554172731899301884779691119177400457640826361914359964889995618273843955820050051136401731342998940859792560938931787155426766034754760036, 93840121740656543170616546027906623588891573113673113077637257131079221429328035796416874995388795184080636312185908173422461254266536066991205933270191964776577196573147847000446118311985331680378772920169894541350064423243733498672684875039906829095473677927238488927923581806647297338935716890606987700071)

v1, v2, v3 = result

# 计算5^m mod n
inv_209 = inverse(209, n)
pow5m = (v3 * inv_209) % n

# 计算5的逆元
inv5 = inverse(5, n)

# 构建线性同余方程求解m
K = (pow5m * inv5 * 209) % n
D = (pow5m * 208 - v2) % n

try:
inv_K = inverse(K, n)
except ValueError:
print("K没有逆元,无法求解m")
exit()

m = (D * inv_K) % n

# 验证第三个方程以确保m正确
inv2 = inverse(2, n)

term1 = (pow5m * 2025) % n

term2 = (m * inv5 % n) * pow5m % n
term2 = (term2 * 208) % n

term3 = (-m * pow5m % n) * 209 % n

term4_part = (m * (m - 1) % n) * inv2 % n
term4 = term4_part * pow5m % n
term4 = term4 * (inv5 * inv5 % n) % n
term4 = (term4 * 209) % n
term4 = (-term4) % n

total = (term1 + term2 + term3 + term4) % n

if total != v1 % n:
print("计算出的m未通过v1验证,可能存在问题")
else:
flag = long_to_bytes(m)
print("解密得到的flag为:", flag)
#VNCTF{WWhy_diagonalization_1s_s0_brRRRrRrrRrrrRrRRrRRrrrRrRrRuUuUUUTTTtte3333?????ouch!ouch!Th3t_is_S0_Crazy!!!!}

复现部分

echo_flowers

imToken这个软件没有漏洞,因此是无法得知私钥的。在软件中可以看到账号是通过助记词导入的,因此猜测恢复助记词方法与输入法有关。

在android-7.1- r5/data/data/com.sohu.inputmethod.sogouoem/files/dict中找到词库

image-20250216165256719

词库中字符是以utf-16编码存储的,用strings解一下得到助记词

image-20250216170106186

正常进imToken导入一遍助记词即可创建钱包设置密码查看私钥

VNCTF{6433c196bb66b0d8ce3aa072d794822fd87edfbc3a30e2f2335a3fb437eb3cda}