CISCN-2021-wp

本文最后更新于:2021年5月30日 晚上

glass

so文件主要逻辑。

先dump数据,

image-20210515130254705

然后写脚本恢复rc4加密后的结果,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = [0xa3,0x1a,0xe3,0x69,0x2f,0xbb,0x1a,0x84,0x65,0xc2,0xad,0xad,0x9e,0x96,0x05,0x02,0x1f,0x8e,0x36,0x4f,0xe1,0xeb,0xaf,0xf0,0xea,0xc4,0xa8,0x2d,0x42,0xc7,0x6e,0x3f,0xb0,0xd3,0xcc,0x78,0xf9,0x98,0x3f]
s = '12345678'
for i in range(0, len(a)):
a[i] ^= ord(s[i%8])
print(a)
aa = a
for i in range(0, len(aa), 3):
a2 = aa[i+1]^aa[i]
a3 = a2^aa[i+2]
a1 = aa[i]^a3
aa[i] = a1
aa[i+1] = a2
aa[i+2] = a3
result = ""
for i in aa:
result += hex(i)[2:].rjust(2,'0')
print(result)

最后rc4解密。

image-20210515130345747

得到flag:CISCN{6654d84617f627c88846c172e0f4d46c}

BABY_bc

LLVM 恢复程序。

image-20210515201706133

image-20210515201439526

fill_number,校验两个为0的位数。

docheck 校验行和列,,没看公告,,跑出来两个结果,,,麻了。
image-20210515205922568

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
s = []
for i1 in range(0,6):
if i1 == 3:
continue
for i2 in range(0,6):
if i2 == i1 or i2 == 0:
continue
for i3 in range(0,6):
if i3 == i1 or i3 == i2 or i3 == 4:
continue
for i4 in range(0,6):
if i4 == i1 or i4 == i2 or i4 == i3 or i4 == 0 or i4 == 3:
continue
for i5 in range(0,6):
if i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4 or i4 <= i5 or i5 == 0:
continue
else:
a = []
a.append(i1)
a.append(i2)
a.append(i3)
a.append(i4)
a.append(i5)
s.append(a)
print(s)
print(len(s))
ss = []
for i1 in range(1,6):
for i2 in range(1,6):
if i2 == i1 or i2 >= i1 or i2 == 5:
continue
for i3 in range(1,6):
if i3 == i1 or i3 == i2 or i3 == 4:
continue
for i4 in range(1,6):
if i4 == i1 or i4 == i2 or i4 == i3 or i4 == 3:
continue
for i5 in range(1,6):
if i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4:
continue
else:
a = []
a.append(i1)
a.append(i2)
a.append(i3)
a.append(i4)
a.append(i5)
ss.append(a)
print(ss)
print(len(ss))
sss = []
for i1 in range(1,6):
for i2 in range(1,6):
if i2 == i1 or i1 >= i2:
continue
for i3 in range(1,6):
if i3 == i1 or i3 == i2 or i3 != 4:
continue
for i4 in range(1,6):
if i4 == i1 or i4 == i2 or i4 == i3 or i4 >= 3 or i4 == 3:
continue
for i5 in range(1,6):
if i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4 or i5 >= i4:
continue
else:
a = []
a.append(i1)
a.append(i2)
a.append(i3)
a.append(i4)
a.append(i5)
sss.append(a)
print(sss)
print(len(sss))
ssss = []
for i1 in range(1,6):
for i2 in range(1,6):
if i2 == i1:
continue
for i3 in range(1,6):
if i3 == i1 or i3 == i2 or i3 == 4:
continue
for i4 in range(1,6):
if i4 == i1 or i4 == i2 or i4 == i3 or i4 != 3 or i4 == 2:
continue
for i5 in range(1,6):
if i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4:
continue
else:
a = []
a.append(i1)
a.append(i2)
a.append(i3)
a.append(i4)
a.append(i5)
ssss.append(a)
print(ssss)
print(len(ssss))
sssss = []
for i1 in range(1,6):
for i2 in range(1,6):
if i2 == i1 or i2 >= i1:
continue
for i3 in range(1,6):
if i3 == i1 or i3 == i2 or i3 == 4:
continue
for i4 in range(1,6):
if i4 == i1 or i4 == i2 or i4 == i3 or i3 <= i4 or i4 == 3:
continue
for i5 in range(1,6):
if i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4 or i5 == 1:
continue
else:
a = []
a.append(i1)
a.append(i2)
a.append(i3)
a.append(i4)
a.append(i5)
sssss.append(a)
print(sssss)
print(len(sssss))
count = 0
for i1 in s:
for i2 in ss:
if i1[2] <= i2[2] or i1[4] <= i2[4]:
continue
c = 0
for i in range(5):
if i2[i] == i1[i]:
c = 1
if c == 1:
continue
for i3 in sss:
c = 0
for i in range(5):
if i3[i] == i1[i] or i3[i] == i2[i]:
c = 1
if c == 1:
continue
for i4 in ssss:
c = 0
for i in range(5):
if i4[i] == i1[i] or i4[i] == i2[i] or i4[i] == i3[i]:
c = 1
if c == 1:
continue
for i5 in sssss:
if i4[1] >= i5[1] or i4[4] >= i5[4]:
continue
c = 0
for i in range(5):
if i5[i] == i1[i] or i5[i] == i2[i] or i5[i] == i3[i] or i5[i] == i4[i]:
c = 1
if c == 1:
continue
count += 1
print('-----------------')
print(i1)
print(i2)
print(i3)
print(i4)
print(i5)
print(count)

image-20210515201556206

image-20210515201602525

image-20210515201614530

GIFT

比赛时没做出来,参考大佬博客学习一下。

不用费劲恢复符号表了,使用IDA7.6即可,哭了。

关键代码:

image-20210525184017527

怎么判断V8呢?

image-20210525184205756

对应的汇编:

image-20210525184500650

进入main_goooo分析:

image-20210525184533241

发现 返回时有两种情况,arg_18处给0或者1,当上边两个值为0时,会返回1。也就是v8为1。

这个地方分析是, (cs:qword_2820E8+1)% 17

image-20210525184053283

python还原关键代码:

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
tab1 = [0x0000000000000001, 0x0000000000000003, 0x0000000000000006, 0x0000000000000009, 0x000000000000000A, 0x000000000000000B, 0x000000000000000C, 0x000000000000000D, 0x000000000000000E, 0x000000000000000F, 0x0000000000000010, 0x0000000000000011, 0x0000000000000012, 0x0000000000000014, 0x0000000000000019, 0x000000000000001E, 0x0000000000000028, 0x0000000000000042, 0x0000000000000066, 0x00000000000000A0, 0x0000000000000936, 0x0000000000003D21, 0x00000000000149A7, 0x00000000000243AC, 0x00000000000CB5BE, 0x000000000047DC61, 0x00000000016C0F46, 0x000000000262C432, 0x0000000004ACE299, 0x0000000010FBC92A, 0x00000000329ECDFD, 0x00000000370D7470]

def main_goooo(data):
v4 = [0] * 5
for i in range(len(data)):
v3 = data[i]
v4[v3] ^= 1
return v4[1] == 0 and v4[3] == 0

def main_wtf(a1, a2, a3, a4):
global num
a3[a1] = a2
if a1 == a4 - 1:
if main_goooo(a3):
num = (num + 1) % 17
else:
for i in range(1, 5):
main_wtf(a1+1, i, a3, a4)
def main(N):
global num
num = 0
data = [0] * N
for i in range(1, 5):
main_wtf(0, i, data, N)
print(num)
# 从1开始跑
#flag_i = [main(i) for i in range(1, 16)]

