看雪CTF.TSRC 2018 团队赛 第四题 『盗梦空间』 解题思路

发布日期:2021-11-01 11:22    点击次数:72

截至今日(12月9日)中午12: 00,《盗梦空间》空的攻击时间停止,五支队伍成功出击!

从下图可以看出,中午哭闹搬砖的狗继续排在第一位,其次是泰肯斯、金作寿和匹萨曲。A2首次脱颖而出,跻身前五。

最新赛况战况一览最新事件的摘要。

在标题《盗梦空间》空,团队中午放标题,搬砖狗哭,以50850s的速度拿下第一名!

第四次进攻后,进攻队的Top10也发生了很大的变化。最新排名如下:

似乎要保持前十的排名需要相当的技巧。

同时也意味着任何一支球队都可能是黑马。

下一匹黑马会是你吗?

第四题 点评

无冠:

《盗梦空间》空之间的主程序采用了很多让人迷惑的方式:持续致盲、垃圾指令、空循环、跳转到计算地址、自修改代码,让我们无法只用一个工具来分析程序,同时考验选手的动态调试和静态分析的技巧。

第四题 出题团队简介

话题团队:雨落星辰沉。

安全业余爱好者前几年玩dota的时候经常会遇到全图挂的情况,在好奇心的驱使下,在网上寻找全图挂的原理。由此,我来到了观雪论坛,被论坛中精彩的底层计算机技术所吸引。但由于缺乏系统训练,知识结构分散,水平徘徊在入门边缘。一年前,接触过它的观雪CTF觉得实战是提升水平的捷径,于是成了CTF的常客。

队里的其他人都是CTF的大牌,有的做过CTF的入门视频教程,有的还在CTF个人排名前十。在团队中,希望互相交流技术,向老板们学习。

比赛的标题被我命名为变形金刚,主要是因为它使用了一些代码混淆技术,比如变形金刚。它还借鉴了《变形金刚》中的一句经典台词,“一个会站,一个会倒。”。不过题目有点仓促,从构思到实现大概用了10天。最终,他在参赛选手手中只存活了10多个小时。如果以后有机会参加比赛,就要全面提升迷惑的强度。

第四题 设计思路

主要设计思路:主要设计思想:

首先,在主函数之前手动修补vc运行时库,并添加反调试代码。如果找不到调试器,请自我修补并跳转到正确的验证位置。否则,我们将陷入无法解决的死胡同。

二是修改TEA算法的流程,混淆编译后的机器码,以内联汇编的形式生成C语言文件。

混淆过程:

1.处理函数的开始和结束,并推送ebpMov ebp,尤指逃生。

2.逃避一些关键指令(shr,shl)。

3.用常量生成器替换出现的常量。

4.花卉说明。

5.去调试。

6.延迟(防止爆破)。

7.跳跃混乱。

8.随机自解密。

附件中的其他文件:

原始操作码:

混淆前修改过的tea加密机器码。

gen_asm_c.py:

混淆代码

tea_asm.c:

混乱的c源代码的修改_tea_encrypt(内联汇编形式)。

候选人. txt:

花卉指令文件

tea_encrypt.c:

修改后的tea加密源代码。

tea_decrypt.c:

修改后的tea解密源代码。

解决方法:

1.编写一个去混淆脚本,并编写modified_tea_decrypt函数。

2.去掉反调试,找到真正的验证逻辑。

的真正验证逻辑是:

char *key =“一个会站,一个会倒。”;

modified_tea_encrypt(arr,(uint*)密钥,0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,(uint*)M1,0x deadbeef);

返回(arr[0]= = 0x 87654321 & & arr[1]= = 0x 12345678);

混淆后写modified_tea_decrypt()。

char *key =“一个会站,一个会倒。”;

arr[0]= = 0x 87654321;

arr[1]= = 0x 12345678;

modified_tea_decrypt(arr,(uint*)密钥,0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,(uint*)M1,0x deadbeef);

此时,bin2hex(arr)是正确的验证码。

原文完整链接:

bbs.pediy.com/thread-247772.htm

第四题 盗梦空间 解题思路

这个话题的分析最初还是由一个看雪的论坛Riatre创建的。

周末,我有一点时间,尽可能详细地写了我的解题过程。看起来很长,但实际上并不复杂。希望你不会害怕。

当然,我猜想其他人也不会用迷惑的方式去做,他们的方法可能值得那些寻求心灵平静和努力的人学习:)。

为了照顾写作逻辑,下面贴的代码可能不完整。完整代码见附件。同时代码有很多调试痕迹,比较乱。看看就知道了。

