Ring0 code implementation without driver under Windows NT2000XP (http:webcrazy.yeah.net)

xiaoxiao2021-03-06  39

Windows NT / 2000 / XP does not have to drive RING0 code implementation

Webcrazy

http://webcrazy.yeah.net/)

Everyone knows that Windows NT / 2000 is strictly divided into kernel mode and user mode in the I386 system, respectively corresponds to the RING0 and RING3 levels of the CPU in the I386 system. Under RING0, the privileged command can be performed, and there are access rights to any I / O device. To achieve a core state from a user state, ie entering RING 0 from Ring 3 must with a certain door mechanism of the CPU, such as interrupt gates, call doors, etc. Windows NT / 2000 provides users with user-state execution system services (Ring 0 routines), the system service's int 2EH interrupt service, etc., strict parameter checks, can only strictly perform the services provided by Windows NT / 2000, and If you want to execute the Ring 0 code provided by the user (pointing the code running in Ring 0), the general method seems to have only the device driver. This article will show a method of performing Ring0 code in a user state without any driver.

Windows NT / 2000 Tumbs the device driver into the kernel area (common on the address 0x80000000), which implements RING 0 when the DPL is 0, ie the CS is 8. This article implements RING0 code by constructing a call gate pointing to our code in the system. Based on this idea, it is mainly to construct your CallGate mainly for this purpose. Callgate is specified by the overall table called Global Descriptor Table (GDT). The GDT address can be obtained by the I386 command SGDT (SGDT is not a privileged command, and ordinary Ring 3 programs can be performed). The GDT address is saved in the Windows NT / 2000 in the KPCR Control Region structure (see "Talking about Windows NT / 2000 Environment Switch"). Callgate in GDT is the following format:

Typedef struct

