感谢宝子们对我的帮助!
特别感谢!存宝!翔哥!呜呜呜呜!
WP是简单的版本,因为做题的时候是远程好盆友的电脑,自己没有windows环境,所以代码和截图说明就没有那么多了,就简单版本!希望大家不要喷我!我就是记录一下!存个档!
题目解读后,可以分为两个块,一个是写注册机,一个是分析内核shellcode的位置和干了什么
在进行这个题目的时候,发现双机调试不能使用,分析的ark
工具也不能使用,基本上这种方式不太行了,但是仍然比不了自己手速!哈哈哈哈!在没有蓝屏的时候用ark dump
了一份load.dump.bin
,哈哈哈哈
因为题目要求将card.txt
放置到C
盘根目录:这个时候发现一个现象,如果我不放到根目录下,或者如果我card.txt
里面的值被我随便修改的情况下可以进行双机调试不会被检测,这个时候自己有了一点想法,(但是还是先做这个问为主),因为这个时候可以进行双机调试所以自己用双机调试做的USER
和KEY
分析的东西
load.dump.bin
中,可以看到路径的名称为:\\??\\C:\\card.txt
,但是回溯不了很烦
还根据ZwCreateFile
入手
直接看一下ObjectAttributes
里面的ObjectName
的名字
一般来说如果读取文件来说,用的是ZwCreateFile
,进行栈回溯一直跟一直跟,因为在vm
中一定要回到text
段,这个时候我认为的方式是:参数写入后,进行call
但是感觉栈回溯太多了不太行,然后想了一下看了一下这个地址的address
模块在这个loader.sys
中,计算一下offset = 0x675e20
,然后交叉引用回去即可
这个的路径是xor 0xace
做到的,我这边直接解密,也可以看到code References
的地址
直接windbg
分析后,这个位置不难,很好的可以分析user
算法的位置:
key
的算法位置:
这两个位置我是动态调试出来的,大概算法的表示为-
进行分割后,user
计算后的值转化为10
进制,就是key
的值
注册机:
第一问:administrator-4007951923
第二问:如上
第三问:编写一个exp,在exp程序运行后,对于任意的用户名-key,Loader.sys均能正确启动
只需要把jne
-> nop
即可,因为我们不需要对al
进行处理了
目前是前三问都OK了,这个时候会出现双机调试的问题,根本调试不了,因为在没有双机调试的环境下进行分析的时候发现不会蓝屏,但是当驱动正常加载后,进行打开ark
这种工具,几秒后还是会蓝屏
想了一下还是在内核当中起了线程(因为第四问也说了:在Load驱动运行后找到内核内存空间中的shellcode),因为一定是线程在做的检测的事情导致的蓝屏,尝试断PsCreateSystemThread
没有发现什么重要的信息,但是一定是有线程跑不然为什么会蓝屏?
所以注册进程回调看有什么异常的,打印ProcessId
和ThreadId
主要观察processid = 4
的,因为初赛也是这样,所以主要观察点在这个位置,发现确实创建了两条很可疑的线程,但是自己在观察这些线程地址的时候,确实没有很奇怪的地址存在,那么很有可能,在线程地址那里做了个跳板,之后进行了恢复所以看到的所有的线程都是很正常的地址
直接使用PsLookupThreadByThreadId
通过threadId
,找到startAddress
然后直接dump
,看一下里面做了什么
发现这里就是一个push mov ret
返回真正的地址位置,这两个都是这种形式
现在可以确定线程的入口是伪造的,当线程启动后会还原入口,所以这就是为什么看的线程的这些都没有啥问题的原因,这个时候猜测的这两个线程肯定是有一个做了检测的工作,另一个做了真正的事情,不然没必要创建两条
所以直接修改入口为ret
,这个时候可以发现可以双机调试了,也可以打开ark
工具,其中的另一个很奇怪的shellcode
如下
这里做了很多xmm
的操作,大概看了一下这个xmm
操作都是混淆,分析的时候直接跳过了这些分析的
现在可以确定的是百分百分确定了线程会被创建,一定会用到PsCreateSystemThread
,但是bp
不到,直接去看一下函数的实现
直接下断PsCreateSystemThreadEx
这里可以获取函数的入口点
但是按照道理来说如果直接ret
的话,不应该会做shellcode
的事情,但是现象是:断下后,瞬间入口还原了,并且蓝屏了,说明有个地方启动了,这里就猜测是插了APC
插入APC:使用KeInsertQueueApc
函数来插入APC到目标线程的APC队列中,直接断KeInsertQueueApc
查看一下KPAC
结构
可以查看到APC
的内容在loader.sys
中
可以看到这里进行了cmp
,直接修改了je -> jmp
就不会蓝屏了
第二次APC
的位置
第二次的时候发现都是xmm
的操作,很难去分析,所以没有管第二次的问题,但是由于题目上说:分析shellcode
反复在读取哪个内存地址,可以确定这里一定是一个while 1
一直在循环操作,为了降低CPU的利用率,猜测会用延时函数,最有可能的就是KeDelayExecutionThread
可以看到找到了这个shellcode
的位置,可以看到是根据rax
来的,往上跟一下
可以看到表的解密方式是xor acacacacacacac
解密出的函数列表:
这样就比较好看了,直接hook
所有的函数,发现一直在循环的遍历进程,感觉有点问题存在,直接过去分析看看做了什么,如果是一直循环遍历进程,自己猜测肯定是在准备比对什么东西,但是没有比对到,直接去分析vm
中的东西
下读断点,断下后,进行分析,发现时逐字节比对,比对是不是GameSec.exe
这个GameSec.exe
需要自己创建这个进程,然后继续分析,直接写了一个helloworld
改个名字丢进去看看做啥了,这个时候不难想到是在读R3
进程的东西
这个时候可以看到了MmCopyVirtualMemory
和PsGetProcessPeb
在一直做事情
直接跟PsGetProcessPeb
回溯
直接对rsp+40h
下访问断点
所以第四问:PsGetProcessPeb + 0xACE
第五问:编写一个search程序,在Load驱动运行后找到内核内存空间中的shellcode,输出shellcode范围内的任意地址 (NMI即可)
NTSYSAPI NTSTATUS ZwCreateFile(
[out]
PHANDLE
FileHandle,
[in] ACCESS_MASK DesiredAccess,
[in] POBJECT_ATTRIBUTES ObjectAttributes,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[in, optional] PLARGE_INTEGER AllocationSize,
[in]
ULONG
FileAttributes,
[in]
ULONG
ShareAccess,
[in]
ULONG
CreateDisposition,
[in]
ULONG
CreateOptions,
[in, optional]
PVOID
EaBuffer,
[in]
ULONG
EaLength
);
NTSYSAPI NTSTATUS ZwCreateFile(
[out]
PHANDLE
FileHandle,
[in] ACCESS_MASK DesiredAccess,
[in] POBJECT_ATTRIBUTES ObjectAttributes,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[in, optional] PLARGE_INTEGER AllocationSize,
[in]
ULONG
FileAttributes,
[in]
ULONG
ShareAccess,
[in]
ULONG
CreateDisposition,
[in]
ULONG
CreateOptions,
[in, optional]
PVOID
EaBuffer,
[in]
ULONG
EaLength
);
#include <iostream>
using
namespace
std;
uint64_t getkey(string user)
{
uint32_t encuser = 0;
for
(
int
i : user)
{
encuser = (i + encuser)*0x1003f;
}
return
encuser;
}
int
main()
{
string user;
cout <<
"input your user: "
<< endl;
cin >> user;
cout <<
"your key : "
<< getkey(user) << endl;
return
0;
}
#include <iostream>
using
namespace
std;
uint64_t getkey(string user)
{
uint32_t encuser = 0;
for
(
int
i : user)
{
encuser = (i + encuser)*0x1003f;
}
return
encuser;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-4-22 00:25
被L0x1c编辑
,原因: