-
-
[原创]CTF2019Q1 第二题 变形金钢
-
2019-3-24 17:19 3808
-
title: 第二题 变形金钢
jni 分析
.init_array 段里,有个解密函数
都是异或很简单,用二进制工具手动改掉
进入 JNI_OnLoad 函数
jni 提供了 android.support.v7.app.AppCompiatActivity 的 eq 函数,在偏移 0x784
dex 分析
用 jadx 打开 apk,常规定位到 MainActivity,没有发现调用到 eq 的地方,幸得队友帮助
发现实 MainActivity 继承的 AppCompiatActivity 比原生的 AppCompatActivity 中间多了个 i,MainActivity 全是幌子,关键要定位到 android.support.v7.app.AppCompiatActivity,果然这里有 native 引用 jni 的地方
jni 分析
回头看 jni 中的 AppCompiatActivity_eq 函数,经过以下流程
- 内置字符串 650f909c-7217-3647-9331-c82df8b98e98 去掉 '-'
- 翻转过来并加上 '-'
- 用了个字符替换算法得到 key
- 使用改过 box 的 rc4 算法加密输入
- 变形的 base64
- 最后和内置的字符串对比
代码
import string # 变形 b64 除了替换了表以外,还在 第1 和 第3 字节处做了异或运算 def b64dec(s): ts = "" for i in xrange(len(s)): if s[i] == ";": ts += ";" elif i % 4 == 0: ts += chr(ord(s[i]) ^ 7) elif i % 4 == 2: ts += chr(ord(s[i]) ^ 0xf) else: ts += s[i] tab = string.maketrans("!:#$%&()+-*/`~_[]{}?<>,.@^abcdefghijklmnopqrstuvwxyz0123456789\\';", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=") return ts.translate(tab).decode("base64") # 先逆向最后一步 b64 step1 = b64dec("207B392A3867612A6C21546E3F4023666A276A245C673B3B".decode("hex")) # fd1e8a4e09ca9003e7f1859f9bf7833e0e # 除了初始化的 box 是内置的,其他流程都一样 def rc4(key, txt): box = bytearray("D7DF02D4FE6F533C256C999706568FDE40116407361570CA18177D6ADB1330372960E123288A508CAC2F8820270F7C52A2ABFCA1CC21141FC2B28B2CB03A66463DBB42A50C7522D8C3761E8374F0F61C26D14F0BFF4C4DC187035AEEA45D9EF4C80D62633E447BA368321BAA2D05F3F7166194E0D0D3986978E90A65918E35857A5186103F7F82DDB51A95E743FD9B2445EF925CE496A99C55899AEAF9905FB80484CF679300A639A84E59316BAD5E5B77B154DC3841B6479F73BAF8AEC4BE34014B2A8DBDC5C6E8AFC9F5CBFBCD79CE1271D2FA09D5BC581980DA491DE62EE37EB73BB3A0B9E5576ED908EBC7ED81F1F2BFC0A74AD62BB4729D0E6DEC48E233".decode("hex")) key_len = len(key) j = 0 for i in range(256): j = (j + box[i] + ord(key[i %key_len])) %256 box[i], box[j] = box[j], box[i] result = "" i = j = 0 for e in txt: i = (i+1) %256 j = (j + box[i]) %256 box[i], box[j] = box[j], box[i] result += chr(ord(e) ^ box[(box[i] + box[j]) %256]) return result # 直接使用调试拿到的 key 运算 print rc4("36f36b3c-a03e-4996-8759-8408e626c215", step1)
后记
开始我以为是输入后弹出对话框的 flag 是答案,输错了几次,结果还是得到的解
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
赞赏
他的文章
看原图