香山杯2023初赛个人做题记录

签到

basecrack –magic一把梭,凯撒解码

URL从哪儿来

丢ida,发现在windows的temp文件夹中创建文件,提取ou_XXXX.tmp改为ou.exe,丢ida,找到szUrl为http://how.did.i.decrypted?id=,发现v3->base64->作为密钥rc4加密得url,但是动调发现密钥被篡改,怀疑原密钥为flag,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
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
import base64
v3=[0 for i in range(56)]
v3[0]=120
v3[1]=139
v3[2]=150
v3[3]=134
v3[4]=120
v3[5]=81
v3[6]=145
v3[7]=80
v3[8]=108
v3[9]=98
v3[10]=119
v3[11]=83
v3[12]=108
v3[13]=136
v3[14]=99
v3[15]=80
v3[16]=120
v3[17]=113
v3[18]=78
v3[19]=80
v3[20]=107
v3[21]=152
v3[22]=119
v3[23]=83
v3[24]=106
v3[25]=114
v3[26]=119
v3[27]=151
v3[28]=108
v3[29]=139
v3[30]=119
v3[31]=146
v3[32]=108
v3[33]=152
v3[34]=99
v3[35]=80
v3[36]=109
v3[37]=113
v3[38]=78
v3[39]=81
v3[40]=108
v3[41]=98
v3[42]=119
v3[43]=150
v3[44]=108
v3[45]=152
v3[46]=95
v3[47]=80
v3[48]=107
v3[49]=114
v3[50]=129
v3[51]=81
v3[52]=108
v3[53]=136
v3[54]=100
v3[55]=87
for i in range(56):
v3[i]-=30
ret=base64.b64encode(bytes(v3))
print(ret)

hello_py

把python捅到apk里去了…,发现引擎叫chaquopy,丢进jeb中把一堆.py和.pyc弄出来,有个hello.py很扎眼,发现是关键代码:转为小端序然后xxtea加密。
hello.py很丑,改变量名:

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
from java import jboolean ,jclass #line:1
import struct #line:3
import ctypes #line:4
def MX (v1 ,v2 ,v3 ,v4 ,v5 ,v6 ):#line:7
v7 =(v1 .value >>5 ^v2 .value <<2 )+(v2 .value >>3 ^v1 .value <<4 )#line:8
v8 =(v3 .value ^v2 .value )+(v4 [(v5 &3 )^v6 .value ]^v1 .value )#line:9
return ctypes .c_uint32 (v7 ^v8 )#line:11
def encrypt (len ,org ,key ):#line:14
delta =0x9e3779b9 #line:15
v13 =6 +52 //len #line:16
v14 =ctypes .c_uint32 (0 )#line:18
v15 =ctypes .c_uint32 (org [len -1 ])#line:19
v16 =ctypes .c_uint32 (0 )#line:20
while v13 >0 :#line:22
v14 .value +=delta #line:23
v16 .value =(v14 .value >>2 )&3 #line:24
for v17 in range (len -1 ):#line:25
v18 =ctypes .c_uint32 (org [v17 +1 ])#line:26
org [v17 ]=ctypes .c_uint32 (org [v17 ]+MX (v15 ,v18 ,v14 ,key ,v17 ,v16 ).value ).value #line:27
v15 .value =org [v17 ]#line:28
v18 =ctypes .c_uint32 (org [0 ])#line:29
org [len -1 ]=ctypes .c_uint32 (org [len -1 ]+MX (v15 ,v18 ,v14 ,key ,len -1 ,v16 ).value ).value #line:30
v15 .value =org [len -1 ]#line:31
v13 -=1 #line:32
return org #line:34

def check (input_str ):#line:63
print ("checking~~~: "+input_str )#line:64
input_str =str (input_str )#line:65
if len (input_str )!=36 :#line:66
return jboolean (False )#line:67
tmp1 =[]#line:69
for i in range (0 ,36 ,4 ):#line:70
encrypted =input_str [i :i +4 ].encode ('latin-1')#line:71
tmp1 .append (encrypted )#line:72
tmp2 =[]#line:73
for i in tmp1 :#line:74
tmp2 .append (struct .unpack ("<I",i )[0 ])#line:75
print (tmp2 )#line:77
encrypted =encrypt (9 ,tmp2 ,[12345678 ,12398712 ,91283904 ,12378192 ])#line:78
ans =[689085350 ,626885696 ,1894439255 ,1204672445 ,1869189675 ,475967424 ,1932042439 ,1280104741 ,2808893494 ]#line:85
for i in range (9 ):#line:86
if ans [i ]!=encrypted [i ]:#line:87
return jboolean (False )#line:88
return jboolean (True )#line:90
def sayHello ():#line:92
print ("hello from py")#line:93

故解密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
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
from ctypes import * 

def MX(z, y, sum1, k, p, e):
return c_uint32(((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))
def btea(v,k,n,delta):

if n>1:
sum1=c_uint32(0)
z=c_uint32(v[n-1])
rounds=6+52//n
e=c_uint32(0)

while rounds>0:
sum1.value+=delta
e.value=((sum1.value>>2)&3) #e都要32位哦
for p in range(n-1):
y=c_uint32(v[p+1])
#v[p]=c_uint32(v[p]+c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))).value).value
v[p] = c_uint32(v[p] + MX(z,y,sum1,k,p,e).value).value
z.value=v[p]

y=c_uint32(v[0])
#v[n-1]=c_uint32(v[n-1]+c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[((n-1)&3)^e.value]^z.value)))).value).value #这里tmd传入的是k[((n-1)&3)啊我草,找了半天!!!
v[n-1] = c_uint32(v[n-1] + MX(z,y,sum1,k,n-1,e).value).value
z.value=v[n-1]
rounds-=1

else:
sum1=c_uint32(0)
n=-n
rounds=6+52//n
sum1.value=rounds*delta
y=c_uint32(v[0])
e=c_uint32(0)

while rounds>0:
e.value=((sum1.value>>2)&3) #e都要32位哦
for p in range(n-1, 0, -1):
z=c_uint32(v[p-1])
#y[p]=c_uint32(v[p]-c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))).value).value
v[p] = c_uint32(v[p] - MX(z,y,sum1,k,p,e).value).value
y.value=v[p]

z=c_uint32(v[n-1])
#v[n-1]=c_uint32(v[n-1]-c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[((n-1)&3)^e.value]^z.value)))).value).value #这里tmd传入的是k[((n-1)&3)啊我草,找了半天!!!
v[0] = c_uint32(v[0] - MX(z,y,sum1,k,0,e).value).value
y.value=v[0]
sum1.value-=delta
rounds-=1

return v




if __name__=='__main__':
a=[689085350 ,626885696 ,1894439255 ,1204672445 ,1869189675 ,475967424 ,1932042439 ,1280104741 ,2808893494]
k=[12345678 ,12398712 ,91283904 ,12378192]
delta=0x9e3779b9
n=9
# print("加密前数据:",a)
# res=btea(a,k,n,delta)
# print("加密后数据:",res)
res=btea(a,k,-n,delta)
print("解密后数据:",res)

解码exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
import struct
enc=[946221411, 912614241, 878851117, 959720758, 1647128883, 761410866, 825241953, 959996208, 842610019]
for i in enc:
print(str(hex(i))[2:])
tmp1=[]
tmp2=[]
for i in range(len(enc)):
tmp1.append(struct.pack("<I",enc[i]))
print(str(bytes(enc[i]).decode('latin-1')),end='')
# print(str(tmp1[i]),end='')
print()
for i in range(len(tmp1)):
print(str(tmp1[i].decode('latin-1')),end='')