Dziś chcialbym napisac o tym jak mozna zabic proces ktory w jakis sposob sie przed tym broni(nie jest to jeszcze 100% skuteczne metoda ale na 99% aplikacji nie ingerujacych w KM* powinna dzialac)
Co bedziemy chcieli zrobic:
-Otworzyc proces
-Zaalokowac kawałek pamieci w tym procesie
-Wrzucic do tej pamieci shellcode
-Utworzyc wątek w tym procesie ktory uruchomi shellcode
Co będzie robil shellcode?
Będzie wywolywal funkcje ZwTerminateProcess za pomoca syscall`a
Czemu akurat tak? A po to aby uminać wszystkie hooki UM*
Najpierw o tym jak wywolywana jest funkcja przez syscall:
-na stos rzucamy parametry funkcji
-do rejestru eax wrzucamy numer funkcji
-do rejestru edx wrzucamy esp
-uzywamy mnemonika SYSENTER aby wywolac funkcje
wyglada to mniej wiecej tak:
1
2
3
4
5
6
7
8
9
10
11
| PUSH 0
PUSH -1
CALL TERM
RET
TERM:
MOV EAX,101h ;101h <- ZwTerminateProcess dla XP
CALL SYS
SYS:
MOV EDX,ESP
SYSENTER
RET |
Pozostaje jeszcze jedna kwestia zwiazana z wywolaniem syscall`a
W kazdej wersji systemu numery syscall`i sie zmieniaja. Aby nie wpisywac ich „na sztywno” pobierzemy je dynamicznie z kodu funkcji ZwTerminateProcess
(tu naleza sie podziekowania dla j00ru ktory mnie na to naprowadzil)
debugujemy tą funkcje i widzimy instrukcje mov eax,101h (B8 01010000)
widzimy więc ze aby uzyskac numer funkcji poprostu odczytamy bajty 2-5 tejze funkcji
Jeszcze jedna uwaga i przejdziemy do kodu 
Aby otworzyc niektore procesy potrzebujemy pewnych uprawnien …nadajmy je sobie
1
2
3
4
5
6
7
8
9
10
11
12
| void DebugPriv()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
}
} |
No dobrze teraz troche innego kodu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #include <windows.h>
char shellcode[]={
"\x6A\x00\x6A\xFF\xE8\x01\x00\x00\x00\xC3\xB8\x01\x01\x00\x00\xE8\x01\x00\x00\x00\xC3\x8B\xD4\x0F\x34\xC3"}; //nasz shellcode
DWORD shellcode_size=0x20;//rozmiar shellcodu
void KillApp(DWORD pid)//pid - process id
{
char code[0x20];
memcpy(code,shellcode,0x20);//kopiujemy shellcode do innego bufora
HMODULE h=GetModuleHandle("NTDLL.DLL");
FARPROC p=GetProcAddress(h,"ZwTerminateProcess");//pobieramy adres ZwTerminateProcess
memcpy((char*)(code+0x0B),(char*)((char*)p+1),4);//kopiujemy numer funkcji tak jak mówiłem wczesniej
HANDLE hProc=0;
hProc=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_CREATE_THREAD, FALSE, pid);//otwieramy proces
LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, 0x20, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//alokujemy pamiec w procesie
DWORD numBytesWritten;
WriteProcessMemory(hProc, hRemoteMem, code, 0x20, &numBytesWritten);//zapisujemy nasz shellcode do procesu
HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hRemoteMem, 0, 0, NULL);//tworzymy zdalny watek ktory wykona kod zapisany w procesie
CloseHandle(hProc);//mozemy juz zamknac uchwyt ...i tak wskazuje na nieistniejacy proces :D |
No dobrze wszystko fajnie …ale co jesli perfidna aplikacja zablokuje nam mozliwosc otwarcia procesu
mozemy probowac 2 metod
1. Debugowac aplikacje
2. Wyciągnąć ten uchwyt z procesu csrss.exe ktory przechowuje uchwyty wszystkich aplikacji(no prawie wszystkich)
Sposob 1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| HANDLE OpenProcessFromDebug(DWORD pid)
{
if(DebugActiveProcess(pid)!=0)//Zaczynamy Debuggowanie
{
DEBUG_EVENT DebugEvent;
while(1)
{
if(WaitForDebugEvent(&DebugEvent, INFINITE))//czekamy na event o jakims zdarzeniu
{
DebugActiveProcessStop(pid);//konczymy debuggowanie
return DebugEvent.u.CreateProcessInfo.hProcess;//zwracamy uchwyt procesu ktory dostajemy w evencie ;)
}
}
}
return 0;
} |
Sposob 2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
typedef DWORD (__stdcall *CSRPID)(void);
typedef DWORD (__stdcall *NTQSI)(ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength, ULONG* ReturnLength);
#define SystemHandleInformation 16
typedef struct {
ULONG OwnerPid;
BYTE ObjectType;
BYTE HandleFlags;
USHORT HandleValue;
PVOID ObjectPointer;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_ENTRY;
typedef struct {
ULONG HandleCount;
SYSTEM_HANDLE_ENTRY Handles[1];
} SYSTEM_HANDLE_INFORMATION;
HANDLE OpenProcessFromCsrss(DWORD pid)
{
HMODULE ntdll = GetModuleHandle("ntdll");
CSRPID CsrGetProcessId = (CSRPID)GetProcAddress(ntdll, "CsrGetProcessId");
NTQSI NtQuerySystemInformation = (NTQSI)GetProcAddress(ntdll, "NtQuerySystemInformation");
DWORD csrss_pid = CsrGetProcessId();//pid procesu csrss
HANDLE csrss = OpenProcess(PROCESS_DUP_HANDLE, FALSE, csrss_pid);//otwieramy proces csrss
if (!csrss)
{
return 0;
}
ULONG size = 0x1000;
SYSTEM_HANDLE_INFORMATION *handles = (SYSTEM_HANDLE_INFORMATION*)malloc(size);
//alokujemy miejsce na strukture zwracana przez NtQuerySystemInformation
DWORD status;
ULONG need;
status = NtQuerySystemInformation(SystemHandleInformation, handles, size, &need);
if(status!=0)//jesli mamy przeznaczylismy za malo miejsca to dodajmy wiecej ;)
{
free(handles);
size =need;
handles = (SYSTEM_HANDLE_INFORMATION*)malloc(size);
NtQuerySystemInformation(SystemHandleInformation, handles, size, &need);
}
int i;
HANDLE h_proc;
//mamy juz nasza strukture ...teraz poszukajmy naszego uchwytu
for (i=0; i<handles->HandleCount; i++)
{
if (handles->Handles[i].OwnerPid == csrss_pid)//wlascicielem uchwytu jest csrss
{
if (DuplicateHandle(csrss, (HANDLE)handles->Handles[i].HandleValue, GetCurrentProcess(), &h_proc, 0, FALSE, DUPLICATE_SAME_ACCESS))//duplikujemy uchwyt
{
if (GetProcessId(h_proc) == pid) //pobieramy PID z uchwytu i jesli sie zgadza to zwracamy ten uchwyt
{
return h_proc;
}
CloseHandle(h_proc);
}
}
}
if (handles) free(handles);
CloseHandle(csrss);
return 0;
} |
No to chyba na tyle w tym temacie, jesli cos mi jeszcze wpadnie do glowy to dopisze
Jeszcze jedna mała uwaga …za pomoca szukania uchwytow w csrss mozna odnalesc ukryte procesy
Cały kod pełnosprawnej aplikacji znajduje sie ponizej 
CLICK
Bede wdzieczny za wszelkie komentarze i uwagi
*UM-User Mode(ring3)
*KM-Kernel-Mode(ring0)