攻防世界Mobile - gogogo、Illusion
0x01 题目 (gogogo)分析
首先下载程序,确认程序是否加固
发现是go语言写的elf文件,使用DIE查看文件信息可以获取到一节字符串SbdNpcmHFLk2wxxGroDK/eAYbXRTx1FtkTOZ6bYjs/UeXTgMk-58143Im6_i3Z/HEZAZRj6H7CjTH5bTU-m 打开IDA进行分析,找到程序入口main
题解
题目用go编写,go实现了一个类似虚拟机的功能,对栈进行了操作,进行一系列定义的code后与内置的stack数组进行比较,令其相等的就是flag。
定义了9个操作码,和操作码数组,给出特定输入让check相等。
flag
flag{I_am_the_last_one}
0x01 题目 (Illusion) 分析
首先查看文件是否加固,使用jadx-gui打开,确保程序没有加固和混淆
1.打开assest目录下面的 “Flag” 文件,使用IDA获取到字符串,后面会用到 Ku@'G_V9v(yGS
2.打开IDA分析lib下面的so文件,获取flag
Alt+T 输入 CheckFlag 方法进行搜索
F5 进行反编译,将汇编代码转换为C语言形式
简单分析一下:
这段代码是一个循环,用于对字符串进行处理。其中,v9
和 v8
分别是两个字符串指针,i
是循环计数器。循环的条件是当 i
小于 v9
字符串的长度时执行循环体。
循环体中,首先将 v9
中第 i
个字符强制转换为 unsigned __int8
类型,并与 aE116c5c66e7b37
中第 i
个字符减去 64 后相加,并将结果右移 32 位。之后将得到的结果作为参数传递给函数 sub_10C0
,并将其返回值赋值给 v8
中的第 i
个字符。
注意,这里有一个坑,我们 双击打开aE116c5c66e7b8761 这个函数,会发现一段字符串,不要被她迷惑了,很有可能是个陷阱哦!
此段汇编代码主要是用来操作字符串的,首先将字符串 “e116c5c66e76873d912cb96885648913” 存储在一段内存中,然后通过 LDR 指令将该字符串的地址加载到 R0 寄存器中。最后,通过 ADD 指令计算出字符串的真实地址并将其存储到 R0 中,以便进行进一步的操作。
接下来继续分析 sub 10C0 这个函数
分析 sub_1028 函数
首先定义了四个变量v2、v3、v4和result
之后 在函数内部,将变量v2初始化为参数al和a2的异或结果,变量v3初始化为1,变量v4初始化为0。
接下来,通过if语句判断参数a2和al的最高位是否为1。如果是,则将它们取负数,这是因为在进行数字运算时,被除数和除数均为正整数时结果为正数,否则结果为负数。
然后,进入while循环,用于计算参数a2和变量v3(初始值为1)的最小公倍数。具体操作是,如果a2小于0x10000000且小于al,则将a2乘以16,v3也乘以16;如果a2左移一位小于0x80000000且小于al,则将a2左移一位,v3右移一位。直到a2等于al为止。
接着,再进入while循环,用于进行除法运算。每次循环,将变量al减去变量a2,并将得到的差存储在变量al中。同时,将变量v4与变量v3的一半相加,结果存储在变量v4中。当变量al小于a2除以2的平方时,跳出循环。
最后,根据变量v2的值来决定函数的返回值。如果v2为正数,则返回变量v4;否则将变量v4取反,并作为函数的返回值。
0x02 编写EXP
将用户输入的每个字符,加上内置data字符串对应的下标的字符,然后再减去64;
得到的结果,取余93后,进行比较
exp
# Ku@'G_V9v(yGS
enc_flag = "Ku@'G_V9v(yGS"
data = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"
data = [ord(i) for i in data]
def main():
enc = [ord(i) for i in enc_flag]
flag = [0]*len(enc)
for i in range(len(enc)):
flag[i] = (enc[i]-32)+64-data[i]
while flag[i] < 0x32:
flag[i] += 93
while flag[i] > 125:
flag[i] -= 93
print("".join([chr(i) for i in flag]))
if __name__ == '__main__':
main()
最后得到flag为:CISCN{GJ5728}