# 1 2 3 4 5 6 7 8
# 2 6 3 4 0 2 12 5 2 6 3 4 0
# 发现8个一组
ss = [2, 6, 3, 4, 0, 2, 12, 5]
ss_result = []
for i in range(0x20):
idx = tab1[i]
ss_result.append(ss[((idx-1) % 8)])
print(ss_result)
s1 = [0x54, 0x5e, 0x52, 0x04, 0x55, 0x05, 0x53, 0x5f, 0x50, 0x07, 0x54, 0x56, 0x51, 0x02, 0x03, 0x57]
result2 = ""
for i in range(0x20):
result2 += chr(s1[ss_result[i]] ^ 0x66)
print(result2)

大佬们都发现了运算规律,我属实脑子不够用,但是发现了8个为一组的规律。

CISCN{4b445b3247c45344c54c44734445452c}

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

#低解密指数攻击
c1 = 19105765285510667553313898813498220212421177527647187802549913914263968945493144633390670605116251064550364704789358830072133349108808799075021540479815182657667763617178044110939458834654922540704196330451979349353031578518479199454480458137984734402248011464467312753683234543319955893
e1 = 3
N1 = 123814470394550598363280518848914546938137731026777975885846733672494493975703069760053867471836249473290828799962586855892685902902050630018312939010564945676699712246249820341712155938398068732866646422826619477180434858148938235662092482058999079105450136181685141895955574548671667320167741641072330259009
i = 0
while 1:
if gmpy2.iroot(c1+i*N1, 3)[1] == 1:
print(hex(gmpy2.iroot(c1+i*N1, 3)[0]))
break
i += 1

c21 = 54995751387258798791895413216172284653407054079765769704170763023830130981480272943338445245689293729308200574217959018462512790523622252479258419498858307898118907076773470253533344877959508766285730509067829684427375759345623701605997067135659404296663877453758701010726561824951602615501078818914410959610
c22 = 91290935267458356541959327381220067466104890455391103989639822855753797805354139741959957951983943146108552762756444475545250343766798220348240377590112854890482375744876016191773471853704014735936608436210153669829454288199838827646402742554134017280213707222338496271289894681312606239512924842845268366950
e21 = 17
e22 = 65537
N2 = 111381961169589927896512557754289420474877632607334685306667977794938824018345795836303161492076539375959731633270626091498843936401996648820451019811592594528673182109109991384472979198906744569181673282663323892346854520052840694924830064546269187849702880332522636682366270177489467478933966884097824069977

#共模攻击
def gongmogongji(n, c1, c2, e1, e2):
def egcd(a, b):
if b == 0:
return a, 0
else:
x, y = egcd(b, a % b)
return y, x - (a // b) * y
s = egcd(e1, e2)
s1 = s[0]
s2 = s[1]

# 求模反元素
if s1 < 0:
s1 = - s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = gmpy2.invert(c2, n)
m = pow(c1, s1, n) * pow(c2, s2, n) % n
return m
print(hex(gongmogongji(N2, c21, c22, e21, e22)))

#已知p高位
c3 = 59213696442373765895948702611659756779813897653022080905635545636905434038306468935283962686059037461940227618715695875589055593696352594630107082714757036815875497138523738695066811985036315624927897081153190329636864005133757096991035607918106529151451834369442313673849563635248465014289409374291381429646
e3 = 65537
N3 = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147

'''
n=113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
p=7117286695925472918001071846973900342640107770214858928188419765628151478620236042882657992902

pbits = 512
kbits = pbits-p.nbits()
p=p<<kbits
print("upper %d bits (of %d bits) is given" % (pbits-kbits, pbits))
PR.<x> = PolynomialRing(Zmod(n))
f = x + p
x0 = f.small_roots(X=2^kbits, beta=0.4)[0] # find root < 2^kbits with factor >= n^0.4
print(p+int(x0))
'''
p = 11437038763581010263116493983733546014403343859218003707512796706928880848035239990740428334091106443982769386517753703890002478698418549777553268906496423
q = N3 // p
n = (p-1) * (q-1)
d = gmpy2.invert(e3, n)
m = pow(c3,d,N3)
print(hex(m))

image-20210516020425188

image-20210516020227872

CISCN{3943e8843a19149497956901e5d98639}


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!