强网杯Secured Personal Vault预期解WP
背景
该题唯一解是非预期。
然后该题为蓝屏DUMP,需要分析内核,那必须搞一下。
预期解
其拿到手是个DMP文件,8G fulldump。
直接看一下堆栈情况,发现是一个从EXE 到 SYS中 并触发蓝屏的情况。
把栈帧切到驱动里面看一下
显然的他是故意触发蓝屏,解引用0指针。
肯定要开始分析了,那么需要把驱动、应用,DUMP出来分析。
DUMP
显然可以直接.writemem来完成,但是会有问题。
问题就是,内存被换出了,并没有驻留,故此内存dump会缺页。
驱动并不明显,但是到了EXE这里就会出大问题,缺很多东西,那么需要换一种办法dump了。
我选择的是折磨自己的办法,写个windbg插件,这玩意AI竟然写不明白。只能自己摸索。
这里花了大量时间
代码如下:
1 |
|
驱动分析
驱动真正入口点很容易定位,无论是字符串还是什么。
可以往下分析一下。
稍微往下看一下就能发现其获取了ntoskrnl的基地址,并通过nt!HalPrivateDispatchTable表获取了HalTimerConvertAuxiliaryCounterToPerformanceCounter的地址(nt!HalPrivateDispatchTable + 0x398)并替换了指针,显然用于通信。
后面则是拿了全局的进程链表。
那么下一步就是看通信函数了。
其中需要恢复一下结构,其轻而易举。
1 | struct CommuStruct |
显然的,当function为1的时候就是蓝屏,当2的时候根据pid拿到该进程的CreateTime。
EPROCESS 的偏移如下:
观察一下所有函数,就可以发现此时驱动已经分析完了,并没有什么有用的函数了。
应用分析
首先查看一下进程列表,会发现有2个进程名字一样的进程(就是一个exe开了2),其中一个引发了蓝屏。
蓝屏的进程为ffffef063fbc1080(EPROCESS)
这里需要用我的插件dump出来并修复PE结构(我反正是手修的)。把2个EXE都dump出来,并把引发蓝屏的进程称之为A,另一个称之为B。
由于2个进程是一样的,这里选取A进程的dump着重分析。
当修好PE结构后,其导入表应该是都在的。
入口点一眼盯真发现其是创建了一个窗口程序,处理程序为sub_7FF611D11D10。直接点进去分析。
可以发现其创建了2按钮(一个是创建,一个是检查)2个输入的地方(一个是用户名,一个是秘密)。
创建逻辑分析

这里比较长,就直接讲是什么意思。
- 通过与R0通信,获取本进程的CreateTime
- 随机生成AESkey与IV
- 采用AES CBC + Padding的方式来加密输入的东西
- 把AESkey和IV与CreateTime进行亦或,本质就是加密一下AESkey和IV
- 创建邮件槽(IPC通信方式之一)并把密文写入其中。
- 创建共享内存(根据输入的用户名),把自己的Pid和邮件槽的句柄写入其中。
那么这一时刻又有老铁问了?为什么是AES。
其实FindCrypt已经给了答案。
检查逻辑分析

这里比较长,就直接讲是什么意思。
- 通过用户名读取共享内存,获取邮件槽句柄
- 查看邮件槽中的数据,并读出来(此时为密文)
- 通过与R0通信,获取本进程的CreateTime
- 通过CreateTime解密AESkey与IV
- 解密密文,并重新加密AESKey与IV
- 判断解密是否成功
- 成功则弹出信息框,不成功则把解密失败的内容写入邮件槽,并引发蓝屏
那么我们需要考虑其为什么蓝屏?
- 很显然是没解密出来正确的密文
那么为什么会出现这个问题?
- 需要动静结合阐述这个问题。
我们抓住一个点:其邮件槽的句柄是通过共享内存来获取的,共享内存则是根据用户名一一对应的。 进而当2个进程输入一个同一个用户名则会导致混乱。
此时我们便可以进行现场还原,根据dumpfile。
在引起蓝屏的进程中查看句柄,情况真相大白。
不难看出mailslot_1359e83被引用了2次,其表明是A、B进程都引用了他,进而A进程用自己的密钥,解密B进程密钥加密的数据,导致与自身不匹配引发的蓝屏。
所以要解密其秘密数据,需要先用A进程的密钥加密回去,再用B进程的密钥解密。(主要是他也不符合padding的结果,肯定是需要做其他操作)
而mailslot_e60a23e2是A进程自身的秘密数据,用A进程的密钥即可解密。
此时我们逻辑理清了,那么现在需要数据。Key、IV、CreateTime都可以直接拿到,难点则在邮件槽的数据。
邮件槽分析
邮件槽(mailslot)是一种跨进程通信的Windows服务,其基于文件。
具体的邮件槽原理在《Windows内核原理与实现》中写的很清楚,这里不在赘述,而是讲述一种分析思路。
我们从只有一个引用的邮件槽开始分析。
首先查看其对象类型,发现其是文件对象。
那么此时先按文件对象的结构进行解析。
此时需要关注其是什么驱动管理了该文件对象。
现在真相大白了,msfs驱动管理了邮件槽的对象,我们需要对其分析。
直接把本地的驱动丢IDA里看一下。
既然邮件槽的对象归msfs驱动管理,我们需要关注其IRP处理函数,就可以知道读写邮件槽时如何对其操作了。
此时转到MsFsdRead函数看一下。
此时可以发现,_FILE_OBJECT的FsContext成员为关键成员,其0x118处存储了数据。
进入MsReadDataQueue进一步分析。
其中会发现在0x18处是其数据的LIST_ENTRY,- 8则是原始数据结构的头部,+ 0x28则是数据指针,+ 0x20则是数据长度。
回归到具体数据上则是这样,0xffffe70b`7e814260是上文中的FsContext
解密
CreateTime只需要dt _EPROCESS的方式就能看到了。
此时我们理一下数据大致如下:
1 | 0298: Object: ffffe70b7f0673c0 GrantedAccess: 00160089 (Protected) Entry: ffffa687a73fba60 |
那么请注意,由于AESkey和IV都是亦或过自己的CreateTime,解密时仍然需要。
先看简单的,0x80长度的密文对应的时只有一个引用的(A进程)。
此时需要把AESkey和IV与A进程的CreateTime逐字节亦或并解密AES即可。
可以发现能解出来一句话,说明另一个才有flag。
那么按照刚才的逻辑来捋一下。
- 需要用A的AESkey和IV先亦或一下CreateTime,得到真正的AESkey和IV
- 由于炸了之前把解密错误的文本写入了邮件槽,则需要把密文用A的key和IV加密
- 用B的AESkey和IV先亦或一下CreateTime,得到真的AESkey和IV,并解密刚刚加密的密文

此时成功解密:flag{Making_challenge_is_hard_manage_a_secure_vault_is_more_difficult}
- 标题: 强网杯Secured Personal Vault预期解WP
- 作者: moshui
- 创建于 : 2025-10-22 00:54:19
- 更新于 : 2025-10-22 10:12:50
- 链接: https://www.moshui.eu.org/2025/10/22/qwb-SecuredPersonalVault-wp/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。