观察

标题(再次)给出了一个32位控制台Windows应用程序transformer.exe,它有824 KB。

运行它:

n:pedi 4 > transformer . exe

请输入您的序列号:0123456789ABCDEF

错误的序列号!你应该再努力一点!

请按任意键继续。

好像是经典的输入序号输出对错题。请注意,在输入和输出之间有大约1秒的停顿。

初步分析

在IDA Pro中加载可执行文件后,很容易定位到00401AF0作为主要功能:

int main(int argc, const char *argv[]) {printf("Plz input your serial:");scanf("2s", serial);if ( CheckSerial(serial) )printf("Congratulations! You have found the correct serial!n");elseprintf("Wrong serial! You should try a bit harder!n");system("pause");return 0;}

被调用的CheckSerial函数位于00401150,其(表观)逻辑大致如下:

BOOL CheckSerial(char *serial) {int block[2] = {0};if ( strlen(serial) != 16 )return 0;for ( i = 0; i 9 ')& &(serial[I] ' F ')返回0;}for(I = 0;I ' 9 ')块[0] += (serial[i] - '7') %d,忽略...% (a,s,v)对于nop_range中的l,r:PE . set _ bytes _ at _ RVA(l-0x 400000,X90 ' *(r-l+1))PE . write(' transformer-deo BF-1 . exe ')原本是准备手动处理之前没有暴露的问题(比如条件跳转指令),但是运行之后却意外发现看似混乱的函数中真的没有正常的代码。

在调试器中观察要去混淆的函数的输出,发现在去混淆之前都是一样的,说明这一步是OK的。

不幸的是,这样做之后,我们发现代码仍然很难直接用Hex-ray理解。由于堆栈帧分析不正确,Hex-ray很难识别函数参数和局部变量,并在此基础上合理剔除死代码。稍微观察一下,发现这个函数使用ebp作为帧指针。我们在IDA Pro中按Alt+P编辑功能,选择基于BP的框架进行尝试:

.text:00401C70 ; Attributes: bp-based frame.text:00401C70.text:00401C70 sub_401C70 proc near ; CODE XREF: sub_401150+560↑p.text:00401C70.text:00401C70 var_7FB3C458 = dword ptr -7FB3C458h.text:00401C70 var_7F802E58 = dword ptr -7F802E58h.text:00401C70 var_7F5D631E = dword ptr -7F5D631Eh.text:00401C70 var_7F22FF9C = dword ptr -7F22FF9Ch.text:00401C70 var_7E66DBE5 = dword ptr -7E66DBE5h.text:00401C70 var_7E5C5872 = dword ptr -7E5C5872h.text:00401C70 var_7E36A138 = dword ptr -7E36A138h遗憾的是,由于Hex-ray依赖IDA Pro本体进行栈帧分析,而IDA Pro本体不是编译器,没有常量折叠等功能,以下常量blinding access函数参数的代码被成功识别错误:

.text:00401C73 mov edi, 0B3692C58h.text:00401C78 sub edi, 15A8B117h.text:00401C7E sub edi, 8B85C52Ch.text:00401C84 mov ecx, [ebp+edi*2+var_24756C32] ; mov ecx, [ebp+edi*2-24756C32h]

似乎我们必须手动消除此类说明中的混乱。请注意,此类指令的形式相对简单。既然我们已经模拟了这个程序,那么在执行这样的指令时,我们不妨手动改变被发现是常量的寄存器的值:(如果一开始只使用了一个带有符号执行的静态分析框架,在这里可以写得更加健壮,我们可以通过查看符号执行的结果直接判断ebp添加的值是否是常量);

from capstone import *from keystone import *stack_access_simplify_candidates = collections.defaultdict(lambda: [])def hook_code_simplify(uc, address, size, user_data):instr = next(cs.disasm(instr, address))ops = instr.op_strif '[ebp + edi' in ops:pants = ops[ops.find('[')+1:ops.find(']')]val = eval(pants, {'ebp': 0, 'edi': uc.reg_read(UC_X86_REG_EDI)}) % 2**32stack_access_simplify_candidates[address].append((instr.mnemonic, ops, pants, val, size))uc.hook_add(UC_HOOK_CODE, hook_code_simplify)# ...for addr, vec in stack_access_simplify_candidates.items():if len(vec) != 1:print 'Non constant stack access @ x, ignoring...' % (addr)continuemnem, ops, pants, val, size = vec[0]new = 'ebp 'if val 大小:打印“空间不足@ x,正在跳过...”% addrcontinuePE . set _ bytes _ at _ RVA(addr-0x 400000,enc.ljust(size,X90 ')#...除了函数末尾的一个0045BFC5的手动ret没有被识别出来,需要手动修复之外,这样得到的程序IDA Pro最终可以正确分析栈帧。六角射线也可以正常得到结果:

然而,我们惊讶地发现,Hex-ray的优化器没有简化连续的ror/rol,这使得结果非常难看。解决这个问题的正常方法,当然是使用7.1版以上新增加的微码API,为Hex-ray编写一个新的优化的pass,从而简化这些事情。但是人总是懒的,Hex-ray输出的代码几乎都是可编译的C代码,我们不妨把结果修改成GCC进行可编译,然后扔进GCC试试看O2怎么优化。顺便说一下,我们可以把这里的参数传入的所有常数都写死。(更多更好的. cpp见附件)。

$ g++ -ggdb -O2更好. cpp

$

通过六边形射线分析获得的结果出人意料地好:

你已经可以看到费斯特密码的明显结构了。

解决

Feistel密码是一种只要看到结构就可以解密的东西,不需要每次操作都反向。复制上面的代码,稍微整理一下,然后背诵一句口头禅:

您可以解密它。

调试隐藏在哪里?

仔细看,可以发现程序修改了初始化栈cookie相关的函数,增加了对反调试函数00490F70的调用。这个功能中有一些比较混乱的花指令,但是都是相同的固定模式,可以直接替换。

检测调试器的方法是调用。

ntqueryformationprocess(GetCurrentProcess()、ProcessDebugObjectHandle、...)。

也就是说,其实loadlibrary+getprocaddress ntdll.dll中所有函数的长链大概就是隐藏字符串NtQueryInformationProcess,这样就不那么显眼了,从而使得反调试代码不那么显眼...

琐事

1.为了阅读方便,以上不是我实际阅读题目时看到的顺序写的。实际发生的情况是:标记完看似部分->第二部分的不可解部分我很疑惑->我以为函数中隐藏了什么可能会被混淆的东西->我还原了代码,发现里面没有什么特别的。对了,我写了第一部分的解密->挠头几分钟->在关键逻辑处看到一些奇怪的无用指令->调试器附加了一个已经检查完毕等待的系统(“暂停”)。

2.这种躲猫猫式的反调试,在没有检测到调试器的情况下默默修改代码是很可怕的,尤其是对于像我这样不喜欢用高端神秘魔改“过测”调试器的各位高手之手,却喜欢直接看代码的人来说。

3.但从其低调的行为和隐藏的位置来看,确实很有意思。

4.第一个真正工作的代码前没有反调试+SMC,最后一个真正工作的代码后有(00462FE2)。我想知道书写是否有问题...

抱怨

独角兽引擎的文档基本没有,用起来真的很头疼。我应该知道使用另一个...

原始链接:bbs.pediy.com/thread-248285.htm(包括附件)

合作伙伴

腾讯安全应急中心。

腾讯安全先锋TSRC负责发现和处理腾讯的安全漏洞和黑客攻击。这是一个没有硝烟的战场,我们与2万多名安全专家并肩同行,共同捍卫全球数亿用户的信息和财产安全。一直以来,我们怀着感恩的心,努力打造一个开放的TSRC交流平台,回馈平安社区。未来,我们将继续携手安全行业精英,探索互联网安全新方向,构建互联网安全生态,开创“互联网+”新时代。

Http://weixin.qq.com/r/H3VudjvE02asrX8V9yAN(二维码自动识别)

请注意:从薛雪学院转学。

看雪CTF。TSRC 2018团体赛解题思路总结:。

看雪CTF。TSRC 2018年团体赛,第一题,“世纪初”。

看雪CTF。TSRC 2018年团体赛,第二题“半加法器”。

看到薛。TSRC 2018团体赛的第三题“七十二疑”。

看雪CTF。TSRC 2018年团体赛第四题,“盗梦空房”。

看到薛。TSRC 2018年团体赛,第五题《交响乐》。

看看雪CTF。TSRC 2018年团体赛,第六题,“追兵也在”,解决问题。

看看雪CTF。TSRC 2018年团体赛,第七题,“魔法森林”。

看看雪CTF。TSRC 2018年团体赛,第八题,“双向陪衬”。

看看雪CTF。TSRC 2018年团体赛,第九题《谍战》。

看到薛。TSRC 2018年团体赛,第十题,“侠义双雄”。