天天看点

BugkuCTF-Reverse题Timer(阿里CTF)

知识点

JEB相当于Windows平台上的IDA

smali代码:双击Bytecode,出现smali代码;相较于C之汇编,那么smali之于Java

onCreate:

一个activity启动回调的第一个函数就是onCreate,这个函数主要做这个activity启动的一些需要的初始操作的工作。

onCreate之后调用了还有onRestart()和onStart()等。

解题流程

下载apk包

apk安装之后出现一个读秒的,20万秒,大于3600,所以大于一个小时,所以太慢了,不等了。

BugkuCTF-Reverse题Timer(阿里CTF)

jeb反编译,主要JEB反编译得到的java代码看起来比较清晰

MainActivity代码:

BugkuCTF-Reverse题Timer(阿里CTF)
BugkuCTF-Reverse题Timer(阿里CTF)
BugkuCTF-Reverse题Timer(阿里CTF)
BugkuCTF-Reverse题Timer(阿里CTF)

源码审计

MainActivity

BugkuCTF-Reverse题Timer(阿里CTF)

对程序进行分析

初始操作了一些变量,其beg为(((int)(System.currentTimeMillis()/1000)+200000;

this.beg = (((int)(System.currentTimeMillis() / 1000))) + 200000;beg为一个定值,在上面代码的run()函数里,k是可以变化的

MainActivity.this.t = System.currentTimeMillis();

MainActivity.this.now = ((int)(MainActivity.this.t / 1000));

给出了now的赋值,从程序的运行来看,beg在now初始赋值后应该比now大了200000,now代表的是程序运行的时间,当now变化了200000的时候,也就是说beg小于now的时候,会进入设置flag的地方。

也就是说,程序一开始k是变化的,flag的值并没被设置,只有当beg==now的时候,flag会被设置并显示,然后到下面k可能还会变化,那么这个被设定的初始flag可能就是我们要拿到的flag了。

也即当前的系统时间除以1000,再加上200000。继续看onCreate:

最先留意的是

this.val$tv2.setText(“alictf{” + MainActivity.this.stringFromJNI2(MainActivity.this.k) + “}”);

可以看出,flag与k有关,而这里有个stringFromJNI2,其是一个底层的函数

继续阅读的话,你可以看到对k做了操作。

这里k,应该为由beg和now反复运算得到。不过,beg-now应为200000,所以,我们可以复制出代码运算得到k的值,然后,修改代码重新编译

总结思路:通过beg - now代入is2函数对k进行操作,200000,需要一秒一秒的操作,而我们,直接通过写代码模拟出200000的结果,找到k,然后改动k值,直接调用,就可以得到flag了。

提取关键代码计算出k的值

直接根据k的变化部分的函数进行模拟,算出进行了200000s之后的k值:

参考java-算k值.java:

Python脚本:

def is2(n):
    if(n <= 3):
        if(n > 1):
            return True
        return False
    elif(n % 2 == 0 or n % 3 == 0):
        return False
    else:
        i = 5
        while(i * i <= n):
            if (n % i == 0 or n % (i + 2) == 0):
                return False
            i += 6
    return True

k=0

for i in  range(200000,0,-1):
    k = k + 100 if is2(i) else k - 1
print(k)
           

输出k的值为1616384,下面我们需要把k值修改为这个值,然后进入进行flag设定的if语句就可拿到flag了,下面进行操作。

通过Android killer反编译

将输出flag的条件反过来,即MainActivity$1.smali里的if-gtz v0, :cond_0这句话(后面是输出The Flag Is那里的跳转)改为if-ltz v0, :cond_0

将k值改为常量,即上文提到的smali文件里的iget v3, v3 …(省略);->k:I之后添加const v3, 1616384

BugkuCTF-Reverse题Timer(阿里CTF)

就是大于改为小于,gt为大于,lt为小于,请求时间与系统时间的差值小于0才会显示flag

BugkuCTF-Reverse题Timer(阿里CTF)

插入这句话,原因是k保存在v3寄存器内,因此修改v3就能修改k

(这里的v0,v1,v2,v3等都是寄存器,添加的指令就是寄存器的赋值)

把if的判断条件进行修改

if-gtz v0, :cond_0 的意思是,如果v0>0,就跳转到:cond_0,所以把gtz改为ltz。

在alictf里面的k值后面再对k进行设定。

保存,重新编译下。

修改后生成的apk路径:

file:F:\CTF\CTF_Tool\Reverse\Android\AndroidKiller\AndroidKiller_v1.3.1\projects\file\Bin\file_killer.apk

然后在模拟器里运行就可以拿到flag了。

BugkuCTF-Reverse题Timer(阿里CTF)

注意

编译译打包程序

在编译的时候遇到以下问题

Project\res\values-v23\styles.xml:6: error: Error retrieving parent for item: No resource found that matches the given name ‘@android:style/WindowTitleBackground’.

Project\res\values-v23\styles.xml:6: error: Error retrieving parent for item: No resource found that matches the given name ‘@android:style/WindowTitleBackground’.

解决方法

解决方法

找到res/value-v23/styles.xml,把resources下的东西注释掉

找到res/value/public.xml,把所有带Base.V23的东西(两个)注释掉

继续阅读