2023XHLJ-RE
2023XHLJ-RE
😭 题目难度适中,着重是对技巧的考察,可惜手生了,有题浪费的时间比较久,赛时没能AK。
注: 部分知识点仅针对题目浅显学习,如有严重错误敬请师傅们指正,不剩感激。
Dual personality
core: 通过hook从32位切换到64位执行,期间穿插反调试代码。
hook切换函数
获取调用该函数的返回地址,将该处7个字节的指令转存到va开辟的空间中,并在其中通过0xE9+偏移回到retaddr+size的地址继续执行。原本ret处的代码被修改为jmp 0x33切换64位模式,一共有两处调用,可在该函数下断点获取64位代码地址。
1 |
|
复制一份文件,将可选头的Magic选为PE64(0x20B),之后IDA64打开即可查看x4011d0和0x401290处的反汇编代码。
1 |
|
用过gs:60获取PEB,并通过+2查看BeingDebug,并将反调试标志存在0x40705C地址(可在原32位文件中查看该偏移处的变量),并将后续0x407058( dword_407058)的初始值设置为0x5DF966AEh,之后jmp到刚刚保存的现场,进而跳转到原retaddr+Size处执行。
之后会调用0x40705c处代码处理数据,并使用了刚刚的反调试标志。
1 |
|
偏移0x1290处的代码负责修改最后异或的数据,可通过调试获取异或值,并设置了check出的指令地址0x4014C5,数据均可调试32位程序获取,断点不能打在64位模式的代码,并且注意前两处处理的反调试。
exp
1 |
|
BabyRe
core: init函数和atexit函数
initterm中依次执行如下函数。
顺序如下
1 |
|
atexit函数的调用顺序为栈式,即后注册先调用,所以数据处理流程是sub_401670->sub_4014E0->sub_4014E0。
第一步是base8编码,3byte扩充为8byte,表为01234567,并且check了加密后的enc[16:112]字节即36字节的输入,加密后的前16字节参与sub_4014E0的魔改sha1运算,最后取输入的最后6个字节用RC4加密enc[:112],根据第一步的check可求中间的36字节,根据最后一步rc4解密需要爆破后6字节,如果第一步解密的字节在rc4解密的明文中那么也可获取前6个字节。
exp
1 |
|
注: 此处是和群友交流后的思路,赛时对前6个字节单独爆破求解,因为不愿copy伪码修正代码,考虑到前6个字节的秘钥空间比较小,并且过了第二个check到最后一步rc4如果验证成功会有输出,所以可以patch最后的jz为jmp让其只要过了第二步check就会有输出,之后结合subprocess直接爆破即可。
1 |
|
程序运算比较复杂,1个多小时才爆出结果。
Berkeley
core: ebpf程序,使用bpftool提取字节码,存在源码注释。
类似题目有去年虎符fype,ebpf字节码逆向方面syj师傅写过详细的总结->传送门。
程序没有去符号,通过搜索Berkeley_bpf__create_skeleton
函数可快速定位到bpf字节码所在地。
字节码文件在.rodata
段,大小0x2118,用过idapy脚本dump即可,之后可用llvm-objdump、ida或ghidra的插件来识别字节码文件。
效果ghidra算是不错的,但是一些变量偏移不明确,读起来也十分痛苦,ghidra反编译的LBB01。
所以这里推荐bpftool工具导出的ir,即使没有源码注释也可以修改后重编译再用ida查看,流程如下。
首先bpf程序需要一些内存操作权限,在开启linux_server时要以root权限运行,并运行过bpf_open_and_load
将字节码载入内存。
之后新开的终端运行bpftool prog show,获取载入内核后的函数id为38和40。
之后运行bpftool prog dump xlated id 38提取LBB0_1处的ir。
可见包括**;源码**的注释,根据存在的源码注释即可快速理解代码,对于LBB0_2则采用同样的方法。
RE群友: strings即可dump出源码,用ghidra看老久真是输麻了。
1 |
|
EasyVT
core: 驱动程序用于处理用户程序中的VT-exit异常,了解vt的无条件退出指令和相关常量即可解题。
VT学习资源参考: 传送门
VT相关常量定义在vtsystem.h中,驱动中相关常量可以在其中搜索来理解相关含义。
驱动入口出调用sub_4026C0函数,之后是sub_402240,其中一条指令非常关键,设置了host程序的ip为处理函数。
1 |
|
sub_401C10函数保存寄存器上下文,并调用sub_401C90函数,进入关键的异常处理模块。比对常量表可得知case对应哪种退出原因,并且皆为无条件退出指令的处理。
查看应用程序main函数的汇编,包括4步循环,每个循环主要由三个动作,第一个是将输入每次取连续8字节分别放到esi和edi,第二个是vm指令跑出异常,第三步进行check。
根据其抛出的异常顺序,从vmxon开始到vmxoff结束,依次查看其对应的异常处理函数即为加密逻辑,这和普通驱动逆向的功能码差不多,比较障眼法的是对rc4的key、魔改tea的sum和delta有多次赋值,只要按照正常的调用流程查看异常函数依次覆盖即可。
完整的流程就不再赘述了,这里提出几点需要注意的。
vmcall的异常处理函数的if分支是停止驱动时服务才会走,为DriverUnload的处理。
vmxoff是对rc4和tea加密结果的比对,并赋值eax,也就是用户程序最后通过eax的值来check。
简述加密逻辑是: rc4加密按照EDI ESI顺序,Tea加密是按照ESI EDI的顺序,在VMPTRST指令的处理中交换了顺序。
解密魔改tea
1 |
|
解密rc4
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!