-
-
[原创]迷雾散去 -散的有点晚
-
发表于:
2022-5-27 22:39
6309
-
题目的第一感觉是和去年的有点像,刚好去年的环境也还在,就直接上手试一试吧。没想到前面安装都正常,查看dex之类的代码也很清楚,但是调试的第一步都进不去:提示没有权限附加。而且看进程列表里面含有两个a.b.c进程,所以应该是个很典型的自己ptrace自己的反调试方法。本来一个进程调试不了也还好,关键两个进程ida都加载不了,这就奇怪了:它总不能自己相互调试吧?
经过仔细研究发现:虽然ida和ps里都只有两个进程(称为a和b吧),但事实上proc目录里还能找到个迷雾中的c进程,a和c都是zygote生成的,b是由a生成的,但是只有a和b是活动的,c中无法运行任何代码,但可以被杀死,死了后a、b、c全崩溃。而且奇怪的是我注入在a中的so,在c中有,b反而没有。常理来说,我们总能找到一个不被调试的进程,让它从源头开始一个个detach各个进程,从而可以调试初始进程。但是终究对linux了解不深,在尝试了各种方法后,终于还是放弃研究。希望出题大佬ArmVMP赛后能帮我释疑(c从何而来?为何而去?)。
本来想用ida调试zygote来挂住fork函数的,结果发现调试中的zygote无法创建app,于是小小的搭建了一下arm框架下的hook框架,因为平时不接触arm,对其指令非常不熟悉,而且linux也不像windows那样有规范的api,对于自己实现的syscall完全无能为力,所以这个框架用处不大,就不拿出来献丑了。
hook了fork函数后发现a会调用fork来生成b,此时就很方便在b中注入代码。经测试fork后a返回,b不返回,b会被c调试,但是a可以被ida调试,如果a不返回,b返回,则b会调试a,而b就可以被ida调试了。
好了,分析了这么多,还是言归正传回到做题这条路上来。ida在加载分析的时候已经发现里面有des常量了,和2021年的题目一比较就可以发现des的两个关键函数还在,而且一点变化都没有。HooK后发现,变化的仅仅只是原来用了解密key,而且现在用来加密哈希过后的name。根据运行时间和代码量判断,hash后的16字节name和输入的16字节key应该是个简单的运算关系,当时就猜测会不会是“简单的异或”,但是没有测试成功--真是被自己蠢死了,测试的时候先是输错了位数(去年的时候就吐槽过手机输这么长码很费劲),然后又发现搞错了key大小写,最后把算法抠出来后才查出来自己其实把KCTF的哈希值的后几位都抄错了。
好了,最后敲下小黑板(关键技术点来了):那就是b进程虽然被c进程调试着,但是却没有设置调试的继承权限(不知道是没有还是不能),所以只要b再fork出一个进程d,那么d具备了b的所有内在和外在,却没有被人调试!所以我们只需要让b永远sleep,直接调试d就行了(完美的是d还可以通过pipe和a通信并输出你赢了)。
最后附上一个可用的(长长的)flag:3432354538383237303738384143323436323438463944343043393831364643。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!