Reversing.kr Writeup(21-25)

Flash Encrypt

第一次做flash逆向的题目,不过这个题目还是比较简单的,简单搜集了一下得到了一个工具:https://github.com/jindrapetrik/jpexs-decompiler

跑起来之后大概这样

翻了下几个目录,得到几个主要的信息:

  • 这个swf有7帧,前六帧都需要输入一个数字然后摁按钮确认
  • 第七帧是答案,猜想是前六帧输对了调到第七帧出答案
  • 前六帧的按钮都有对应的处理脚本,Action Script,可读性很高

简单读了下发现是这样一个逻辑:
在第1帧里面:

所以第1帧输入1456,跳到第3帧
然后跟进第3帧:

所以第3帧输入25,跳到第4帧,
然后跟进第4帧:

所以第4帧输入44,跳到第2帧,
然后跟进第2帧:

所以第4帧输入8,跳到第6帧,关于这个spw和spwd是算最后的key的,所以可以不用管具体怎么算的,因为最后会打印答案的。
然后跟进第6帧:

所以第6帧输入88,跳到第5帧,
然后跟进第5帧:

最后输入20546,跳到最后一帧打印答案

MetroApp

做题之前先说一下环境安装过程吧,好歹折腾了快俩小时,头疼。题目的readme提示了要win8。

首先在MSDN上下镜像,我用的是这个:

起一个管理员权限的powershell,先设定可以执行ps脚本,再设定运行不受信任的用户发布的软件

set-executionpolicy remotesigned
Set-ExecutionPolicy -ExecutionPolicy Unrestricted

然后证书有效期注意

调整系统时间为2013年,之后用powershell运行ps1脚本,然后就会弹出一个框要链接服务器获取win8开发者许可证,这个时候先别点我同意,因为要连接服务器,需要把系统时间恢复回来,然后再点我同意,之后登录Microsoft账户,然后很快就弹出一个框:

然后关闭之后可能会失败,这个时候不慌,因为win8开发者许可证已经拿到了,我们把系统时间重新回到2013年,然后重新跑一次ps1脚本,然后就安装成功了:

然后查了下,这个appx后缀其实就是个皮包的zip,直接按zip解压就行了,然后看到一个MetroApp.exe,放进ida里面,搜字符串找到了判断的关键位置:

然后想着动态调试,很迷很迷,没有调过类似的,并没有经验,每次调试器附加上去之后,只要暂停,一般不过10多秒钟,程序就自动退出了,非常头疼,而且经过调试之后发现上述找到的关键位置应该是个还不够:

即便开头以MERONG开头也是wrong,说明后面还有进一步的判断,
这里用的各种windowsxxxx的api都是对HSTRING结构体操作,从多次调试来看,如下下图的前20字节:

第4-7代表HSTRING长度,第16-19字节代表实际的UTF-16的字符串的地址。

然后继续往下看代码,整个代码量太大了,而且动态调试应该是我没有掌握到方法,最多只能暂停住进程10来秒的样子,一旦超了进程就退出了。

这里要注意调试的线程是主线程,通过调用堆栈可以定位到用户空间的代码,然后搜索关键字符串例如wrong就能找到具体的代码位置,然后下断点就能调试

进过一番调试测试,终于定位到了一个奇怪的地方:

对应的反编译代码如下:

这三个都是对应的我们输入的字符串,再看看接下来这个递归式子,
v80是个计数器,在while之前被置为0,每一轮循环自加一,
v50,v51,v52都是输入。考虑到其中的字符串编码是UTF-16,每一个字符对应两个字节,所以换算一下,递归式如下:

input[i+1] = byte_4307A8[i] ^ rol(input[i] , input[i] & 7)

Readme.txt提示了说答案是大写字母+数字

那就很简单了,写个深搜直接爆破所有答案,由于不知道长度,暂时用15来爆破:

byte_4307A8=[0x77,0xAD,0x07,0x02,0xA5,0x00,0x29,0x99,0x28,0x29,0x24,0x5E,0x2E,0x2A,0x2B,0x3F,0x5B,0x5D,0x7C,0x5C,0x2D,0x7B,0x7D,0x2C,0x3A,0x3D,0x21]
v80=0
stringtable="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
ans=""
length=15

def rol(lst_int, k):
    lst=list('{:0>8}'.format(bin(lst_int)[2:]))
    tmp= lst[k:] + lst[:k]
    tmp2=int("0b"+"".join(i for i in tmp),2)
    return tmp2

def search(char,i,ans):
    print(char,i,ans)
    if i==length:
        print(ans)
        input("")
        return
    else:
        for j in stringtable:
            if ord(j) == byte_4307A8[i&7]^rol(ord(char),ord(char)&7):
                search(j,i+1,ans+j)
        return

for i in stringtable:
    search(i,0,i)

结果如下:

答案也就是D34DF4C3

虽然乱七八糟把答案整出来了,但是几个地方还是没弄懂

    1. 为什么附加到MetroAPP上一定时间之后程序会自动退出?
    1. 从结果来看,最开始的初始化CorrectWrongHSTRING明显就是幌子,但是真实的判断点及输出点哪儿?
    1. 如何正常调试MetroAPP

CRC1

最近时间实在太碎了,这类型的题先留坑,有整块时间再来看。

Multiplicative

一个2kb不到的jar文件,直接放到jd里面一看,空空如也。。。

不知道是版本还是混淆的原因,那就换一个在线反编译网站java Decompilers online


六种反编译器,JDCore出不来,但是CFR出来了,代码如下:

/*
 * Decompiled with CFR 0.139.
 */
import java.io.PrintStream;

public class JavaCrackMe {
    public static final synchronized /* bridge */ /* varargs */ strictfp /* synthetic */ void main(String ... arrstring) {
        try {
            System.out.println("Reversing.Kr CrackMe!!");
            System.out.println("-----------------------------");
            System.out.println("The idea came out of the warsaw's crackme");
            System.out.println("-----------------------------\n");
            long l = Long.decode(arrstring[0]);
            if ((l *= 26729L) == -1536092243306511225L) {
                System.out.println("Correct!");
            } else {
                System.out.println("Wrong");
            }
        }
        catch (Exception exception) {
            System.out.println("Please enter a 64bit signed int");
        }
    }
}

那就很简单了,-1536092243306511225=2**64-1536092243306511225=16910651830403040391

但是16910651830403040391/26729不能整除,考虑到无符号long型的数据最大为2**64-1,那就多叠加几个2**64如下:

for i in range(10000000):
    if (-1536092243306511225+2**64+i*2**64)%26729==0:
        print((-1536092243306511225+2**64+i*2**64)//26729)
        print(2**64-(-1536092243306511225+2**64+i*2**64)//26729)
        exit()

得到结果9468659231510783855,但是被说不是64bit signed int,那就转换成负数-(2**64-9468659231510783855)=8978084842198767761,

最终答案就是-8978084842198767761

CRC2

同留坑