首页
社区
课程
招聘
[原创]看雪CTF2017第十二题简单解析
2017-6-24 23:35 4556

[原创]看雪CTF2017第十二题简单解析

loudy 活跃值
10
2017-6-24 23:35
4556

看雪CTF2017第十二题简单解析

    者:loudy

使用工具:IDA6.8so修改、反汇编分析、动态调试) notepad(记录) vc6.0(编程解码) android sdk emulatorandroid4.4虚拟机) jebdex反编译) ApkIDE(修改DEX、重打包)

    骤:

一、反逆向手段绕过

1dex

直接JEB分析,如下图3处红线标注的地方有MD5校验。

绕过方法也很简单,ApkIDE反编译,修改下图61行的if-eqzif-neq,并重新打包,即可直接跳过MD5检测。打包时,也许会提示某个styles.xml的几行有问题,删除那几行即可。

2so

IDA连接,程序直接退出,故肯定有反调试手段。用winrarapk文件解包后,发现lib目录有3个不同的so文件,如下,其中armeabi-v7a文件夹下的libenjoy.so文件才是我的android4.4系统需要的,分析此文件。

IDA载入,静态分析,没有发现.init表,那么我们重点分析JNI_OnLoad函数。其中sub_24B8sub_281C是两个主要的反调试函数。

sub_2350sub_2378都是同一种形式的解码函数,即按字节依次与0x16异或,解密结果都是字符串,这种函数后面还有很多,不一一介绍。

JNI_OnLoad中第14行解码结果为“check”,也即dex调用的本地函数,再看17行,跟踪到如下位置,发现check函数的实际地址为sub_3748

而此处作者也用了一个小手段,自己新建了一个名为.mytext的可执行段,sub_3748在其中实现,导致IDA在默认的.text段找不到该函数,有一定的反逆向效果。

再看JNI_OnLoad函数调用的sub_24B8函数,该函数的主要作用是读取/data/dalvik-cache/目录下的data@app@com.game.kxctf-1.apk@classes.dex文件或者data@app@com.game.kxctf-2.apk@classes.dex文件的校验值,结果与“E07784C2A2923354F18952BBDB5D81916D24D2F5”比较,不等于则exit(0)退出程序。

绕过方法也很简单直接将JNI_OnLoad中对该函数的调用以0x00覆盖即可。

JNI_OnLoad函数调用的sub_281C函数,实际就是调用sub_1B04如下,该函数创建了一个线程。

跟进后,发现线程主体如下。其中sub_25A8函数获取/proc/%d/statusState,看其中是否包含“R/S/T”sub_2628 获取/proc/%d/statusTracerPid,看是否为非0值。sub_2688执行cat /proc/%d/wchan,看结果中是否包含sys_epoll或者ptrace_stopsub_24B8之前已经分析。

从分析可以知道,该线程没有影响算法流程,因此也可以直接在JNI_OnLoad中将对sub_281C的调用以0x00覆盖,实现绕过。

最后在check函数sub_3748开头还有一处反调试,如下,分析发现sub_27B4功能和sub_24B8一模一样,不再累述,直接将调用处用0x00覆盖实现绕过。

二、算法流程分析

反逆向手段清除后就可以大胆调试,跟踪算法流程了。流程分dex层和so层两个方面讲。

1dex

   JEB分析结果很直观,将三个函数分别对输入字符串的处理结果连接起来,送入so层处理,如果so层处理结果为1,则正确。

ca.abase64编码,ba.aab.a也分别是一种编码,虽然有三种编码,但实际分析后发现,ca.aba.a都不起作用,实际只有ab.a参与了算法流程,该函数如下。

   public static String a(String input) {
        return ab.encrypt(input);
    }
    public static String encrypt(String input) {
        String v3 = "";
        int v2;
        for(v2 = 0; v2 < input.length(); ++v2) {
            int v0 = input.charAt(v2);
            if(v0 < 97 || v0 > 109) {
                if(v0 >= 65 && v0 <= 77) {
                    v3 = String.valueOf(v3) + (((char)(v0 + 13)));
                    goto label_20;
                }
                if(v0 >= 110 && v0 <= 122) {
                    v3 = String.valueOf(v3) + (((char)(v0 - 13)));
                    goto label_20;
                }
                if(v0 >= 78 && v0 <= 90) {
                    v3 = String.valueOf(v3) + (((char)(v0 - 13)));
                    goto label_20;
                }
                if(v0 >= 48 && v0 <= 57) {
                    v3 = String.valueOf(v3) + (((char)(v0 ^ 7)));
                    goto label_20;
                }
                v3 = String.valueOf(v3) + (((char)(v0 ^ 6)));
            }
            else {
                v3 = String.valueOf(v3) + (((char)(v0 + 13)));
            }
        label_20:
        }
        return v3;
    }

此时无需更加深入分析,可以等so反推之后再爆破。

2so

so层流程其实很简单。

