浙江省省赛2024决赛wp

Re

Re2

upx魔改

然后直接base64变表

Re1

Rc4得到真正的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
def rc4(data, key):
S = list(range(256))
j = 0
out = []

for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]

i = j = 0
for char in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
out.append(char ^ S[(S[i] + S[j]) % 256])

return out


data = b'ban_debug!'
key = b'keykey'
decrypted = rc4(data, key)
print(decrypted)

#[105, 13, 90, 178, 64, 234, 25, 63, 47, 106]

crypto2魔改rc4

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
def rc4(data, key):
S = list(range(256))
j = 0
out = []

for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]

i = j = 0
for char in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
char+=S[(S[i] + S[j]) % 256]
char%=256
out.append(char)

return bytes(out)


data = bytes([ 0x4E, 0x47, 0x38, 0x47, 0x62, 0x0A, 0x79, 0x6A, 0x03, 0x66,
0xC0, 0x69, 0x8D, 0x1C, 0x84, 0x0F, 0x54, 0x4A, 0x3B, 0x08,
0xE3, 0x30, 0x4F, 0xB9, 0x6C, 0xAB, 0x36, 0x24, 0x52, 0x81,
0xCF])
key = bytes([105, 13, 90, 178, 64, 234, 25, 63, 47, 106])
decrypted = rc4(data, key)
print(decrypted)

#b'flag{1237-12938-9372-1923-4u92}'

Re3-3

题目提示debug,一开始tls得到1.exe

v4像key,后面是分组加密

一眼aes

看上去像s盒

但是怎么解密都不对,回去看re3.exe

得到标准aes的s盒

还是不对,看师傅用frida尝试去hook,因为不会被反调试检测

frida -l .\hook.js -n 1.exe

Crypto

Mycode

加解密脚本都写好了,直接fromhex然后爆破即可

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
import numpy as np

def substitute(state, sub_box):
return [sub_box[b & 0xF] | (sub_box[(b >> 4) & 0xF] << 4) for b in state]

def generate_round_keys(base_key, rounds):
round_keys = []
temp_key = base_key
for _ in range(rounds):
round_keys.append(temp_key & 0xFFFFFFFF)
temp_key ^= ((temp_key << 1) & 0xFFFFFFFF) | ((temp_key >> 31) & 0x1)
return round_keys

def process_state(base_key, state, rounds, encrypt):
sub_box = [0x9, 0x4, 0xA, 0xB, 0xD, 0x1, 0x8, 0x5, 0x6, 0x2, 0x0, 0x3, 0xC, 0xE, 0xF, 0x7]
inv_sub_box = [0xA, 0x5, 0x9, 0xB, 0x1, 0x7, 0x8, 0xF, 0x6, 0x0, 0x2, 0x3, 0xC, 0x4, 0xD, 0xE]

round_keys = generate_round_keys(base_key, rounds)

if encrypt:
for round in range(rounds):
state = substitute(state, sub_box)
state = [s ^ ((round_keys[round] >> (i * 8)) & 0xFF) for i, s in enumerate(state)]
else:
for round in range(rounds - 1, -1, -1):
state = [s ^ ((round_keys[round] >> (i * 8)) & 0xFF) for i, s in enumerate(state)]
state = substitute(state, inv_sub_box)

return state

def encrypt(plaintext, key, rounds=10):
length = len(plaintext)
padded_length = length if length % 4 == 0 else length + (4 - (length % 4))
plaintext += b'\x00' * (padded_length - length)

ciphertext = bytearray(padded_length)
for i in range(0, padded_length, 4):
state = list(plaintext[i:i+4])
state = process_state(key, state, rounds, True)
ciphertext[i:i+4] = state

return ciphertext

def decrypt(ciphertext, key, rounds=10):
length = len(ciphertext)
plaintext = bytearray(length)
for i in range(0, length, 4):
state = list(ciphertext[i:i+4])
state = process_state(key, state, rounds, False)
plaintext[i:i+4] = state

return plaintext.rstrip(b'\x00')

# def main():
# plaintext = b"DASCTF{******}"
# key = 0xECB... # 4 bytes
# ciphertext = encrypt(plaintext, key)
# print("Ciphertext:", ''.join(f"{b:02X}" for b in ciphertext))


Ciphertext='A6B343D2C6BE1B268C3EA4744E3AA9914E29A0789F299022820299248C23D678442A902B4C24A8784A3EA401'
Ciphertext=bytes.fromhex(Ciphertext)
print(Ciphertext)
for key in range(0xECB00000,0xECBFFFFF):
out=decrypt(Ciphertext,key)
if b'DASCTF' in out:
print(key)
print(out)

#DASCTF{6ef4d8e1-845a-4e3c-a4e1-a15e5530a0f4}

DlcgH-1

看到题目的时候确实慌了,k和t都是512位,爆破不现实,又想到DH算法本身并不会,所以也没做过多尝试就返回去看re了

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

