转载

Reversing.kr Writeup(21-25)

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

跑起来之后大概这样

Reversing.kr Writeup(21-25)

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

Action Script

Reversing.kr Writeup(21-25)

简单读了下发现是这样一个逻辑:

在第1帧里面:

Reversing.kr Writeup(21-25)

所以第1帧输入 1456 ,跳到第3帧

然后跟进第3帧:

Reversing.kr Writeup(21-25)

所以第3帧输入 25 ,跳到第4帧,

然后跟进第4帧:

Reversing.kr Writeup(21-25)

所以第4帧输入 44 ,跳到第2帧,

然后跟进第2帧:

Reversing.kr Writeup(21-25)

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

然后跟进第6帧:

Reversing.kr Writeup(21-25)

所以第6帧输入 88 ,跳到第5帧,

然后跟进第5帧:

Reversing.kr Writeup(21-25)

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

Reversing.kr Writeup(21-25)

MetroApp

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

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

Reversing.kr Writeup(21-25)

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

set-executionpolicy remotesigned
Set-ExecutionPolicy -ExecutionPolicy Unrestricted

然后证书有效期注意

Reversing.kr Writeup(21-25)

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

Reversing.kr Writeup(21-25)

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

Reversing.kr Writeup(21-25)

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

Reversing.kr Writeup(21-25)

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

Reversing.kr Writeup(21-25)

即便开头以 MERONG 开头也是wrong,说明后面还有进一步的判断,

这里用的各种 windowsxxxx 的api都是对 HSTRING 结构体操作,从多次调试来看,如下下图的前20字节:

Reversing.kr Writeup(21-25)

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

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

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

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

Reversing.kr Writeup(21-25)

对应的反编译代码如下:

Reversing.kr Writeup(21-25)

这三个都是对应的我们输入的字符串,再看看接下来这个递归式子,

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)

结果如下:

Reversing.kr Writeup(21-25)

答案也就是 D34DF4C3

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

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

CRC1

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

Multiplicative

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

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

Reversing.kr Writeup(21-25) 六种反编译器,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

原文  http://www.bendawang.site/2019/06/23/reversing_kr writeup[21-25]/
正文到此结束
Loading...