1、    判断dex层传来的数据是否大于0x78(其实此时就是0x78),大于则over

2、    截取前0x24位(即dexab.a函数处理结果),并在结尾补440x28位。

3、    用密钥{0xFD, 0xB4, 0x68, 0x54, 0x08, 0xCD, 0x56, 0x4E}对此0x28位进行DES加密(非标准)(实际操作时,密钥转换为子密钥总有一两位不同,故直接在内存提取子密钥表,取消密钥生成过程)

4、    DES结果第0x200x210x220x23位替换密钥{0x65, 0x48, 0x32, 0xEF, 0xBA, 0xCD, 0x56, 0x4E, 0x0F, 0x9B, 0x1D, 0x27, 0x0, 0x0, 0x0, 0x0}的最后四位。

5、    用上一步的密钥对DES结果前0x20位进行RC6加密。

6、    RC6加密(非标准)结果与0x42D3C3C2, 0xF12AE92D, 0x66C92822, 0x2CEB540E0x9407E577, 0x4A92B792, 0x2E5DFDF0, 0xF3549FC6比较,全部相等则注册成功。

三、破解过程

流程梳理清楚就好了,首先通过调试修改标准DESRC6与程序所用一致。

其中DES修改较小,RC6修改较大,分别如下。一般RC6加密Q值为0x9E3779B9,而静态分析可知此程序为0x61C88647(即-0x9E3779B9)。

另外RC6的密钥会有个反馈,不是每次块(0x10字节)加密都用同一个密钥,对照IDAC代码做如下修改,其中kerr为下一次加解密的密钥。

这两个函数调整好后(这是一个漫长的跟踪过程),事情就好办了。

由于DESECB模式,8字节独立加密。根据已知条件前8字节为“kxuectf{”得到加密结果0x4C0xD9, 0xA3, 0xE6, 0xED, 0xFE, 0xD1, 0x05

由最后一个字节为“}”ab.a函数处理后为“{”,所以DES加密的最后8字节为x,x,x,{,4,4,4,4,其中x为未知数。编写如下代码爆破,得到结果“a>6”

for(char i=0x20;i<0x7f;i++)
         for(char j=0x20;j<0x7f;j++)
              for(char k=0x20;k<0x7f;k++)
              {
                       str[0] = i;
                       str[1] = j;
                       str[2] = k;
                       memset ( str2, 0, sizeof ( str2 ) );
                       Des_Run ( str2, str, ENCRYPT );
                       key1[12]=str2[0];
                       key1[13]=str2[1];
                       key1[14]=str2[2];
                       key1[15]=str2[3];
                       rc6_key_setup(key1, 16);
                       rc6_block_decrypt(ct, pt);
                       if(pt[0]==stro[0] && pt[1]==stro[1])
                       {
                            printf("%c%c%c%c\n",str[0],str[1],str[2],str[3]);
                       }
              }

由此得到正确RC6密钥{0x65, 0x48, 0x32, 0xEF, 0xBA, 0xCD, 0x56, 0x4E, 0x0F, 0x9B, 0x1D, 0x27, 0x13, 0x6a, 0x7e, 0x1F}

利用此密钥对0x42D3C3C2, 0xF12AE92D, 0x66C92822, 0x2CEB540E0x9407E577, 0x4A92B792, 0x2E5DFDF0, 0xF3549FC6解密,得到结果“xkhrpgs}Q4pelcgrq6fI4elyagrer2gv”,加上“a>6{”,即“xkhrpgs}Q4pelcgrq6fI4elyagrer2gv a>6{”为正确的进入so的字符串。

通过如下函数爆破。

#include <stdio.h>
char test[] = "xkhrpgs}Q4pelcgrq6fI4elyagrer2gva>6{";
char getit(char a){
    if(a<97 || a>109){
            if(a>=48 && a <=57){
                return  a^7;
            }
            else if(a>=65&&a<=77){
                return a+13;
            }
            else if(a>=78&&a<=90){
                return a-13;
            }
            else if(a>=110 && a<=122){
                return a-13;
            }
            else{
                return a^6;
            }
    }
    else{
            return a+13;
    }   
}
 
int main(){
    for(int j=0;j<36;j++){
        printf("%d ",j);
        for(char a=0x20;;a++){
            if(getit(a)==test[j]){
                printf("%c ",a);
            }
            if(a==0x7f) break;
        }
        printf("\n");
    }
    return 0;
}

如果剔除掉特殊字符,得到注册码为

“kxuectf{D3crypted1sV3rylntere5tin91}”输入模拟器,正确。当然如果算上特殊字符,此题多解,不多解释。


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 4357
活跃值: (874)
能力值: ( LV8,RANK:142 )
在线值:
发帖
回帖
粉丝
elecs 2 2018-10-10 16:31
2
0
修改smali文件后重新打包,总会出现错误:mismatched input 'if-neq' expecting END_METHOD_DIRECTIVE。楼主知道是什么原因吗?

游客
登录 | 注册 方可回帖
返回