2024鹅厂安全竞赛题解-初赛
hack.exe
反调试
对hack.exe脱外壳+IAT修复后,进行简单分析,可知存在三种检测反调试(不完全),后边调试dll_shellcode是还发现了有扫字符串。
1、调用NtQueryInformationProcess 扫描进程的DebugPort。
2、清空dr寄存器。
3、隐藏线程
token1
运行hack.exe
后,运行调试器附加后发现提示非法,且下次重新打开hack.exe
时仍然提示。
偶然发现重启后,非法失效(不弹框),因此猜测存在写文件 or 傀儡进程检测。使用WinAPIOverride
进行api监视(API Monotor被加黑),发现进程存在频繁读内存,且意外发现存在写内存(4D5A),因此考虑到dll-MapInject
。
自行编写工具,hook WriteProcessMemory
和ReadProcessMemory
得到shellcode文件。
并且通过日志文件发现在最后一次弹窗的时候,有访问winlogon.exe
内存1字节。
使用CE查看可知该内存的值为0xF
,大胆修改为0
后,第二次启动发现不弹窗,猜测已经过了检测,但原理没仔细分析,至少避免每次都要重启。
对工具保存到的bin文件分析发现每个bin作用如下:
filename | todo |
---|---|
9_10316_Taskmgr.exe_390_000002060B510000_58c.bin | map_loader |
10_10316_Taskmgr.exe_390_000002060B51058C_3f7e00.bin | dll数据 |
11_10316_Taskmgr.exe_390_000002060B90838C_228.bin | 调用map_loader的参数指针 |
直接对dll进行分析,代码vm不多,对iat进行查看,发现可疑的APIWriteProcessMemory
,交叉引用后得到相关位置,该处未vm,直接F5分析。
首先发现存在写addr+0xACE
地址,并且是跨进程,与上边工具记录到的最后一条内容0x327eb92ace
符合,并且写入的值(0xF),与实际内存查看一致。往下分析发现存在写文件。
记得题目条件有说写出token1,因此直接进行调试该处。
对CreateFileA
打断点断下后,查看rcx值。

发现为C:\2024GameSafeRace.token1
,接着继续往下F8,发现CreateFileA
执行返回-1
,呃,,OPEN_EXISTING,第二次重新操作,先手动在C盘创建该文件,然后再F8执行,一直执行到CloseHandle
结束,对文件进行打开查看,得到token1。
ace.sys
ace.sys
需要在hack.exe
启动后加载才行,不然驱动加载失败(非31返回值)。
首先是返回值31
,第一个想法就是估计是个Loader,想双机,但是有题目调试,用之前写的反反调试工具尝试绕过,失败。驱动加载后尝试用一些ark(pchunter、ydark,noone,winark),但发现打开立马蓝屏,蓝屏代码为0xACE
。
重新思考了一下,内核线程是跑在system
进程里的,而且看题目描述运行时修改尽量少的内存,让两段token输出成功
,那应该是挂了一个线程的用来输出flag的(r3层也是一个while在跑)。因此得出两点:
1、system
线程列表里挂着一个线程在等待flag输出。
2、因为猜测ace.sys
是作用是个Loader,因此线程所属模块极大可能是无模块。
根据第一点,首先猜到是会不会有dbg输出,因此打开dbgview
、dbgview++
分别测试,发现无输出;因此疯狂尝试切换各种冷门ark,测试后发现WKE(https://github.com/AxtMueller/Windows-Kernel-Explorer)、OpenArk(https://github.com/BlackINT3/OpenArk)可以使用。
打开WKE
对system
进程的线程扫描,发现存在一个无模块线程。
因此下一步想法是dump,由于检测双机,因此使用了livekd(https://learn.microsoft.com/zh-cn/sysinternals/downloads/livekd)进行dump。
使用!address
命令进行内存区域扫描,发现RegionSize相当大,全部dump显然不合理,因此只对部分内存dump(保证dump的内存中包含了完整的线程代码)。
使用ida加载后发现,代码段和r3的很类似。
对照反汇编进行分析,实际上rax_FFFF848C4C016018
对应的函数是DbgPrintEx
。
那就有点奇怪了,,,,明明有调用,但是没输出,那么考虑到Log是不是被过滤了。对注册表操作一段,发现还是没用,于是对调用参数进行分析。MSDN(https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debugger/reading-and-filtering-debugging-messages)
以往驱动开发中DbgPrintEx
的参数二没印象可以传这个值,想到可能是需要修改参数?因此打开OpenArk
直接修改对参数修改.
读一下,确保修改生效。
然后重新打开dbgview,发现token已经输出了。
总结
flag{ 757f4749aebb1891ef5ac2a9b5439cea-8b3f14a24d64f3e697957c252e3a5686}