-
-
[原创]KCTF 2024 第六题 WriteUp
-
发表于: 2024-8-27 00:28 3069
-
首先x64dbg挂上,验证一遍给的用户名和序列号能否通过,发现可以通过,看来没加反调试或者反调试被ScyllaHide给干掉了,好事
用IDA看了看,关键的部分是这个函数,用x64dbg下硬件断点设置日志输出,把这两个地方call的地址都记录下来
其中,v13的基本上都是上面这种,调用的外部函数,或者.text段中的被虚拟化的函数
而rcx的则是零散的加了混淆的代码块,基本上就popfq的下一条指令是真实指令,别的都是保存、恢复上下文和修改控制流的指令,写个脚本通过刚才记录的call地址把代码还原出来(如果想看仔细一点就把去重的逻辑删掉,输出的内容会多很多)
代码很清楚,没有嵌套混淆,也没有奇奇怪怪的扩展指令集优化
简单描述一下算法,就是把输入的16字节用户名(不满16字节则填充0x00)和"welcome_to_fzbz,"异或,再把输入的64字节0-9、A-F序列号转换为32字节,然后进行4次大循环,每次循环处理8字节序列号,其中用到了异或后的16字节用户名,最后把处理完的序列号和"welcome_to_fzbz,my_name_is_sbzx!"判断是否相同,我写了一个每一次大循环的python等价代码
每个input、output都是4字节,两个加起来8字节,用户名的部分我硬编码到算法代码里了
一直做到这个部分,都一路顺畅,很快搞完没有卡壳,然后……求逆算法花了巨多的时间,期间试过用z3来求解,然后发现挂了半天啥也没算出来,问GPT也是一通胡言乱语,最后还是用笨办法老老实实手动搞完的
fn
=
...
fp
=
open
(...,
"w"
)
visited
=
set
()
for
i
in
fn.splitlines():
ea
=
int
(i,
16
)
if
ea
in
visited:
continue
visited.add(ea)
idaapi.create_insn(ea
+
1
)
fp.write(
hex
(ea))
fp.write(
"\t\t"
)
fp.write(generate_disasm_line(ea
+
1
,
0
))
fp.write(
"\n"
)
fp.close()
fn
=
...
fp
=
open
(...,
"w"
)
visited
=
set
()
for
i
in
fn.splitlines():
ea
=
int
(i,
16
)
if
ea
in
visited:
continue
visited.add(ea)
idaapi.create_insn(ea
+
1
)
fp.write(
hex
(ea))
fp.write(
"\t\t"
)
fp.write(generate_disasm_line(ea
+
1
,
0
))
fp.write(
"\n"
)
fp.close()
import
ctypes
input_A
=
...
input_B
=
...
rsp_1
=
ctypes.c_uint(input_A)
rsp_2
=
ctypes.c_uint(input_B)
rsp_0
=
ctypes.c_uint(
0x2538263C
)
rsp_5
=
ctypes.c_uint(
0x5F656D6F
)
eax
=
ctypes.c_uint(
0
)
ecx
=
ctypes.c_uint(
0
)
edx
=
ctypes.c_uint(
0
)
for
_
in
range
(
0x1F
):
eax.value
=
rsp_2.value
eax.value <<
=
6
ecx.value
=
rsp_0.value
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_2.value
edx.value
+
=
ecx.value
ecx.value
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_2.value
ecx.value >>
=
3
edx.value
=
rsp_0.value
edx.value >>
=
8
edx.value &
=
0xFF
ecx.value
+
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_1.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_1.value
=
eax.value
eax.value
=
rsp_5.value
ecx.value
=
rsp_0.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_0.value
=
eax.value
eax.value
=
rsp_1.value
eax.value <<
=
6
ecx.value
=
rsp_0.value
ecx.value >>
=
0x18
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_1.value
edx.value
+
=
ecx.value
ecx.value
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_1.value
ecx.value >>
=
3
edx.value
=
rsp_0.value
edx.value >>
=
0x10
edx.value &
=
0xFF
ecx.value
+
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_2.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_2.value
=
eax.value
rsp_1.value ^
=
rsp_0.value
rsp_2.value ^
=
rsp_0.value
rsp_0
=
ctypes.c_uint(
0x665F6F74
)
rsp_5
=
ctypes.c_uint(
0x2C7A627A
)
for
_
in
range
(
0x1F
):
eax.value
=
rsp_2.value
eax.value <<
=
4
ecx.value
=
rsp_0.value
ecx.value >>
=
0x18
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_2.value
edx.value
+
=
ecx.value
ecx.value
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_2.value
ecx.value >>
=
5
edx.value
=
rsp_0.value
edx.value &
=
0xFF
ecx.value
+
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_1.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_1.value
=
eax.value
eax.value
=
rsp_5.value
ecx.value
=
rsp_0.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_0.value
=
eax.value
eax.value
=
rsp_1.value
eax.value <<
=
4
ecx.value
=
rsp_0.value
ecx.value >>
=
0x10
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_1.value
edx.value
+
=
ecx.value
ecx.value
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_1.value
ecx.value >>
=
5
edx.value
=
rsp_0.value
edx.value >>
=
8
edx.value &
=
0xFF
ecx.value
+
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_2.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_2.value
=
eax.value
output_A
=
rsp_0.value ^ rsp_1.value
output_B
=
rsp_0.value ^ rsp_2.value
import
ctypes
input_A
=
...
input_B
=
...
rsp_1
=
ctypes.c_uint(input_A)
rsp_2
=
ctypes.c_uint(input_B)
rsp_0
=
ctypes.c_uint(
0x2538263C
)
rsp_5
=
ctypes.c_uint(
0x5F656D6F
)
eax
=
ctypes.c_uint(
0
)
ecx
=
ctypes.c_uint(
0
)
edx
=
ctypes.c_uint(
0
)
for
_
in
range
(
0x1F
):
eax.value
=
rsp_2.value
eax.value <<
=
6
ecx.value
=
rsp_0.value
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_2.value
edx.value
+
=
ecx.value
ecx.value
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_2.value
ecx.value >>
=
3
edx.value
=
rsp_0.value
edx.value >>
=
8
edx.value &
=
0xFF
ecx.value
+
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_1.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_1.value
=
eax.value
eax.value
=
rsp_5.value
ecx.value
=
rsp_0.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_0.value
=
eax.value
eax.value
=
rsp_1.value
eax.value <<
=
6
ecx.value
=
rsp_0.value
ecx.value >>
=
0x18
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_1.value
edx.value
+
=
ecx.value
ecx.value
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_1.value
ecx.value >>
=
3
edx.value
=
rsp_0.value
edx.value >>
=
0x10
edx.value &
=
0xFF
ecx.value
+
=
edx.value
eax.value ^
=
ecx.value
ecx.value
=
rsp_2.value
ecx.value
+
=
eax.value
eax.value
=
ecx.value
rsp_2.value
=
eax.value
rsp_1.value ^
=
rsp_0.value
rsp_2.value ^
=
rsp_0.value
rsp_0
=
ctypes.c_uint(
0x665F6F74
)
rsp_5
=
ctypes.c_uint(
0x2C7A627A
)
for
_
in
range
(
0x1F
):
eax.value
=
rsp_2.value
eax.value <<
=
4
ecx.value
=
rsp_0.value
ecx.value >>
=
0x18
ecx.value &
=
0xFF
eax.value
+
=
ecx.value
ecx.value
=
rsp_0.value
edx.value
=
rsp_2.value
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: