WMCTF2025 逆向出题笔记

这次我出的题预期难度定在了Hard,最后结束在三解,符合预期。这次的项目代码量很大,费了不少时间去构思,就是为了出不恶心人的难题,是合理的难,而且还不失乐趣。开源地址:VideoPlayer Source

alt text

alt text

[出题构思]

这次出题我是往现实场景逆向靠拢,也就是模仿的现实逆向商业VMP保护下的软件场景,想要考察的是选手的软件综合审计能力,以及动态调试、观察数据能力。所以弱化了(甚至没有)传统的加解密环节。仅仅需要静态分析配合动态调试即可得到Flag,但是需要很强的代码审计能力。

UI的框架选用Imgui,因为我平常开发UI都是用这个,所以用的比较顺手,(推荐一波我开源的OS-ImGui库->OS-ImGui,基于ImGui的二次封装库)。由于ImGui库的代码量较大,所以最终VMP保护后代码膨胀较大,造成脱壳后IDA加载分析较为吃力,后续上传了体积更小的版本便于IDA进行静态分析。

加上VMP是因为仿制现实逆向场景,而且我需要其中的函数保护功能,对其中三个核心函数进行虚拟化保护,考验选手从其他函数进行侧面逆向来综合分析,也就是在函数不完整的情况下去探索软件的流程,通过分析函数调用流,去寻找漏洞点。

[题目设计]

这题背景选在了加密视频播放器下,因为平常买的一些课程视频大多都用一些视频保护器进行保护,需要特定的加密视频播放器登入才能播放视频,所以就选了这么一个场景来当作题目背景。

[主流程]

  1. 需要账号密码来登入软件,然后不同账号播放加密视频的密钥是不一样的,是根据该账号绑定的机器信息生成的,也就是一机一密。

alt text

  1. 预留了后门超级用户,且该超级用户只校验输入的用户名,不校验密码,这边特意使用strcmp校验超级用户名,方便选手拦截到超级用户名。

alt text

  1. 模仿游戏反作弊机器码部分功能,获取目前机器的一些信息,如:硬盘序列号、Mac地址等机器信息,然后整合进行MD5,进行本地校验是否为超级用户的机器,校验通过则登入成功,并且该超级用户机器信息MD5直接作为密钥凭证进行使用。

alt text

  1. 选取.mp0后缀加密视频文件进行播放,但软件不具备视频播放能力,但是在软件中已经解密了,直接找到解密处断点步过执行提取解密后数据即可。

alt text

[题目writeup]:

反调试处理+VMP脱壳Dump

法1:TitanHide过反调试

这边反调试使用TitanHide驱动,Github可以搜索到相关项目,运行TitanHide.sys需要配置环境。

使用VKD工具的target64中的vminstall在虚拟机中运行安装,会多出来一个引导启动,重启电脑选择新的引导启动就可以,他会进入内核调试模式,禁止驱动强制签名以及关闭PG,也就可以让我们加载titanhide驱动。

运行titanhide.sys,将titanhide的dbg相关插件文件放入dbg的plugins文件夹中,运行dbg即可调试VMP程序。

法2:CheatEngine Veh debugger

软件运行后,使用CE附加,选用VEH Debugger即可进行断点调试。

alt text

寻找OEP

断点GetSystemTimeAsFileTime,运行,第二次断下后,栈的第二个返回地址就是OEP,这也是exe程序VMP寻找OEP的通法。

alt text

OEP:

alt text

RIP修改到OEP,使用Scylla插件Dump程序。

alt text

主流程分析

IDA加载Dump的程序,可以通过字符串定位到Login页面代码,但是会发现Login按钮后调用的相关登入Check函数,被VMP虚拟保护了,所以无法正向从这边分析。

alt text

题目说存在后门账户,猜测会通过strcmp判断用户名或密码文本(这边通过断点用户名或密码的内存进行后续分析也可以)

随便输入用户名和密码后,断点strcmp,点击Login按钮断下,发现会判断一次用户名是否为WMAdmin_#6&JZZ%B,证实确实存在后门用户名判断,但是目前还是登入失败。

alt text

字符串这边可以看到一些系统信息相关字符串。

alt text

定位到字符串相关调用函数,再查函数的交叉调用,发现这边会调用多个引用到系统字符串相关函数。

alt text

alt text

alt text

dbg定位到调用这些函数的主函数,断点,发现正常输入随机用户名和密码并不会触发,用户名输入后门用户名时会触发。

这个获取系统信息的函数会断下,执行到ret,发现是获取了多个系统信息字串,然后拼接到一起返回。

alt text

单步返回到这边,分析这部分代码,发现是将获取到的系统信息字串进行MD5,然后逐字节push_back到一个vector容器中。

alt text

