【CTF】Reverse Writeup TracerPid反调试,BUG()内核异常 2022长城杯决赛 逆向学习

CTF · 2022-09-27 · 997 人浏览

前言

长城杯决赛的逆向题目 感觉还是有点意思的 这种读TracerPid的反调试和BUG()内核异常跳转以前没见过 比赛的时候疯狂搜索 也没个解决办法,后来是自己试着调试调试把这个反调试过掉了 然后大概摸清楚了题目的运行逻辑。总的来说这题还是很有趣的。直接看题吧

easy_re

首先我们拿到题目,进来是start函数,这边可以看到main,init

image-20220906132259169

点进去init可以发现加载了三个函数,依次点进去看

image-20220906132335039

image-20220906132515957

第一个是一些奇怪的操作,但是可以看到一个函数,这个是检测反调试的

第二个是一个TracerPid反调试加BUG()异常

image-20220906132616562

第三个不知道是啥玩意,感觉没啥用

经过动态调试,f8断点可以发现程序是先执行init for循环里面的第一个函数,第二个函数,第一个函数里面的那个函数。我们过反调试也很简单,只要在这个位置断点,然后点进cmp左边的,按dddd把里面第一行的pid数字改成0即可

image-20220906133004796

然后进入到第一个函数里面的那个函数,这个其实是检测反调试的,之前被卡在这里卡了好久,一直不懂他是怎么传参的,后面发现其实是和之前运行的那个反调试有关系。把反调试过了之后也就进入主函数正常执行了。

不过这底下有个函数需要注意,这个是init替换的主函数,实际上这个函数是当成main执行的。

image-20220906133338043

点进去看,可以发现

image-20220906133448800

有一堆东西,仔细观察汇编可以发现,对用户输入前四位和一些变量进行操作,最后要使得前四个变量值为0,最后可以得到flag。那我们直接用c爆破前四位输入

#include<stdio.h>

int main(){
    int inp[4];
            for (int i=30;i<127;i++){
                for (int j=30;j<127;j++){
                    for (int m=30;m<127;m++){
                        for (int n=30;n<127;n++){
                            inp[0]=i;
                            inp[1]=j;
                            inp[2]=m;
                            inp[3]=n;

                            int dword_5611F8803040=0;
                            int dword_5611F880303C=0;
                            int dword_5611F8803030=0;
                            int dword_5611F8803034=0;
                            int dword_5611F8803038=0;
                            dword_5611F8803040 += 16;
                            dword_5611F880303C += dword_5611F8803040 * inp[3];
                            dword_5611F8803040 += 3;
                            dword_5611F880303C += dword_5611F8803040 * inp[2];
                            dword_5611F8803040 -= 10;
                            dword_5611F8803030 += dword_5611F8803040 * inp[3];
                            dword_5611F8803040 -= 2;
                            dword_5611F8803034 += dword_5611F8803040 * inp[2];
                            dword_5611F8803040 += 13;
                            dword_5611F8803030 += dword_5611F8803040 * inp[1];
                            dword_5611F8803040 -= 8;
                            dword_5611F8803038 += dword_5611F8803040 * inp[1];
                            dword_5611F8803040 -= 7;
                            dword_5611F8803038 -= 3481;
                            dword_5611F8803040 += 3;
                            dword_5611F8803034 -= 2422;
                            dword_5611F8803040 += 9;
                            dword_5611F8803030 += dword_5611F8803040 * inp[2];
                            dword_5611F8803040 -= 2;
                            dword_5611F8803038 += dword_5611F8803040 * inp[2];
                            dword_5611F8803040 -= 6;
                            dword_5611F8803030 -= 4518;
                            dword_5611F8803040 += 7;
                            dword_5611F880303C -= 5006;
                            dword_5611F8803040 -= 9;
                            dword_5611F8803034 += dword_5611F8803040 * inp[0];
                            dword_5611F8803040 += 5;
                            dword_5611F8803030 += dword_5611F8803040 * inp[0];
                            dword_5611F8803038 += ++dword_5611F8803040 * inp[0];
                            dword_5611F8803040 -= 8;
                            dword_5611F8803038 += dword_5611F8803040 * inp[3];
                            dword_5611F8803040 += 14;
                            dword_5611F880303C += dword_5611F8803040 * inp[0];
                            dword_5611F8803040 -= 11;
                            dword_5611F8803034 += dword_5611F8803040 * inp[3];
                            dword_5611F8803040 += 3;
                            dword_5611F880303C += dword_5611F8803040 * inp[1];
                            dword_5611F8803040 -= 2;
                            dword_5611F8803034 += dword_5611F8803040 * inp[1];

                            if(dword_5611F8803030==0 && dword_5611F8803034==0 && dword_5611F8803038==0 && dword_5611F880303C==0){
                                printf("%c   %c   %c   %c",i,j,m,n);
                                break;
                            }
                        }
                    }
                }
            }
}

可以得到前四位flag,然后下面是根据前四位和之前v27的密文进行异或得到后面的flag

image-20220906133736368

s=[0x0064, 0x0010, 0x007C, 0x007C, 0x0022, 0x0017, 0x002F, 0x0034, 0x0013, 0x0013, 0x000B, 0x003B, 0x001F, 0x001B, 0x000F, 0x0000, 0x001E, 0x0005, 0x0072, 0x003C, 0x0062, 0x001F, 0x0036, 0x0004, 0x001F, 0x002E, 0x0032, 0x003F]
print(len(s))
input='QTEM'
flag=''

for i in range(len(s)):
    flag += chr(s[* i] ^ ord(input[i % 4]))
print(flag)
'QTEM5D91sCjyBGNvNOJMOQ7q3KsINzwr'

得到最终flag

总结

长城杯这次决赛就做了两题 其他方向还是不太会 但是我们团队得分应该是非常靠前的(有niyah大爹排第二)题目还是做慢了,动态调试技巧还需要提升。

RE
  1. 您好~我是腾讯云开发者社区运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan
    作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器等,另外还有些周边礼物。 ヾ(≧∇≦*)ゝ

Theme Jasmine by Kent Liao