首页
论坛
课程
招聘
[原创]2022KCTF春季赛 第八题 迷雾散去
2022-5-28 02:26 3899

[原创]2022KCTF春季赛 第八题 迷雾散去

2022-5-28 02:26
3899

程序用了ptrace,防止调试程序,这样IDA,CheatEngine都是用不了的,不过还是可以用scanmem(https://github.com/scanmem/scanmem)读取内存查看内存信息(需要自行编译+改部分代码,此处略过)

 

程序最后会有 "顺利通关" 字样,找到相关内存并dump
图片描述
dump出附近内存,用作对比,没啥想法

 

ida查算法特征,发现有个des,算法和上次比赛的代码差不多,可以hook
frida hook后发现没有输出,写个debugger发现程序停住,说明frida 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
mylogfile = new File("/data/data/a.b.c/d1.txt","wb");
Interceptor.attach(baseAddr.add(0x4d15),{
    onEnter:function(args){
        var mylog = "";
        mylog += "DES Enc:" + (this.context as any).lr.sub(baseAddr) + "\n";
        // mylog += JSON.stringify(this.context) +"\n";
        // mylog += (this.context as any).lr.sub(baseAddr) + "\n";
        // // mylog += hexdump(args[0],{
        // //     offset:0,
        // //     length:0x100,
        // //     header:true,
        // //     ansi:true
        // // })
        // // mylog+="\n";
        // mylog += hexdump(args[1],{
        //     offset:0,
        //     length:0x10,
        //     header:true,
        //     ansi:true
        // })
        // mylog+="\n";
        // mylog += hexdump(args[2],{
        //     offset:0,
        //     length:0x10,
        //     header:true,
        //     ansi:true
        // })
        // mylog+="\n";
        mylogfile.write(mylog);
        mylogfile.flush();
    },onLeave:function(ret){
        var mylog = "";
        mylog += "After DES Enc:" + (this.context as any).lr.sub(baseAddr) + "\n";
        // mylog += JSON.stringify(this.context) +"\n";
        // mylog += hexdump((this.context as any).r2,{
        //     offset:0,
        //     length:0x10,
        //     header:true,
        //     ansi:true
        // })
        // mylog+="\n";
        mylogfile.write(mylog);
        mylogfile.flush();
        count+=1
        if(count==2){
            //debugger;
        }
    }
});

找出返回地址0xe409,观察发现vmp代码有点相似结构 44 f0 0d e5 ? ? 00 ea,ghidra强制识别这些arm代码试试

1
2
3
4
5
6
7
8
f=open("libcrackme.so","rb")
data = f.read()
f.close()
 
result = 0
while(result != -1):
    result = data.find(bytearray.fromhex("44 F0 0D E5"),result+4)
    print(hex(result+0x1000))

图片描述
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
32
33
34
35
36
37
38
39
40
41
function hookart(){
    var baseAddr = Module.findBaseAddress("/apex/com.android.runtime/lib/libart.so");
    //var baseAddr = Module.findExportByName(null,"_ZN3art12_GLOBAL__N_18CheckJNI12NewStringUTFEP7_JNIEnvPKc");
    console.log("Art",baseAddr)
    Interceptor.attach(baseAddr.add(0x2C85D1),
        {
            onEnter: function (args)
            {
                if(args[1].readCString() == "您输错了" || args[1].readCString() == "顺利过关"){
                    console.log(args[1].readCString(),args[1]);
                    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].add(0xe0),{
                        offset:0,
                        length:128,
                        header:true,
                        ansi:true
                    }));
                    console.log(JSON.stringify(this.context));
                    console.log(hexdump(this.context.sp.sub(0),{
                        offset:0,
                        length:128,
                        header:true,
                        ansi:true
                    }));
                    memset_log = false;
                    mylogfile.close();
                    //debugger;
                }
            },
            onLeave: function (ret)
            {
 
            }
        }
    );
}

图片描述
计算下最后输出字符串位置返回是14664
图片描述
去hook vmp函数找一下,hook后再运行会崩溃,不过能输出寄存器信息,也能暂停程序留出dump内存的机会

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Interceptor.attach(baseAddr.add(0xf628),{
    onEnter:function(args){
        if(true || (this.context as any).sp.sub(0x44).readPointer().sub(baseAddr) == ptr(0x145e8)){
            var mylog = "";
            mylog += (this.context as any).sp.sub(0x44).readPointer().sub(baseAddr) + " Result " + (this.context as any).lr.sub(baseAddr) +"\n";
            mylog += JSON.stringify(this.context)+"\n";
            // mylog += hexdump((this.context as any).r3,{
            //     offset:0,
            //     length:(this.context as any).r0.sub((this.context as any).r3).toUInt32(),
            //     header:true,
            //     ansi:true
            // })
            mylog+="\n";
            console.warn("!!  ",JSON.stringify(this.context))
            mylogfile.write(mylog);
            mylogfile.flush();
            debugger;
        }
    },onLeave:function(ret){
 
    }
});

附近hook函数找了一下,没有找到判定条件,不过能确定正确输入会有0xc,不正确的输入则是0x0

 

去跟des算法,发现是加密用户名的,和序列号没啥关系,发现走到后面,程序没有断下
图片描述
发现1e48c 跳转到xref较少的地方
图片描述
图片描述
一个个试,发现找到一个地方正好是卡在des加密后,得出判断结果前,且正好有返回结果为0xc
图片描述
观察也可以发现有个循环结构,多次尝试hook输出信息,根据寄存器信息和dump出的内存猜出xor
图片描述
KCTF对应序列号为3432354538383237303738384143323436323438463944343043393831364643


看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

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