checkyourkey

主要代码逻辑保存在libCheckYourKey.so

1
2
if (MainActivity.ooxx(content)) {
new AlertDialog.Builder(MainActivity.context).setTitle("result").setMessage("Congratulations!").show();

image-20221215200343524

加密主要逻辑如下

image-20221215203744036

最后会和一段数据比较,但是数据存在异常,非正常base64加密数据。

image-20221215205307787

我们找到init_array,如下这段完成了对一大段数据的解密

image-20221215205214489

通过脚本还原数据得到如下,因为手机坏了这次没有动调emm,主要是利用数组指针,然后直接执行获得内容

image-20221215213059532

得到内容如下,猜测有检测frida

image-20221215212200376

解密得到aes后的数据

image-20221215212455206

然后aes解密

1
2
3
4
5
6
7
8
9
from Crypto.Cipher import AES

cipher = b'\x49\x67\xeb\x32\x9d\x05\x61\xda\xdb\x07\xd7\x5a\xb9\x01\xb2\x46'
key = b"goodlucksmartman"
aes = AES.new(key,AES.MODE_ECB)
output = aes.decrypt(cipher)
print(output)

# b'flag{rtyhgf!@#$}'

rttt

这里存在rc4特征

image-20221216095320284

rc4的秘钥通过异或生成,得到为Welc0me to RCTF 2O22

image-20221216104536008

然后rc4函数之后出现了一段大小为15的数组,解密出来为Congratulations

image-20221216104716196

解密rc4,很明显顺序不太对

1
2
3
4
5
6
from Crypto.Cipher import ARC4
rc4 = ARC4.new(b'Welc0me to RCTF 2O22')
t1 = [52, 194, 101, 45, 218, 198, 177, 173, 71, 186, 6, 169, 59, 193, 204, 215, 241, 41, 36, 57, 42, 192, 21, 2, 126, 16, 102, 123, 94, 234, 94, 208, 89, 70, 225, 214, 110, 94, 178, 70, 107, 49]
f = rc4.decrypt(bytes(t1)).decode()
print(f)
C7DD9165-R-72--}332DE0CBEF9C{1776T7DF3DCEF

回到xor的地方,构造密文得到置换表

获取输入–>置换–>rc4

1
2
s1 = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTY'
s2 = 'n0mWa8v4bq31zflYohd92yispr7wtTjQRe5Exuc6gk'

image-20221216121227719

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Cipher import ARC4
rc4 = ARC4.new(b'Welc0me to RCTF 2O22')

t1 = [52, 194, 101, 45, 218, 198, 177, 173, 71, 186, 6, 169, 59, 193, 204, 215, 241, 41, 36, 57, 42, 192, 21, 2, 126, 16, 102, 123, 94, 234, 94, 208, 89, 70, 225, 214, 110, 94, 178, 70, 107, 49]
f = rc4.decrypt(bytes(t1)).decode()


s1 = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTY'
s2 = 'n0mWa8v4bq31zflYohd92yispr7wtTjQRe5Exuc6gk'
dic = {}
for i in range(len(s2)):
dic[i] = s1.index(s2[i])

f1 = ['' for i in range(42)]
for i in range(len(f)):
f1[dic[i]] = f[i]
print(''.join(f1))

huowang

非预期的题,第一个迷宫走完然后爆破即可,这里就记一下学习笔记。

unicorn

  1. uc_open(uc_arch arch, uc_mode mode, uc_engine **result)

    UC_ARCH_X86, // X86 architecture (including x86 & x86-64)

    image-20221217223850704

    UC_MODE_64 = 1 << 3, // 64-bit mode

  2. uc_mem_map

  3. uc_mem_write

  4. uc_hook_add

  5. uc_emu_start

  6. uc_close

看似hook了一个奇怪的指令

image-20221217223456302

动态修改后,更改为了syscall,然后对syscall的调用进行处理

image-20221218115021662

设置硬件断点可以发现实在第二段模拟中修改了dword_18D73E0,

image-20221218120208753

从而修改if中的第二个值

image-20221218120329295

然后跳转到了

image-20221218120427849

观察syscall,每一轮syscall都会进行一轮异或,也就是smc自解密代码

image-20221218121528517

配合hook回调函数,可以看出第一个函数为uc_reg_read_batch函数,把7个寄存器的值读入到了qword中,然后在进行判断是sys_write还是sys_exit

image-20221218121204561

第一段代码模拟为0x145e0a9–>0x145E0FA

image-20221218122216722

第二段代码执行

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
.rodata:000000000145E0C2                 mov     r10d, 0
.rodata:000000000145E0C8 mov rbx, 400174h
.rodata:000000000145E0D2 mov rdi, 400174h
.rodata:000000000145E0DC mov rsi, offset loc_407B34
.rodata:000000000145E0E6 mov r10, offset qword_400170
.rodata:000000000145E0F0 mov r11, 400172h

.rodata:000000000145E010 lea rax, loc_4000D9
.rodata:000000000145E017 mov r8, [rbx]
.rodata:000000000145E01A xor [rax], r8
.rodata:000000000145E01D mov r8, [rbx+8]
.rodata:000000000145E021 xor [rax+8], r8
.rodata:000000000145E025 mov r8, [rbx+10h]
.rodata:000000000145E029 xor [rax+16], r8 R
.rodata:000000000145E02D mov r8, [rbx+18h]
.rodata:000000000145E031 xor [rax+24], r8
.rodata:000000000145E035 mov r8, [rbx+20h]
.rodata:000000000145E039 xor [rax+32], r8
.rodata:000000000145E03D mov r8, [rbx+28h]
.rodata:000000000145E041 xor [rax+40], r8
.rodata:000000000145E045 mov r8, [rbx+30h]
.rodata:000000000145E049 xor [rax+48], r8
.rodata:000000000145E04D mov r8, [rbx+38h]
.rodata:000000000145E051 xor [rax+56], r8
.rodata:000000000145E055 mov al, [rsi]
.rodata:000000000145E057 add rsi, 1
.rodata:000000000145E05B jmp short loc_4000D9

有一点点迹象,如下

image-20221218182849070

留坑:

这个师傅写了一个脚本,通过修改代码在迷宫上执行dfs,使用pwntools的disasm来获得新的xor-key。后续写好了会补上来

https://hackmd.io/@94y7q597ST2hNdB9lbTJhA/S1wJr4Bds#HuoWang

picstore

还原字节码

修改了字节码加载,修改lua-5.3.3的逻辑后即可获取到字节码

1
luadec -dis picStore.bin > out.txt

在load的时候修改了字节码,但是在dump的时候没有修改字节码

自编译luadec,可以得到结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
; Disassembled using luadec 2.2 rev: UNKNOWN for Lua 5.3 from https://github.com/viruscamp/luadec
; Command line: -dis picStore.bin

; Function: 0
; Defined at line: 0
; #Upvalues: 1
; #Parameters: 0
; Is_vararg: 2
; Max Stack Size: 2

0 [-]: CLOSURE R0 0 ; R0 := closure(Function #0_0)
1 [-]: SETTABUP U0 K0 R0 ; U0["menu"] := R0
2 [-]: CLOSURE R0 1 ; R0 := closure(Function #0_1)
3 [-]: SETTABUP U0 K1 R0 ; U0["upload_impl"] := R0
4 [-]: CLOSURE R0 2 ; R0 := closure(Function #0_2)
5 [-]: SETTABUP U0 K2 R0 ; U0["download_impl"] := R0
...

第二种方法,先通过opcode还原写成正常的字节码

https://bbs.pediy.com/thread-275620.htm#msg_header_h3_5

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
import gdb
import time

startt = time.time()
fp = open(r"./log.log","w")
strr = ""
def pt(p):
global strr
strr += p + "\n"

Esp = 0
# 断点
gdb.execute('b *0x55555559C078') # LoadBlock
gdb.execute('b *0x55555559C184') # LoadByte
gdb.execute('b *0x55555559C1D1') # LoadInt
gdb.execute('b *0x55555559C111') # LoadNumber
gdb.execute('b *0x55555559C0A1') # LoadInteger

gdb.execute('r')
while 1:


frame = gdb.selected_frame()
rip = frame.read_register("rip")

if rip == 0x55555559C078 :

rdx = frame.read_register("rdx")
Esp += rdx

elif rip == 0x55555559C184:
pt(f"{hex(Esp).ljust(10,' ')} => 1")

elif rip == 0x55555559C1D1:
pt(f"{hex(Esp).ljust(10,' ')} => 4")

elif rip == 0x55555559C111:
pt(f"{hex(Esp).ljust(10,' ')} => 8")

elif rip == 0x55555559C0A1:
pt(f"{hex(Esp).ljust(10,' ')} => 8")

if Esp == 0x19f0:
fp.write(strr)
fp.close()
print("finish!!!")
enddd = time.time()
print(enddd - startt)
break


gdb.execute('c')

写fix_picstore.bin

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
import struct
fp = open(r"log.log","r")
fps = open(r"picStore.bin","rb")
fix_bin = open(r"fix_picStore.bin","wb")
data = fp.readlines()
data_bin = fps.read()
fix_data = b""


ans = 0
for i in range(len(data)):
op_str = data[i]
loa = int(op_str[2:6],16) + 1
step = int(op_str[14:15],16)

for j in range(ans,loa):
fix_data += struct.pack("B",data_bin[j])

for j in range(loa,loa + step):
if data_bin[j] != 0 and data_bin[j] != 0xff:
t = data_bin[j] ^ 0xff
fix_data += struct.pack("B",t)
else:
fix_data += struct.pack("B",data_bin[j])

ans = loa + step
fix_bin.write(fix_data)
fix_bin.close()

然后使用unluac还原

1
java -jar ./unluac.jar ./fix_picStore.bin > ./oplua.lua

得到源码后分析发现,进入check_func函数

image-20221226141839499

在该函数中发现了关键函数标志

1
a_AHy3JniQH4

klee求解

通过a_AHy3JniQH4找到对应ida中对应的函数chk_23

image-20221226144048131

看一下ida中代码实现,利用klee进行还原input

https://github.com/Pusty/writeups/blob/master/RCTF2022/kleeMe.c

先生成字节码,然后再执行klee

1
clang-11 -I klee/include -emit-llvm -c kleeMe.c &&  ~/klee_deps/klee_build110stp_z3/bin/klee kleeMe.bc
1
2
3
4
5
6
7
8
ktest file : 'test000001.ktest'
args : ['klee.bc']
num objects: 1
object 0: name: 'input'
object 0: size: 30
object 0: data: b'!\x92\xd0\xcf34\xe6\xbe\xc7\xd3n3\xcf\xbe.3O\xb7Ig*g\xc5S\xdd\x1d\xd1\xf0\xc2\x1a'
object 0: hex : 0x2192d0cf3334e6bec7d36e33cfbe2e334fb749672a67c553dd1dd1f0c21a
object 0: text: !...34....n3...3O.Ig*g.S......

脚本原理

对于所有abs方程,都假设为0

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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <klee/klee.h>

// clang-11 -I klee/include -emit-llvm -c kleeMe.c && ~/klee_deps/klee_build110stp_z3/bin/klee kleeMe.bc

bool chk_23(unsigned char *a1);

int main() {
unsigned char input[30];
klee_make_symbolic(input, 30, "input");
int res = chk_23(input);
return res;
}

int abs32(int x) {
klee_assume(x == 0);
return 0;
}

bool chk_23(unsigned char *a1) {
unsigned int v1;
unsigned int v2;
unsigned int v3;
unsigned int v4;
unsigned int v5;
unsigned int v6;
unsigned int v7;
unsigned int v8;
unsigned int v9;
unsigned int v10;
unsigned int v11;
unsigned int v12;
unsigned int v13;
unsigned int v14;
unsigned int v15;
unsigned int v16;
unsigned int v17;
unsigned int v18;
unsigned int v19;
unsigned int v20;
unsigned int v21;
unsigned int v22;
unsigned int v23;
unsigned int v24;
unsigned int v25;
unsigned int v26;
unsigned int v27;
unsigned int v28;
unsigned int v30;
unsigned int v31;
unsigned int v32;
unsigned int v33;
unsigned int v34;
unsigned int v35;
unsigned int v36;
unsigned int v37;
unsigned int v38;
unsigned int v39;
unsigned int v40;
unsigned int v41;
unsigned int v42;
unsigned int v43;
unsigned int v44;
unsigned int v45;
unsigned int v46;
unsigned int v47;
v1 =a1[0];
v2 =a1[1];
v3 =a1[2];
v4 =a1[3];
v5 =a1[4];
v6 =a1[5];
v7 =a1[6];
v8 =a1[7];
v9 =
+abs32(72265*v1-2384745)
+abs32(264694*v1-190137*v2+19025100)
+abs32(25295*v2+69369*v3+191287*v1-24434293)
+abs32(-170345*v2+217412*v3-26668*v1+38500*v4-27440782)
+abs32(127326*v4+260948*v2+-102835*v1+225038*v5-129683*v3-45564209)
+abs32(277432*v6+110191*v3+-186022*v4+175123*v2-75564*v5-252340*v1-12226612)
+abs32(255036*v7+-90989*v3+-201344*v4+122006*v5+-140538*v6+109859*v2-109457*v1-9396023);
v10 =a1[8];
v11 =a1[9];
v30 =v11;
v31 =a1[10];
v32 =a1[11];
v12 =
+abs32(251337*v3+-198187*v6+-217900*v2+-62192*v8+-138306*v7+-165151*v4-118227*v1-22431*v5+72699617)
+abs32(17253*v8+-134891*v7+144501*v4+220594*v2+263746*v3+122495*v6+74297*v10+205480*v1-32973*v5-115484799)
+abs32(101752*v11+67154*v8+-20311*v1+-30496*v6+-263329*v7+-99420*v10+255348*v3+169511*v4-121471*v2+231370*v5-33888892)
+abs32(-250878*v11+108430*v1+-136296*v5+11092*v8+154243*v7+-136624*v3+179711*v4+-128439*v6+22681*v31-42472*v10-80061*v2+34267161)
+abs32(41011*v8+-198187*v1+-117171*v7+-178912*v3+9797*v11+118730*v10-193364*v5-36072*v6+10586*v31-110560*v4+173438*v2-176575*v32+54358815)+v9;
v33 =a1[12];
v34 =a1[13];
v16 =a1[14];
v35 = v16;
v36 =a1[15];
v17 =
+abs32(243012*v33+-233931*v4+66595*v7+-273948*v5+-266708*v30+75344*v8-108115*v3-17090*v31+240281*v10+202327*v1-253495*v2+233118*v32+154680*v6+25687761)
+abs32(-69129*v10+-161882*v3+-39324*v32+106850*v1+136394*v5+129891*v2+15216*v33+213245*v30-73770*v34+24056*v31-123372*v8-38733*v7-199547*v4-10681*v6+57424065)
+abs32(-236487*v30+-45384*v1+46984*v32+148196*v7+15692*v8+-193664*v6+6957*v10+103351*v16-217098*v34+78149*v4-237596*v5-236117*v3-142713*v31+24413*v33+232544*v2+78860648)
+abs32(65716*v36+-18037*v32+-42923*v7+-33361*v4+161566*v6+194069*v31+-154262*v2+173240*v3-31821*v33-80881*v5+217299*v8-28162*v10+192716*v1+165565*v30+106863*v16-127658*v34-75839517)
+v12;
v37 =a1[16];
v38 =a1[17];
v18 =a1[18];
v39 =v18;
v19 =
+abs32(175180*v35+25590*v4+-35354*v36+-173039*v37+145220*v31+6521*v7+99204*v30+72076*v33+207349*v2+123988*v5-64247*v8+169099*v6-54799*v3+53935*v1-223317*v32+215925*v10-119961*v34-83559622)
+abs32(-207225*v1+-202035*v3+81860*v33+-114137*v5+265497*v36+-216722*v8+276415*v34+-201420*v10-266588*v38+174412*v6+249222*v30-191870*v4+100486*v2+37951*v31+67406*v32+55224*v37+101345*v7-76961*v35+33370551)
+abs32(-268870*v36+103546*v30+-124986*v33+42015*v7+80222*v2+-77247*v10+-8838*v31+-273842*v4+-240751*v34-187146*v32-150301*v6-167844*v3+92327*v8+270212*v5-87705*v18-216624*v1+35317*v37+231278*v38-213030*v35+114317949)
+v17;
v40 =a1[19];
v20 =
+abs32(43170*v3+-145060*v2+199653*v6+14728*v36+139827*v30+59597*v35+2862*v10+-171413*v37+-15355*v31-71692*v7-16706*v32+264615*v1-149167*v39+75391*v33-2927*v4-187387*v5-190782*v8-150865*v34+44238*v38-276353*v40+82818982)
+v19;
v41 =a1[20];
v21 =
+abs32(-3256*v33+-232013*v31+-261919*v35+-151844*v32+11405*v4+159913*v38+209002*v7+91932*v40+270180*v10+-195866*v3-135274*v39-261245*v1+24783*v41+262729*v8-81293*v30-156714*v2-93376*v34-163223*v37-144746*v5+167939*v6-120753*v36-13188886);
v22 =a1[21];
v42 =v22;
v43 =a1[22];
v23 =
+abs32(-92750*v34+-151740*v33+15816*v41+186592*v30+-156340*v35+-193697*v2+-108622*v8+-163956*v5+78044*v4+-280132*v22-73939*v39-216186*v3+168898*v36+81148*v40-200942*v38+1920*v1+131017*v32-229175*v10-247717*v37+232852*v31+25882*v7+144500*v6+175681562)
+abs32(-240655*v41+103437*v36+236610*v33+100948*v8+82212*v6+-60676*v5+-71032*v3+259181*v7+100184*v10+7797*v35+143350*v30+76697*v2-172373*v31-110023*v43-13673*v4+129100*v37+86759*v1-101103*v39-142195*v22+28466*v38-27211*v32-269662*v40+9103*v34-96428951)
+v21
+v20;
v44 =a1[23];
v45 =a1[24];
v24 =
+abs32(234452*v40+-23111*v35+-40957*v2+-147076*v8+16151*v38+-250947*v41+-111913*v36+-233475*v30+-2485*v34+207006*v32+71474*v3+78521*v1-37235*v42+203147*v5+159297*v7-227257*v44+141894*v31-238939*v10-207324*v43-168960*v39+212325*v6+152097*v37-94775*v33+197514*v4+62343322)
+abs32(216020*v44+-248561*v35+-86516*v39+237852*v32+-132193*v37+-101471*v3+87552*v31+-122710*v8+234681*v5+-24880*v7+-245370*v1+-17836*v42-225714*v40-256029*v4+171199*v41+266838*v10-32125*v30-43141*v38-87051*v36-68893*v45-242483*v34-12823*v2-159262*v33+123816*v43-180694*v6+152819799)
+v23;
v46 =a1[25];
v25 =
+abs32(-142909*v40+-111865*v37+258666*v42+-66780*v2+-13109*v41+-72310*v31+-278193*v32+-219709*v30+40855*v8+-270578*v44+96496*v5+-4530*v1+63129*v34-4681*v7-272799*v36-225257*v10+128712*v43-201687*v45+273784*v3+141128*v35+93283*v38+128210*v39+47550*v6-84027*v4+52764*v46-140487*v33+105279220)
+v24;
v26 =a1[26];
v47 =a1[27];
v27 =
+abs32(-215996*v4+-100890*v46+-177349*v7+-159264*v6+-227328*v33+-91901*v30+-28939*v10+206392*v47+6473*v31+-22051*v26+-112044*v40+-119414*v36+-225267*v41+223380*v3+275172*v5+95718*v45-115127*v35+85928*v32+169057*v44-204729*v1+178788*v42-85503*v37-121684*v2-18727*v38+109947*v39-138204*v8-245035*v34+134266*v43+110228962)
+v25
+abs32(-116890*v3+67983*v33+-131934*v4+256114*v46+128119*v30+48593*v39+-41706*v2+-217503*v32+49328*v6+223466*v7+-31184*v5+-208422*v42+261920*v1+83055*v26+115813*v43+174499*v35-188513*v41+18957*v31+15794*v10-2906*v34-25315*v8+232180*v38-102442*v45-116930*v40-192552*v44-179822*v37+265749*v36-54143007);
v28 =a1[28];
return v27
+ abs32(
-165644 * v38
+ 4586 * v45
+ 138195 * v31
+ 155259 * v41
+ -185091 * v3
+ -63869 * v37
+ -23462 * v36
+ 150939 * v47
+ -217079 * v8
+ -122286 * v6
+ 5460 * v44
+ -235719 * v7
+ 270987 * v32
+ 157806 * v40
+ 262004 * v35
- 2963 * v34
- 159217 * v10
+ 266021 * v39
- 190702 * v30
- 38473 * v26
+ 122617 * v2
+ 202211 * v42
- 143491 * v33
- 251332 * v4
+ 196932 * v5
- 155172 * v28
+ 209759 * v46
- 146511 * v1
+ 62542 * v43
+ 185928391)
+ abs32(
57177 * v30
+ 242367 * v45
+ 226332 * v37
+ 15582 * v32
+ 159461 * v40
+ -260455 * v28
+ -179161 * v43
+ -251786 * v38
+ -66932 * v47
+ 134581 * v1
+ -65235 * v35
+ -110258 * v34
+ 188353 * v44
+ -108556 * v6
+ 178750 * v46
+ -20482 * v31
+ 127145 * v8
+ -203851 * v5
+ -263419 * v10
+ 245204 * v39
+ -62740 * v26
+ 103075 * v2
- 229292 * v42
+ 142850 * v36
- 1027 * v33
+ 264120 * v3
+ 264348 * v4
- 41667 * v41
+ 130195 * v7
+ 127279 * a1[29]
- 51967523) == 0;
}

可以得到结果

1
2
3
4
5
6
7
8
ktest file : 'test000001.ktest'
args : ['klee.bc']
num objects: 1
object 0: name: 'input'
object 0: size: 30
object 0: data: b'!\x92\xd0\xcf34\xe6\xbe\xc7\xd3n3\xcf\xbe.3O\xb7Ig*g\xc5S\xdd\x1d\xd1\xf0\xc2\x1a'
object 0: hex : 0x2192d0cf3334e6bec7d36e33cfbe2e334fb749672a67c553dd1dd1f0c21a
object 0: text: !...34....n3...3O.Ig*g.S......

继续分析lua,可以提取出字节表L3_2

image-20221226161517400

会利用该表进行操作如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for L7_2 = L4_2, L5_2, L6_2 do
temp = "xor"
temp = _ENV[temp]
L9_2 = L1_2[L7_2]
L10_2 = L7_2 - 1
temp = temp(L9_2, L10_2)
L1_2[L7_2] = temp
temp = "xor"
temp = _ENV[temp]
L9_2 = L1_2[L7_2]
L10_2 = 255
temp = temp(L9_2, L10_2)
L1_2[L7_2] = temp
temp = L1_2[L7_2]
temp = temp & 255
L1_2[L7_2] = temp
temp = #L2_2
temp = temp + 1
L9_2 = L1_2[L7_2]
L9_2 = L9_2 + 1
L9_2 = L3_2[L9_2] out[i] = t
L2_2[temp] = L9_2
end

相当于一个置换表,脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
byteTable = "69f43f0a18a9f86b818a19b660b00e5938e5ce13171516c6b3a798421cc9d550a29766245b253211aa29035455e283264720128e462770dc10db9fde0b7763cb2f94b9375d30997101ed234b439ba14a6c4cb5e9ba2c7de858085fa3c8f978f3aed4fcea3a65e4566d90687975570f840c14a573888776454402527bfafb35ff33ddd3c3918cfe00742b1dd9c5b7a8bc22da92936295f6b4672128cfd0c08f1a9ae1648daf7ce63eb1cd6ecafdad2e3472a4a6899e7a0d53b285bdbb07b84df5d8bec2489dacabc7a02d311bcc51065c3bd1ef82613dd6d7495a7e2a1ef04fe04edf6f3c0405c4e76a408beb96e3eebf7f1f9c36f1f286f780415e39d2ec09c1"
validInput = "2192d0cf3334e6bec7d36e33cfbe2e334fb749672a67c553dd1dd1f0c21a"

byteTable = bytes.fromhex(byteTable)
validInput = bytes.fromhex(validInput)

def encrypt(inputValues):
output = []
for i in range(30):
a = inputValues[i]^(i^0xff)&0xff
output.append(byteTable[a])
[print(hex(i).split('0x')[1],end='') for i in output]

def decrypt(enc):
for i in range(30):
index = byteTable.index(enc[i])
a = index^(i^0xff)&0xff
print(chr(a),end='')
print('\ndecrypt success')

# encrypt(b'flag{U_90t_th3_p1c5t0re_fl49!}')
decrypt(validInput)

tips

abs32函数在算法上与y = x >> 31; (x^y)-y相等。

image-20221226150705352

https://hackmd.io/@94y7q597ST2hNdB9lbTJhA/S1wJr4Bds

https://blog.csdn.net/qq_41866334/article/details/128302662

https://blog.wm-team.cn/index.php/archives/35/

https://www.cnblogs.com/xyqer/articles/16454030.html

https://hackmd.io/@K-atc/rJTUtGwuW?type=view#uc_hook_add

https://s1lenc3-chenmo.github.io/2021/07/25/unicorn%E5%85%A5%E9%97%A8%E5%8F%8A%E5%BC%BA%E7%BD%91%E6%9D%AFunicorn-like-a-pro%E5%A4%8D%E7%8E%B0/#unicorn%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97

本文采用CC-BY-SA-3.0协议,转载请注明出处
Author: scr1pt