[NCTF 2023] Re
中文编程1
载入x64dbg,注意到一堆浮点运算,果断载入IDA。
由于易语言中的整数操作,全部都是拿浮点数进行的,所以这里直接大胆假设为整数,进行计算。
唯一坑人的地方在于,有一个数字,xxxx.e11,.e11去掉后是错误的,因为少了个0,这个卡了很久。
有11组DWORD,每一组都是flag的ASCII码拼接而成,用z3进行爆破,最后还原就行。
Jvav
先拖入jadx,发现混淆直接给jadx干爆了,然后拖入GDA,发现同样被干爆。最后拖入JByteMod中,发现成功读取,也不需要进行反混淆,效果如图:
然后在Idea里面新建一个项目,手动拷贝(由于部分解密函数有调用栈检测,所以不好扣出来)
进行了一会人工反混淆后,注意flag判断:(var4是用户输入的东西异或51的结果)
if(ALLATORIxDEMO(var4).equals("😉😶😌😕😃😀😃😄😉😂🙂😀🤐😂🤗☹️🤗😐🤗😱😃🤣😀😘😐😄😔😄😃🤣🤨😋🤐😑😌🙂🤗😂😌🤐😃😀🤨😄🤗🤨🙂🤐😉🤩😔😘😐🙂😛😍😤😘😌😚😗🤩😧🤗"));
那么前面的这个ALLATORIxDEMO一定就是关键函数。通过更改输入,发现这个函数对于一个字符的输入可能会引起1-2个emoji的变化。我这里采用了爆破的方法:
这个函数返回加密后的flag和真正加密后flag的相似度(字符匹配,如果相同位置一样则++)
然后通过一个函数进行爆破
输入测试,发现是错的,但是大致雏形已经有了。
然后进行更精细化的爆破
通过手动修改,每四个进行爆破,逐个敲出(时间复杂度$O(n^4)$),最后得到了flag:
flag{a973b923-68bf-430f-b42a-a7a1472bcb49}(本题用时2小时)
比赛结束后听别人说,这是base64改的,直接爆了。
ezVM
拖入x64dbg和IDA进行对比,注意到有upx壳,所以直接upx -d,然后继续进行分析。拖入IDA后,发现
但是其实F5后,VM的架构已经很清晰了。我们只需要拿到vm字节码,然后进行自动化或者手动分析即可。
经过一段时间的F8单步跑后,注意到vm中许多指令并没有用,switch中直接走了default路径;但是这对我们的静态分析是比较困难的。我们其实可以直接从gets_s开始分析。
方法一、由于动态调试x64dbg的方便性,我们可以采用对输入的东西进行内存软件/硬件断点,然后逐个追踪并分析,逐字节拿到flag,而且我们也知道flag长度是44,且格式为flag{.?},这个方法虽然很慢,但是能保证做出来。
方法二、静态对字节码进行分析,注意到
实际上是从字节码下一位拿到一个值,并把它推入vStack上,我们记作vmLdImm8
这个是从栈上拿到一个值(offset)和一个指针ptr,进行寻址并push到栈上
这两个其实完成了从某个地址拿数据的操作。注意到vm里面其实一直在进行这样的操作,且input handler会push buffer的地址
如此以来,对于VM的数据读入,我们就可以对其字节码进行正则匹配或者是python中自动处理,而且我们无需管垃圾指令。数据拿到以后,我们需要继续分析VM。发现VM其实是在对数据进行xor操作并在最后判断是否为0,而且每个xor指令中都没有掺入垃圾指令,这在VM的字节码中重复率很高,非常显眼,而且没组相同数据之前都有一个vmLdImm8, imm的形式,记录下来每一个立即数,在最后即可还原flag。
不过在还原xor的时候,还需要用到一些万用门的知识(实际上可以才出来是xor)
最后得到Flag:flag{O1SC_VM_1s_h4rd_to_r3v3rs3_#a78abffaa#}
评论已关闭