# CTF 移动端

# 第一题 Illusion

jadx 打开

image-20220802160426972

发现就是对输入的进行了一个判断,用到的是 native 方法

用 ida 打开 so,然后修改下变量名

image-20220802161701172

这里的 aE 就对应的下面这个长字符串

image-20220802161639961

然后这串代码的大致意思其实就是判断计算的这个 Buffer 中的每一个值是不是和 enc 中的相等,如果相等那就返回 correct,接下来就需要进一步查看 sub_10C0 的逻辑,因为这里的 a2 恒为 93,那么直接进入 sub_1028 查看对应逻辑

image-20220802162458311

直接把 sub_10C0 代码 copy 下来测试

image-20220802164705080

发现主要逻辑与 a1,a2 的大小有关,如果 a1 小于 a2 就为 0,同时观察函数名可以猜测应该和除有关,接着测试几个,发现这个其实就是整数除法。

回到 so 开始位置还原逻辑

# 对应的 for 循环内部的操作
(a + b - 64)/93 >> 32 + 32 = c 
c - 32 = (a + b - 64)/93 [0,1,2...]
c + 32 - b = a [分情况]

image-20220802202342663

  • ord 返回字符的 unicode 编码

  • chr 将 unicode 编码转化为字符

直接不采用分情况的写法会拿到如下 ascii 码表,其中包含负数,我们知道一个负数 / 93 然后在 >> 32 是会得到 0 的,同时,如果一个数大于 32 , 那么 对其进行 >>32 的操作,其实是不会变的,所以就需要分离出小于 32 的情况。

key = '(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;'
enc = "Ku@'G_V9v(yGS"
flag = [(ord(i) + 32 - ord(j))for i,j in zip(enc,key)]
print(flag)
for i in range(len(flag)):
    if flag[i] <= 0x20:
       flag[i] = chr(93+flag[i])
    else:
      flag[i] = chr(flag[i])
print(''.join(flag))
# CISCN{GJ5728}

这里有个小 bug,就是 key 这里的值,用 Ida 打开直接看发现是上述那个 32 位的字符串

Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

Mr2 WeChat Pay

WeChat Pay