flag = b'DASCTF{******}'
def iterate_function(seed, coeff_a, coeff_b, prime_modulus):
return (coeff_a * seed + coeff_b) % prime_modulus

def iterate_multiple_times(seed, num_iterations, coeff_a, coeff_b, prime_modulus):
for _ in range(num_iterations):
seed = iterate_function(seed, coeff_a, coeff_b, prime_modulus)
return seed

p = getPrime(600)
a = getPrime(512)
b = getPrime(512)
s = getPrime(512)
k = getPrime(512)
t = getPrime(512)

A = iterate_multiple_times(s, k, a, b, p)
B = iterate_multiple_times(s, t, a, b, p)

print("p =", p)
print("a =", a)
print("b =", b)
print("s =", s)
print("A =", A)
print("B =", B)

secret1 = iterate_multiple_times(A, k, a, b, p)
secret2 = iterate_multiple_times(B, t, a, b, p)

assert secret1 == secret2
'''
p = 2565258348684709722726260231955260453241716968378483821594041597297293609376806025180965681289016169408781752953380586044352169083397987333072306444539318806255242559916564022662479
a = 7703427441632069990122897903141278700284019287330080801753208940444135129072547305259960648105321270085533531118395452229965873504176368162947864923497711
b = 8477265953761650860710068507342719089504862957398782381045770264963932696457722724393775545810962476516315838411812248360284564925846788951219272632661157
s = 9228773209718156231041982890745928246648483643042884535935071957475932603607283209094294685862893340598940862096657878372229519375655468524041406914666867
A = 434251860827782638796736001849473241231781620594954088572922898040098881748337513244415553659525671751903798527967205418513869125476445927127124010452649344318178999731385274553080
B = 434251860827782638796736001849473241231781620594954088572922898040098881748337513244415553659525671751903798527967205418513869125476445927127124010452649344318178999731385274553080
'''

p2 = next_prime(secret1)
q2 = getPrime(600)
n2 = p2*q2
e = 4
m = bytes_to_long(flag)
c = pow(m, e, n2)
print("n2 =", n2)
print("c =", c)

'''
n2 = 3241139665583501598296135149075754735041636843305130049654913708275571916563715101898946962033698805416493133339619007016676895968314902474922279948997540924678346952667095320094789476561995339618782687993966133770687551933070478999383821269223854568552819152909266096733330218505088222661907600152055916956562332379930822529724151378274932991887183193175206749
c = 1131281812215293796960536920068009435705926803182047772347743960804329656316689664084120353862091370978145286943689311985878028828902275260824388998300548644880722651153603738691769179255824425771260974588160589473958033612303767050773921373389315920529311000160530833707622310013322631917184737227893101365726934901652170763292132835433158093074003616578836411
'''

赛后看到wp发现可以爆破k,怎么想都不现实,但是别人能出就该想想原本不现实的方法,算出p和q,后来想想%p其实可以循环

发现e和phi不互素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p=1472490340321845700492870656866629756386520746748019952980831685935628618084832981576756885932019702470337632472478610542460495595381421112792242654382213433012352298291319463142659# n = 3241139665583501598296135149075754735041636843305130049654913708275571916563715101898946962033698805416493133339619007016676895968314902474922279948997540924678346952667095320094789476561995339618782687993966133770687551933070478999383821269223854568552819152909266096733330218505088222661907600152055916956562332379930822529724151378274932991887183193175206749
c = 1131281812215293796960536920068009435705926803182047772347743960804329656316689664084120353862091370978145286943689311985878028828902275260824388998300548644880722651153603738691769179255824425771260974588160589473958033612303767050773921373389315920529311000160530833707622310013322631917184737227893101365726934901652170763292132835433158093074003616578836411
e = 4
q=2201127964530536768531437690590447485511044947862563552674657770394302822371223893779621142446998848918986248500749184930380894798831854267120305815092270548187578354416455278612511
R.<x> = PolynomialRing(GF(p))
f1 = x^4 - c
res1 = f1.roots()
R.<x> = PolynomialRing(GF(q))
f2 = x^4 - c
res2 = f2.roots()

for i in res1:
for j in res2:
m = crt([int(i[0]),int(j[0])],[p,q])
print(long_to_bytes(m))

当然发现p和q都%4=3,也就是用rabin解密

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

p = 2565258348684709722726260231955260453241716968378483821594041597297293609376806025180965681289016169408781752953380586044352169083397987333072306444539318806255242559916564022662479
a = 7703427441632069990122897903141278700284019287330080801753208940444135129072547305259960648105321270085533531118395452229965873504176368162947864923497711
b = 8477265953761650860710068507342719089504862957398782381045770264963932696457722724393775545810962476516315838411812248360284564925846788951219272632661157
s = 9228773209718156231041982890745928246648483643042884535935071957475932603607283209094294685862893340598940862096657878372229519375655468524041406914666867
A = 434251860827782638796736001849473241231781620594954088572922898040098881748337513244415553659525671751903798527967205418513869125476445927127124010452649344318178999731385274553080
B = 434251860827782638796736001849473241231781620594954088572922898040098881748337513244415553659525671751903798527967205418513869125476445927127124010452649344318178999731385274553080
n = 3241139665583501598296135149075754735041636843305130049654913708275571916563715101898946962033698805416493133339619007016676895968314902474922279948997540924678346952667095320094789476561995339618782687993966133770687551933070478999383821269223854568552819152909266096733330218505088222661907600152055916956562332379930822529724151378274932991887183193175206749
c = 1131281812215293796960536920068009435705926803182047772347743960804329656316689664084120353862091370978145286943689311985878028828902275260824388998300548644880722651153603738691769179255824425771260974588160589473958033612303767050773921373389315920529311000160530833707622310013322631917184737227893101365726934901652170763292132835433158093074003616578836411
e=4

seed=s
k=0
while seed!=A:
seed=(seed*a+b)%p
k+=1
print(k)

seed=A
for i in range(12345):
seed=(seed*a+b)%p
p=next_prime(seed)
print(p)
q=n//p
print(q)

inv_p = invert(p, q)
inv_q = invert(q, p)

cs = [c]
lge = math.log(e, 2)
for i in range(int(lge)):
ps = []
for c2 in cs:
r = pow(c2, (p + 1) // 4, p)
s = pow(c2, (q + 1) // 4, q)

x = (r * inv_q * q + s * inv_p * p) % n
y = (r * inv_q * q - s * inv_p * p) % n
if x not in ps:
ps.append(x)
if n - x not in ps:
ps.append(n - x)
if y not in ps:
ps.append(y)
if n - y not in ps:
ps.append(n - y)
cs = ps

for m in cs:
flag=long_to_bytes(m)
if b'DASCTF' in flag:
print(flag)

Misc

FinalSign

得到的字符串尝试转化成16进制,去异或DASCTF,看到hellow,猜测循环异或的字符串是helloworld,得到flag

1
2
3
4
5
6
7
8
9
10
11
12
s='2c243f2f3b3114345d0a0909333f06100143023b2c55020912'
print(len(s))
# for i in range(0,len(s),2):
# print(int(s[i:i+2],16),end=",")
a=[44,36,63,47,59,49,20,52,93,10,9,9,51,63,6,16,1,67,2,59,44,85,2,9,18]
print(len(a))
s1='helloworld'
for i in range(len(a)):
print(chr(a[i]^ord(s1[i%len(s1)])),end="")
#print(i)

#DASCTF{F1nal_Sign1n_D0ne}

实际上是snow无密钥解密得到异或的字符串helloworld

信创安全

easy_hpp-1

两次解压得到modules.abc

发现aes和base64,没发现密文,事后想到要搜索等号

看到zjuctf一眼原题但是没做过

也没有so文件,比赛的时候就卡住了

复现的时候找到几乎原题,就是加密有些不一样

Writeups - GoPoux 的笔记本

下载能反编译abc的jadx,找到真正的密文

Releases · ohos-decompiler/abc-decompiler

稍微修改一下decodeX的顺序就能得到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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np
from Crypto.Cipher import AES
import base64

def string_to_uint8_array(s):
return np.array([ord(c) for c in s], dtype=np.uint8)

def encodeX(arg0, arg1):
res = []
for i in range(16):
res.append(arg1[i])
for i in range(16):
res.append(arg0[i] ^ arg1[i])
return res

def encodeY(arg):
return base64.b64encode(bytes(arg)).decode()

def decodeY(arg):
return base64.b64decode(arg)

def decodeX(res):
arg1 = res[:16]
arg0 = res[16:]
for i in range(16):
arg0[i] ^= arg1[i]
return arg0, arg1

commonCipherKey = string_to_uint8_array("DASCTF2024-OHAPP").tobytes()

code = "/aPR+E8wS9+XbFMUfm8NacHpP190pf5xaR8+MIm/8gw="

tmp4 = code

tmp3 = decodeY(tmp4)
tmp3 = [c for c in tmp3]
# print(tmp3)

tmp1, tmp2 = decodeX(tmp3)
tmp1 = bytes(tmp1)
tmp2 = bytes(tmp2)


cipherY = AES.new(commonCipherKey, AES.MODE_CBC, iv=tmp1)
slice2 = cipherY.decrypt(tmp2)
# print(slice2)

cipherX = AES.new(commonCipherKey, AES.MODE_ECB)
slice1 = cipherX.decrypt(tmp1)
# print(slice1)

flag = slice1+ slice2
print(flag)

#b'DASCTF{Ea5Y_ohaPp_&_5iMPl3_fl4g}'

浙江省省赛2024决赛wp
https://j1ya-22.github.io/2024/11/12/浙江省省赛2024决赛wp/
作者
j1ya
发布于
2024年11月12日
许可协议