首页
社区
课程
招聘
[原创]KCTF2021秋季赛第8题 群狼环伺
2021-12-6 02:55 19337

[原创]KCTF2021秋季赛第8题 群狼环伺

2021-12-6 02:55
19337

IDA上来一看,没啥函数

 

图片描述

 

找一下密码学常量,发现有个DES

 

图片描述

 

查找引用

 

图片描述

 

发现有部分函数没有识别,手动Create Function

 

sub_788就是DES过程了,hook下打印三个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Interceptor.attach(baseAddr.add(0x789),{
    onEnter: function (args)
    {
        console.log((this.context as any).lr.sub(baseAddr));
        console.log(JSON.stringify(this.context));
 
        console.log(hexdump((this.context as any).r0,{
            offset:0,
            length:128*3,
            header:true,
            ansi:true
        }));
        //Enc Data
        console.log(hexdump((this.context as any).r1,{
            offset:0,
            length:8,
            header:true,
            ansi:true
        }));
    },
    onLeave: function (ret)
    {
        //After Enc
        console.log(hexdump((this.context as any).r2,{
            offset:0,
            length:8,
            header:true,
            ansi:true
        }));
    }
});

可以看到将输入转成hex再转hex后,加密了一次,随后是加密相同的内容

 

图片描述

 

这里可以将DES轮秘钥倒过来,解密

1
2
3
4
5
6
7
8
9
function swapkey(addr:NativePointer){
    var key = []
    for(var i = 0;i<48;i+=1){
        key.push(addr.add(i*8).readU64());
    }
    for(var i = 0;i<48;i+=1){
        addr.add(i*8).writeU64(key[47-i]);
    }
}

当提交成功时,会出现"恭喜成功",但是在java层代码和native层代码没有找到这个字符串,这里无意尝试把以下内容修改了

 

图片描述

 

程序崩溃,查看logcat

 

图片描述

 

UTF-8转换相关,hook下libart.so的CheckJNI::NewStringUTF(dump自己的so文件,ida找一下这个函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Interceptor.attach(baseAddr.add(0xae765),
    {
        onEnter: function (args)
        {
 
            //console.log(args[1].readCString(),args[1]);
            if(args[1].readCString() == "恭喜成功" || args[1].readCString() == "输入错误"){
                var mainAddr = Module.findBaseAddress("libcrackme.so");
                console.log((this.context as any).lr.sub(mainAddr));
                for(var i=0;i<64;i++){
                    //console.log((this.context as any).sp.add(i*4).readPointer(),(this.context as any).sp.add(i*4).readPointer().sub(mainAddr));
                }
 
                console.log(hexdump(args[1]));
                console.log(JSON.stringify(this.context));
                console.log(hexdump(this.context.sp.add(0xB0),{
                    offset:0,
                    length:192,
                    header:true,
                    ansi:true
                }));
                debugger;
            }
        },
        onLeave: function (ret)
        {
 
        }
    }
);

这样可以在判断完结果后将程序断下(frida的debugger命中会暂停当前线程)

 

搜一下正确输入的加密结果,运行程序时保持name相同,serial不同

 

bd 3a b0 69 39 40 f8 cd 42 0d e3 8a 79 db 52 bd

 

找到一个

 

图片描述

 

运行程序时保持name不同(这里输入KCTF),serial相同

 

同样也找到一个

 

图片描述

 

这时就能猜出DES加密结果应该为

 

45 68 97 A3 29 2A 7F D4 F5 90 73 57 46 02 AE D5

 

就可以得到正确答案了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(true){
    //DES Decrypt
    swapkey((this.context as any).r0);
    //Data 1
    if((this.context as any).lr.sub(baseAddr) == 0xe8b5){
        var encdata = [0x45,0x68,0x97,0xa3,0x29,0x2a,0x7f,0xd4];
        (this.context as any).r1.writeByteArray(encdata);
    }
    //Data 2
    if((this.context as any).lr.sub(baseAddr) == 0xe8e5){
        var encdata = [0xf5,0x90,0x73,0x57,0x46,0x02,0xae,0xd5];
        swapkey((this.context as any).r0);//Swap Again
        (this.context as any).r1.writeByteArray(encdata);
    }
}

图片描述

 

应该输入的hex 为 63 8f 67 73 59 3b d9 1d 78 8e 89 1e 6c f4 2e fa

 

再转换一次 3633386636373733353933626439316437383865383931653663663432656661,即为正确答案

 

部分代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
function swapkey(addr:NativePointer){
    var key = []
    for(var i = 0;i<48;i+=1){
        key.push(addr.add(i*8).readU64());
    }
    for(var i = 0;i<48;i+=1){
        addr.add(i*8).writeU64(key[47-i]);
    }
}
 
function hook(){
    var baseAddr = Module.findBaseAddress("libcrackme.so");
    Interceptor.attach(baseAddr.add(0x789),
        {
            onEnter: function (args)
            {
                console.log((this.context as any).lr.sub(baseAddr));
                //console.log(JSON.stringify(this.context));
 
                // console.log(hexdump((this.context as any).r0,{
                //     offset:0,
                //     length:128*3,
                //     header:true,
                //     ansi:true
                // }));
                if(true){
                    //DES Decrypt
                    swapkey((this.context as any).r0);
                    //Data 1
                    if((this.context as any).lr.sub(baseAddr) == 0xe8b5){
                        var encdata = [0x45,0x68,0x97,0xa3,0x29,0x2a,0x7f,0xd4];
                        (this.context as any).r1.writeByteArray(encdata);
                    }
                    //Data 2
                    if((this.context as any).lr.sub(baseAddr) == 0xe8e5){
                        var encdata = [0xf5,0x90,0x73,0x57,0x46,0x02,0xae,0xd5];
                        swapkey((this.context as any).r0);//Swap Again
                        (this.context as any).r1.writeByteArray(encdata);
                    }
                }
                //Enc Data
                console.log(hexdump((this.context as any).r1,{
                    offset:0,
                    length:8,
                    header:true,
                    ansi:true
                }));
            },
            onLeave: function (ret)
            {
                //After Enc
                console.log(hexdump((this.context as any).r2,{
                    offset:0,
                    length:8,
                    header:true,
                    ansi:true
                }));
            }
        }
    );
}
 
function hookart(){
    var baseAddr = Module.findBaseAddress("/system/lib/libart.so");
    //var baseAddr = Module.findExportByName(null,"_ZN3art12_GLOBAL__N_18CheckJNI12NewStringUTFEP7_JNIEnvPKc");
    console.log("Art",baseAddr)
    Interceptor.attach(baseAddr.add(0xae765),
        {
            onEnter: function (args)
            {
 
                //console.log(args[1].readCString(),args[1]);
                if(args[1].readCString() == "恭喜成功" || args[1].readCString() == "输入错误"){
                    var mainAddr = Module.findBaseAddress("libcrackme.so");
                    console.log((this.context as any).lr.sub(mainAddr));
                    for(var i=0;i<64;i++){
                        //console.log((this.context as any).sp.add(i*4).readPointer(),(this.context as any).sp.add(i*4).readPointer().sub(mainAddr));
                    }
                    console.log(hexdump(args[1]));
                    console.log(JSON.stringify(this.context));
                    console.log(hexdump(this.context.sp.add(0xB0),{
                        offset:0,
                        length:192,
                        header:true,
                        ansi:true
                    }));
                    debugger;
                }
            },
            onLeave: function (ret)
            {
 
            }
        }
    );
}

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回