{

Unsigned short offset_0_15;

UNSIGNED Short Selector;

Unsigned char param_count: 4;

Unsigned char SOME_BITS: 4;

Unsigned char TYPE: 4;

Unsigned char app_system: 1;

UNSIGNED Char DPL: 2;

Unsigned char present: 1;

UNSIGNED SHORT OFFSET_16_31;

Callgate_Descriptor;

GDT is located in the kernel area, and the general user-state program is impossible to have direct access to this memory area. Fortunately, Windows NT / 2000 provides a section kernel object called PhysicalMemory under the path of / device. As the name suggests, physical memory can be operated by this section object. The object is analyzed with Objdir.exe as follows:

C: / NTDDK / BIN> OBJDIR / D / DEVICE

PhysicalMemory

Section

DACL -

ACE [0] - GRANT - 0XF001F - NT Authority / SYSTEM

Inherit:

Access: 0x001f and (d rctl wown wdacl)

ACE [1] - GRANT - 0x2000D - Builtin / Administrators

Inherit:

Access: 0x000D and (RCTL)

From DUMP, this object DACL's ACE can see that only System users have read and write permissions for this object by default, that is, the physical memory is read and written, and the Administrator is only read, and ordinary users have no permissions. However, if we have Administrator permissions, you can modify this object's ACE via GetSecurityInfo, STENTRIESINAACL with the setsecurityInfo these APIs. This is also the reason why the code I have requires administrator. The implementation code is as follows: void setphyscialMemorysectioncanbewrited (Handle Hsection)

{

PACL PDACL = NULL;

PACL PNEWDACL = NULL;

PSecurity_Descriptor PSD = NULL;

DWORD DWRES;

EXPLICIT_ACCESS EA;

IF (dwres = getsecurityInfo (HSECTION, SE_KERNEL_Object, DACL_SECURITY_INFORMATION,

NULL, NULL, & PDACL, NULL, & PSD)! = Error_Success

{

Printf ("GetSecurityInfo Error% U / N", DWRES);

Goto cleanup;

}

ZeromeMory (& EA, SIZEOF (EXPLICIT_ACCESS));

Ea.grfaccesspermissions = section_map_write;

Ea.grfaccessmode = GRANT_ACCESS;

Ea.grfinheritance = no_inheritance;

Ea.trustee.trusteeform = trustee_is_name;

EA.TRUSTEE.TRUSTEETEETYPE = trustee_is_user;

Ea.trustee.ptStrName = "current_user";

IF (dwres = setENTRIESINACL (1, & EA, PDACL, & PNEWDACL)! = Error_Success)

{

Printf ("STENTRIESINACL% U / N", DWRES);

Goto cleanup;

}

IF (dwres = setsecurityInfo (hsection, se_kernel_object, dacl_security_information, null, null, pnewdacl, null)! = error_success

{

Printf ("SetSecurityInfo% U / N", DWRES);

Goto cleanup;

}

Cleanup:

IF (PSD)

Localfree (PSD);

IF (PNewDACL)

Localfree (PSD);

}

This code adds the following ACE to a given Handle's object:

PhysicalMemory

Section

DACL -

Ace [0] - GRANT - 0x2 - Webcrazy / Administrator

Inherit:

Access: 0x0002 // section_map_write

This way we have read and write ability for physical memory under conditions with administrator privileges. But to modify the GDT table to implement the Ring 0 code. We will face another problem, because the GDT address obtained by the SGDT command is a virtual address (linear address), and we only have the physical address of the GDT table to modify the GDT table through the / Device / PhysicalMemory object, which involves the conversion of linear addresses. Problem of physical address. Let's take a look at how Windows NT / 2000 implements this: kd> u nt! Mmgetphysicaladdress L 30

Ntoskrnl! mmgetphysicalAddress:

801374e0 56 Push ESI

801374E1 8B742408 MOV ESI, [ESP 0x8]

801374E5 33D2 XOR EDX, EDX

801374E7 81FE00000080 CMP ESI, 0x80000000

80137 4ED 722C JB NTOSKRNL! MMGETPHYSICALADDRESS 0X2B (8013751B)

801371EF 81FE000000A0 CMP ESI, 0XA0000000

801374f5 7324 JNB NTOSKRNL! MMGETPHYSICALADDRESS 0x2B (8013751B)

801374F7 39153CE71780 CMP [NTOSKRNL! MMKSEG2FRAME (8017E73C)], EDX

801374FD 741C JZ NTOSKRNL! MMGETPHYSICALADDRESS 0X2B (8013751B)

801374FF 8BC6 MOV EAX, ESI

80137501 C1E80C SHR EAX, 0xC

80137504 25FFFF0100 and Eax, 0x1ffff

80137509 6a0c push 0xc

8013750B 59 POP ECX

8013750c E8D3A7FCFF CALL NTOSKRNL! _ALLSHL (80101CE4)

80137511 81e6ff0f0000 and ESI, 0xFFF

80137517 03C6 Add Eax, ESI

80137519 EB17 JMP NTOSKRNL! MMGETPHYSICALADDRESS 0X57 (80137532)

8013751B 8BC6 MOV EAX, ESI

8013751D C1E80A SHR EAX, 0xA

80137520 25FCFF3F00 and Eax, 0x3fffcc

80137525 2D00000040 SUB Eax, 0x40000000

8013752A 8B00 MOV EAX, [EAX]

8013752C A801 ​​Test Al, 0x1

8013752e 7506 JNZ NTOSKRNL! MMGETPHYSICALADDRESS 0X44 (80137536)

80137530 33c0 xor Eax, EAX

80137532 5e POP ESI

80137533 C20400 RET 0x4 From this assembly code, it can be seen that if the linear address is within the range of 0x80000000 and 0xA0000000, it is just a simple shift operation (located between 801374FF-80137519 instructions), and does not check the page table. I want Microsoft to arrange this definitely because of the efficiency of performing. This also specifies a line of shirts because the GDT table is in this area in this area in Windows NT / 2000 (I don't know if the Windows NT / 2000 of the / 3GB switch).

After such an analysis, we can only modify the GDT table by the user program. And adding a CallGate is not what I can introduce, find this Intel manual to see it. The specific implementation code is as follows:

Typedef struct gdtr {

Short limit;

Short baselow;

Short baseh;

} GDTR_T, * PGDTR_T;

Ulong MinimmgetPhysicalAddress (Ulong Virtualaddress)

{

IF (VirtualAddress <0x80000000 || VirtualAddress> = 0xa0000000)

Return 0;

Return Virtualaddress & 0x1fff000;

}

BOOL EXECRING0PROC (Ulong Entry, Ulong Seglen)

{

GDTR_T GDT;

__ASM SGDT GDT;

Ulong mapaddr = minimmgetphysicaladdress (gdt.basehigh << 16u | gdt.blelow);

IF (! mapaddr) return 0;

Handle hsection = NULL;

NTSTATUS STATUS;

Object_attributes objectattribute;

Unicode_String Objname;

Callgate_descriptor * cg;

Status = status_success;

RTLinitunicodeString (& ObjName, L "// device // physicalmemory);

InitializeObjectAttributes (& ObjectAttributes,

& objname,

Obj_case_insensitive | obj_kernel_handle,

NULL,

(Psecurity_descriptor) null;

Status = zwopensection (& hsection, section_map_read | section_map_write, & jectattributes);

IF (status == status_access_denied) {

Status = zwopensection (& Hsection, Read_Control | Write_DAC, & Objectattributes);

SetPhyscialMemorySECTIONCANBEWRITED (HSECTION);

ZWClose (HSECTION);

Status = zwopensection (& hsection, section_map_write | section_map_write, & objectattribute);

}

IF (status! = status_success)

{

Printf ("Error Open PhysicalMemory Section Object, Status:% 08X / N", STATUS);

Return 0;

}

Pvoid ​​BaseAddress; BaseAddress = MapViewOffile (HSECTION,

FILE_MAP_READ | file_map_write,

0,

MapAddr, // low part

(GDT.LIMIT 1));

IF (! BaseEaddress)

{

Printf ("ERROR MAPVIEWOFFILE:");

PRINTWIN32ERROR (getLastError ());

Return 0;

}

BOOL setcg = false;

For (CG = (Callgate_Descriptor *) ((Ulong) Baseaddress (GDT.LIMIT & 0xFFF8)); (Ulong) CG> (Ulong) BaseAddress; cg -)

IF (cg-> type == 0) {

CG-> offset_0_15 = loword (entry);

CG-> selector = 8;

CG-> param_count = 0;

Cg-> Some_bits = 0;

CG-> Type = 0xc; // 386 Call Gate

CG-> app_system = 0; // a system descriptor

CG-> DPL = 3; // Ring 3 Code Can Call

CG-> present = 1;

CG-> Offset_16_31 = HiWord (entry);

Setcg = true;

Break;

}

IF (! setcg) {

ZWClose (HSECTION);

Return 0;

}

Short farcall [3];

Farcall [2] = ((Ulong) CG- (Ulong) BaseEaddress) | 3; // Ring 3 CallGate;

IF (! VirtualLock ((pvoid) entry, seglen))

{

Printf ("Error VirtualLock:");

PRINTWIN32ERROR (getLastError ());

Return 0;

}

SetthreadPriority (getCurrentThread (), thread_priority_time_critical;

Sleep (0);

_ASM Call fword PTR [farcall]

SetthreadPriority (getCurrentthRead (), thread_priority_normal);

Virtualunlock ((pvoid) Entry, Seglen;

// Clear Callgate

* (Ulong *) cg = 0;

* ((Ulong *) cg 1) = 0;

ZWClose (HSECTION);

Return True;

}

I am demonstrating the operation of the Control Register and I / O port in the code. The CIH virus is in Windows 9x because it has a certain harm because of Ring 0 permissions, but Windows NT / 2000 is not Windows 9x, she already has more security audit mechanisms, and the code provided herein also requires Administrator privileges. However, if there is a loophole, such as buffer overflow, etc., it is possible to obtain this permission, so I don't have any responsibility for the methods provided herein. All discussion is just a technical enthusiast in discussing technology. Thank you!

Reference:

转载请注明原文地址:https://www.9cbs.com/read-62180.html

New Post(0)