XMan2017冬 孔雀翎writeup

周六下午听说有面向萌新的移动安全CTF,本来不想欺负小朋友,最后抱着去装个B的态度去做了一下最难的那个apk,质量不错,出题人还是很良心的。

附上题目链接:https://github.com/LeadroyaL/attachment_repo/tree/master/xman_2017/ 。

整个题目是Java写的,没有用到一丁点native的东西,但处理的还是很好的。主要难点在于静态字符串的混淆和由此引来的反射方法难以追踪,加密方式可以通过观察规律来探索,总体来说设计的很不错。

一开始抱着弄懂每一处细节去做的,所有的字符串都被加密处理过了,但解密的方法是写在代码里的,一般位于static段,也可能是动态运行并且解密的,显然里面加了几个while-true让JEB和jadx都发生了不同程度的抽风,从一个确定的字符串为起点,生成String或String[],前者的话,就按位异或,组成解密后的字符串,循环与无规律的byte[7]进行xor;后者要复杂一点,使用substring来切开不同的部分,再分别与无规律的byte[7]进行xor,第一个substring的长度由const-int来确定,后面的长度是在字符串里紧接着的一个char的值。格式类似于给定int3,去处理这条

字符串这样的。

还有一种动态解密方式是给定一个Long,只有最高的几个bit有效,所以看起来是杂乱无章的,经过计算将Long换算为index,去查Object[] cache,如果类别是Object,就表示未解密,如果类别是String,表示已经解密可以直接拿去用。这部分使用的是每个String分别去xor一个固定数值的char,有多少个String就会有多少个xor_char。

嗯,写代码解密吧。。。呸,解个毛线,太恶心了不想解密,还是动态上去看吧。懒得写了,而且提取参数的话还会稍微费点时间。

观察一下,每个被静态解密的String最终都会调用到String.intern(),虽然不大明白这个的意义是什么,但搜索smali就方便多了。调试时候下这么几个断点:对于单个String的解密,断各个String.intern();对于String[]的解密,断在对数组赋值的地方;对于反射,断在获取字符串的地方。但是由于smalidea本身bug的存在,只能dump到String和String[],其他地方经常会crash。所以也懒得debug了,看一眼dump出来的数据,有个table,有个AES256_ECB_PKCS5。再浏览一下整体的逻辑,就差反射的部分没有任何信息了,调试的话崩溃太多没法搞。

随便解密几个固定的数值,感觉已经够用了,能猜到是在做什么了。

 

观测到a.a.c.d是最主要的入口,也是由反射调进去的,而且里面看起来经过了多轮加密,大概率是要逆的东西了。上xposed搞一下,hook一下反射时候的各种参数,主要关注控制流程和传参数值、类型。

贴一下hook和log

Log

这样看起来就舒服多了,调用流程很清楚,连续过好好几个函数,再浏览一遍主程序,嗯非常清晰完整。

1235步都很好懂,主要是第4步不知道在干嘛,而且那段代码jadx反出来居然是错的。。。mdzz

观察一下,输入是binaryString,输出是int[]数组,而且输入必须要”1″开头,观察发现是连续的1的个数、连续的0的个数。逆起来也不复杂,刚好这个int[]加起来长度为384,是一个很吉利的数字。

之后,按照步骤解密一下,看python就可以了

还是挺不错的,有机会研究一下Java层的防御手段。


=============================================================
随着访客的增多,LeadroyaL在本站流量的开支越来越多了,曾经1元能用1个月,现在1元只能用3天。如果觉得本文帮到了你,希望能够为服务器的流量稍微打赏一点,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code