执行到push_back之后的Call,让所有数据添加完毕,push_back的第一个参数rcx就是容器对象本身,也就是[rsp+80],对[rsp+80]下8字节的硬件断点,运行,会断到下面这个函数。

alt text

单步运行到返回,来到如下函数,复制部分二进制48 63 44 24 24 48 89 44 24 50 48 8B 8C 24 D0 00 00 00 E8 E9 92 FF FF,到IDA搜索字节找到对应函数进行反编译分析。

alt text

可以发现这边是将刚刚系统信息MD5的Vector数据传入进来然后逐个与v5数组比对,如果相等则返回1,不等则返回0。

结合题目信息,可以知道该软件登入后门用户的时候还会对机器进行校验,如果是指定机器才会登入成功。

alt text

尝试运行到ret,将函数返回值rax修改成1。
alt text

结果动调发现上面MD5数组在后续仍被访问,最后会到这边,v34就是上面的那个数组对象,第一个箭头函数是判断数组是否为空,如果为空则报错账号密码错误,如果不为空则把数据复制给a1参数的Vector数组。

alt text

Vector判断是否数据为空:

alt text

这边就可以该程序登入的大概流程:

  1. 输入账号、密码

  2. 判断是否为后门账户名

  3. 获取机器信息MD5,储存到Vector数组

  4. 返回Vector数组,如果账号密码错误则Vector数组为空,如果后门账号登入失败也同样为空。

  5. 将返回的MD5信息数组数据复制到登入函数的参数Vector容器中。

上面操作流程中我们将检验机器的那个函数返回值改成了1,也就是true,让他通过后门登入,所以返回了MD5数据数组。

IDA字符串可以找到”Open File”和”Play Video”相关字串,跳转到调用函数,就可以看到这个是登入后的页面相关函数。

alt text

“Open File”下面那个Call就是初始化结构,打开对话框的。

alt text

通过调试该页面函数,发现第一个箭头就是将对话框里面选中的文件目录绘制到窗口上,上面的(255,255,255,255)就是字体颜色,第二个箭头处判断选中文件目录是否为空,如果不为空则返回1,为空则弹对话框要求选中一个.mp0后缀的文件并返回0。

alt text

通过相关字符串查交叉引用定位到Player Page页面,这边也能看到打开视频文件的错误信息,复制函数部分代码字节48 89 54 24 10 48 89 4C 24 08 56 57 48 81 EC B8 01 00 00 B8 04 00 00 00,到dbg搜索,对函数头下硬件断点。

alt text

选择video.mp0文件,然后点击Play按钮断下,发现该函数的参数一rcx是上面返回的MD5 Vector数据对象,进入两层就可以看到之前得到的MD5数据。

alt text

IDA这边可以看到判断是否通过a2文件路径的读入文件成功,然后传入文件数据以及a1参数(MD5数据)调用了一个函数,动调可以发现这边第三个参数就是返回的数据,那么这边就可以猜测就是视频数据解密函数。

alt text

通过题目可以知道该视频播放器并没有开发完成,在下面也看不到对该返回数据操作的相关代码,以及播放视频相关代码,所以就只能断在上面函数调用,单步执行,然后拿到第三个参数的数据,手动导出到文件。

题目可知该视频是由后门账户加密的,且解密的时候有传入系统信息MD5数据,所以要在MD5函数调用处将数据修改成上面校验的目标数据,也就是后门账号电脑系统信息MD5数据。

这样后续解密的时候就会传入后门账号电脑系统信息MD5数据,成功解密由后门账号加密的视频。

alt text

断在该处记下参数三r8的地址,单步执行后,跳转到r8地址,将md5数据修改成B4 EC ED FE 29 6E DE 7B 93 84 57 AF 61 9C 83 4B

alt text

复制IDA中的调用解密函数的汇编字节4C 8D 05 C1 9D 02 00 48 8B 94 24 D0 01 00 00 48 8D 0D 92 9D 02 00 E8 7D 35 F9 FF,dbg搜索定位到解密函数调用,断下。

alt text

选择video.mp0文件,点击Play按钮断下,记下参数三r8地址,单步执行Call,然后等待解密完成,跳转到r8地址。

alt text

可以看到r8这边还是一个Vector结构,第一个是数据头指针,第二个是数据尾指针,相减就是数据大小,这边计算得到为11904字节大小。

alt text

进入第一个地址,就可以看到成功解密出来的相关mp4文件数据。

alt text

使用Scylla插件,File->Dump memory,填入数据头指针地址,以及数据大小,进行Dump。

alt text

Dump得到mp4文件,打开就可以看到输入Flag的视频,拉到最后就是完整Flag。

alt text

[Flag]

WMCTF{63840490-84c5-4223-b5ee-63d4e51d0f05}