🔒 Locked
Getting into Ring 0...
Advertisement
Original Post
I don''t think is really possible, but I just ask, maybe someone knows...
OK, the Pentium Processors have several different safety rings. The OS gets Ring 0 (the one with all the power) and you can use the API of the OS to do somethings you can only do if you are in Ring 0. Like traversing directories. Also some interrupts won''t work if you''re not in ring 0.
This seems to make sence, since you can only destroy things if you would have total power over the user''s computer. But I just feel like experimenting today and I want to know if I can get into Ring 0.
After a search on Google I didn''t found anything, but a friend of me says that some people can do it in 20- rows, and they use some virtual drivers for that (.vxd''s). I don''t think that is possible without completely shutting down the OS. That would be really simple, since there is no-one using Ring 0 at that point.
If you have any idea, website or code on this subject, please post. BTW: I''m using windows ME and XP and I know ASM and C++.
Thank you!
It can be done on W9x using asm - search google on "Ring0" - no space between - and be prepared to visit virus writing sites and the like. On NT - that means 2K and XP - a dll is required. For info on that visit www.internals.com. Kaplan has an ample set of links. A search on "callgate" might be useful as well.
Here is a blast from the past to get you started - note the date and recognize that this code is Win 3
[edited by - lessbread on September 24, 2002 4:13:55 AM]
Here is a blast from the past to get you started - note the date and recognize that this code is Win 3
// File: RING0.C
//=================================
#include <windows.h>
#include <stdio.h>
#include "descript.h"
DWORD far pascal GET_CR(WORD cmd);
DWORD far pascal GET_CR_RING3(WORD cmd);
typedef DWORD (FAR PASCAL * DWORD_FARPROC)(WORD);
int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow )
{
char buffer[256];
DWORD_FARPROC GET_CR_ptr;
unsigned long ring0CR0, ring0CR2, ring0CR3; // GRETCHEN - New Line
unsigned short ourCS; // GRETCHEN - New Line
//
// Call the ring 3 version of GET_CR() to show that you
// can't access these registers from normal ring 3 code.
// Comment the first set of sprintf()/MessageBox() calls
// below if you want to run in standard mode or on Windows
// 3.0. The call to Get_CR0_At_Ring_3() will GP fault
// unless run under Windows 3.1 in enhanced mode.
//
sprintf(buffer, "From ring 3, CR0 = %08lX\r\n"
"From ring 3, CR2 = %08lX\r\n"
"From ring 3, CR3 = %08lX\r\n",
GET_CR_RING3(0), GET_CR_RING3(2),
GET_CR_RING3(3) );
MessageBox(0, buffer, "First try", MB_OK);
//
// Now we'll get a function pointer that uses a call gate.
// The second parameter indicates how many WORD parameters
// should be copied to the ring 0 stack. If the destination
// was a 32 bit segment, the parameter would be the number
// of DWORDs to copy.
//
GET_CR_ptr = (DWORD_FARPROC)CreateCallgate( GET_CR, 1 );
// !!!!! GRETCHEN !!!! - THINGS ARE PRETTY CHANGED FROM HERE
// DOWN TO THE CLOSING COMMENT BELOW!!!
if ( GET_CR_ptr == 0 )
{
MessageBox(0, "ERROR!!!", "Second try", MB_OK);
return 0;
}
// Pagelock the segment containing the code to be executed in
// Ring 0. This is a small model program, so CS is what we want.
_asm mov [ourCS], cs
GlobalPageLock(ourCS);
//
// Use the call gate to show that at ring 0, the
// instructions can be accessed. We disable interrupts
// around the 3 calls to ring 0.
//
_asm cli
ring0CR0 = GET_CR_ptr(0);
ring0CR2 = GET_CR_ptr(2);
ring0CR3 = GET_CR_ptr(3);
_asm sti
// We don't need the segment pagelocked anymore
GlobalPageUnlock(ourCS);
sprintf(buffer, "From ring 0, CR0 = %08lX\r\n"
"From ring 0, CR2 = %08lX\r\n"
"From ring 0, CR3 = %08lX\r\n",
ring0CR0, ring0CR2, ring0CR3 );
MessageBox(0, buffer, "Second try", MB_OK);
// !!!!! GRETCHEN !!!!! THIS IS THE END OF THE BIG CHANGES
//
// Deallocate the 2 selectors we used.
//
FreeCallgate( (GENERIC_PROC)GET_CR_ptr );
return 0;
}
// ring0asm.asm
;=================================
; RING0, by Matt Pietrek, 1993
; File: RING0ASM.ASM
;=================================
.model small
.386P
.code
public GET_CR
public GET_CR_RING3
GET_CR proc
push ebp
mov ebp, esp
xor eax, eax
cmp word ptr [ebp+8], 0
jne not_cr0
mov eax, cr0
jmp done
not_cr0:
cmp word ptr [ebp+8], 2
jne not_cr2
mov eax, cr2
jmp done
not_cr2:
cmp word ptr [ebp+8], 3
jne done
mov eax, cr3
done:
mov edx, eax
shr edx, 16
pop ebp
retf 2
GET_CR endp
;
; GET_CR3_RING3 is identical in function to GET_CR. The only
; difference is that it will be called while running on the
; 16 bit stack of the calling app, instead of on the ring 0
; stack. You might think that the "push ebp / mov ebp,esp"
; code for GET_CR would work in either case, but there is
; some strangeness in the "mov ebp, esp" instruction that
; forces us to use to very slightly different versions.
;
GET_CR_RING3 proc
push bp
mov bp, sp
xor eax, eax
cmp word ptr [bp+6], 0
jne not_cr0_ring3
mov eax, cr0
jmp done_ring3
not_cr0_ring3:
cmp word ptr [bp+6], 2
jne not_cr2_ring3
mov eax, cr2
jmp done_ring3
not_cr2_ring3:
cmp word ptr [bp+6], 3
jne done_ring3
mov eax, cr3
done_ring3:
mov edx, eax
shr edx, 16
pop bp
retf 2
GET_CR_RING3 endp
end
// descript.h
#ifndef __DESCRIPT_H
#define __DESCRIPT_H
// GRETCHEN: The comment below is new, and the #pragma is uncommented
// We need the pack directive to force MSC to byte align
#pragma pack(1)
typedef struct
{
unsigned short limit_0_15;
unsigned short base_0_15;
unsigned char base_16_23;
unsigned int accessed : 1;
unsigned int readable : 1;
unsigned int conforming : 1;
unsigned int code_data : 1;
unsigned int app_system : 1;
unsigned int dpl : 2;
unsigned int present : 1;
unsigned int limit_16_19 : 4;
unsigned int unused : 1;
unsigned int always_0 : 1;
unsigned int seg_16_32 : 1;
unsigned int granularity : 1;
unsigned char base_24_31;
} CODE_SEG_DESCRIPTOR;
typedef struct
{
unsigned short offset_0_15;
unsigned short selector;
unsigned int param_count : 4;
unsigned int some_bits : 4;
unsigned int type : 4;
unsigned int app_system : 1;
unsigned int dpl : 2;
unsigned int present : 1;
unsigned short offset_16_31;
} CALLGATE_DESCRIPTOR;
unsigned short GetLDTAlias(void);
typedef void (_far _pascal * GENERIC_PROC)(void);
GENERIC_PROC CreateCallgate(void far * func_address, unsigned params);
void FreeCallgate( GENERIC_PROC callgate_ptr );
#endif
// descript.c
#include <windows.h>
#include "descript.h"
static char MS_DOS_STR[] = "MS-DOS";
//
// Return a far pointer to the LDT
//
unsigned short GetLDTAlias(void)
{
unsigned short LDT_alias;
unsigned short (far * dpmiproc)(void);
//
// Use INT 2Fh, fn. 168A to get the "DPMI extensions
// entry point" function pointer
//
_asm mov si, offset MS_DOS_STR // DS:SI = "MS-DOS"
_asm mov ax, 168Ah
_asm int 2Fh
_asm cmp al, 8Ah
_asm je extensions_not_found
//
// The entry point is returned in ES:DI. Save it
//
_asm mov word ptr [dpmiproc], di
_asm mov word ptr [dpmiproc+2], es
//
// Call the extensions with AX == 0x100. The LDT alias
// selector is return in AX. Carry flag is set on failure.
//
_asm mov ax, 100h
LDT_alias = dpmiproc();
_asm jc extensions_not_found;
return LDT_alias;
extensions_not_found: // We get here if something failed
return 0;
}
//
// Given a far 16:16 address, create a function pointer for it,
// and which uses a call gate.
//
GENERIC_PROC CreateCallgate(void far * func_address, unsigned params)
{
CALLGATE_DESCRIPTOR far *callgate_desc;
CODE_SEG_DESCRIPTOR far *ring0_desc;
unsigned short ldt_alias;
unsigned short ring_0_alias;
unsigned short callgate_selector;
if ( (ldt_alias = GetLDTAlias()) == 0 )
return 0;
//
// Grab a selector from Windows that has the exact same
// attributes as the CS portion of "func_address"
//
if ((ring_0_alias = AllocSelector(HIWORD(func_address)))==0)
return 0;
//
// Change the DPL bits of the ring 0 alias descriptor to
// be privilege 0.
//
ring0_desc = MAKELP( ldt_alias, ring_0_alias & 0xFFF8 );
ring0_desc->dpl = 0;
//
// Allocate the selector that'll be used for the call gate
//
if ( (callgate_selector= AllocSelector(0)) == 0 )
{
FreeSelector( ring_0_alias );
return 0;
}
//
// Create a pointer to the call gate descriptor
//
callgate_desc = MAKELP( ldt_alias, callgate_selector & 0xFFF8 );
//
// Fill in the fields of the call gate descriptor with the
// appropriate values for a 16 bit callgate.
//
callgate_desc->offset_0_15 = LOWORD( func_address );
callgate_desc->selector = ring_0_alias;
callgate_desc->param_count = params;
callgate_desc->some_bits = 0;
callgate_desc->type = 4; // 286 call gate
callgate_desc->app_system = 0; // A system descriptor
callgate_desc->dpl = 3; // Ring 3 code can call
callgate_desc->present = 1;
callgate_desc->offset_16_31 = 0;
return MAKELP( callgate_selector, 0 );
}
//
// Free a previously allocated call gate function pointer.
//
void FreeCallgate( GENERIC_PROC callgate_ptr )
{
CALLGATE_DESCRIPTOR far *callgate_desc;
unsigned short ldt_alias;
if ( (ldt_alias = GetLDTAlias()) == 0 )
return;
//
// Create a pointer to the call gate descriptor
//
callgate_desc = MAKELP( ldt_alias, HIWORD(callgate_ptr) & 0xFFF8 );
//
// First, free the ring 0 alias selector stored in the LDT
// call gate descriptor, then free the call gate selector.
//
FreeSelector( callgate_desc->selector );
FreeSelector( HIWORD(callgate_ptr) );
}
[edited by - lessbread on September 24, 2002 4:13:55 AM]
quote:
Original post by LessBread
On NT - that means 2K and XP - a dll is required.
More specifically, you need a driver (which is a DLL, although there are additional requirements). The Windows DDK (driver development kit) will provide some useful tools and information.
Writing a simple driver isn't that hard, but it should really only be done when there's no other reasonable way to implement the required functionality. Kernel-mode device driver bugs can be very nasty and are a common source of system instability.
[edited by - spock on September 24, 2002 11:03:48 AM]
Caveat: this worked on Win98, not sure about ME, but it definately won''t work on NT (2k & XP).
GDT and IDT memory is not protected, and the GDT limit is greater than its size. This is COLOSSALLY stupid!! All you have to do is create your own code descriptor (DPL=0 of course), have int0 point to it (could also use other faults, but this is easiest) and divide by 0 => you''re in CPL 0.
Sickening.
GDT and IDT memory is not protected, and the GDT limit is greater than its size. This is COLOSSALLY stupid!! All you have to do is create your own code descriptor (DPL=0 of course), have int0 point to it (could also use other faults, but this is easiest) and divide by 0 => you''re in CPL 0.
Sickening.
quote:
Original post by Jan Wassenberg
Caveat: this worked on Win98, not sure about ME, but it definately won''t work on NT (2k & XP).
GDT and IDT memory is not protected, and the GDT limit is greater than its size. This is COLOSSALLY stupid!! All you have to do is create your own code descriptor (DPL=0 of course), have int0 point to it (could also use other faults, but this is easiest) and divide by 0 => you''re in CPL 0.
Sickening.
Thank you, but I lost you after the first line, can you try to explain it to me again? I am sorry, but am trying to get it.
Also thanks to lessBread, the google tip really worked. I found some sites about virii and I hope to combine the knowledge from this thread with the site I found to get it right. Please be gentle
I''ve looked into the topic before too
These sites have info -
Elicz''s - an exploit site - code oriented not script kiddie
Zombies - a virii site - Russian/English
If you find better or more informative sites - don''t forget to share the urls
Spock is correct - on NT a device driver is needed too. The dll acts as a go-between from the driver (.sys) to the user mode exe.
You''ll probably want to brush up on descriptor tables and their acronyms - Jan referenced GDT and IDT, the Pietrek code references LDT. I found that Pietrek code on microsoft''s ftp site but I wasn''t able to pull it up yesterday so I don''t know what it''s status is and so I pasted all that code instead.
Here''s another url that you might find helpful:
The Operating System Resource Center
These sites have info -
Elicz''s - an exploit site - code oriented not script kiddie
Zombies - a virii site - Russian/English
If you find better or more informative sites - don''t forget to share the urls
Spock is correct - on NT a device driver is needed too. The dll acts as a go-between from the driver (.sys) to the user mode exe.
You''ll probably want to brush up on descriptor tables and their acronyms - Jan referenced GDT and IDT, the Pietrek code references LDT. I found that Pietrek code on microsoft''s ftp site but I wasn''t able to pull it up yesterday so I don''t know what it''s status is and so I pasted all that code instead.
Here''s another url that you might find helpful:
The Operating System Resource Center
OK, thanks again, but I have indeed to catch a bit of those terms up before I can call meself a real Ring0-er
. I found another URL about The VXD-way:
http://vx.netlux.org/lib/vgy06.html
But know that this site is about writing vrii. Although I find it really intresting, be aware that using this information is illigal in almost every country on the world. And since virii cross borders is a blink of an eye, you might be brought to justice in a country you have never visited before but were you will going to be spending half a year (at least) behind bars.
Or is a disclamer at this forum a bit overdone?
http://vx.netlux.org/lib/vgy06.html
But know that this site is about writing vrii. Although I find it really intresting, be aware that using this information is illigal in almost every country on the world. And since virii cross borders is a blink of an eye, you might be brought to justice in a country you have never visited before but were you will going to be spending half a year (at least) behind bars.
Or is a disclamer at this forum a bit overdone?
I forgot about VXHeavens. I haven''t looked at that site in a long time.
Well you know some books are banned in many countries but that doesn''t mean that it''s ok to ban books. Hell, in China they banned google! In the US, Congress recently passed a bill that would make cracking punishable by life imprisonment - I don''t know if the bill made it through the Senate. All that said - don''t do something stupid and get your head cut off for it.
Here''s a legitimate use for accessing Ring0 from Ring3: Detecting Vertical Retrace in Microsoft Windows
(And before anyone chimes in with "Why not use DX blah blah blah" - go read the article first it answers the question).
Well you know some books are banned in many countries but that doesn''t mean that it''s ok to ban books. Hell, in China they banned google! In the US, Congress recently passed a bill that would make cracking punishable by life imprisonment - I don''t know if the bill made it through the Senate. All that said - don''t do something stupid and get your head cut off for it.
Here''s a legitimate use for accessing Ring0 from Ring3: Detecting Vertical Retrace in Microsoft Windows
(And before anyone chimes in with "Why not use DX blah blah blah" - go read the article first it answers the question).
First, read the relevant parts of Intel''s System Programming book (available online).
The GDT contains segment descriptors for code&data segments, while the IDT holds descriptors for traps, faults & interrupts. This HAS to be protected from user level access, or else you''re toast. After giving thanks to MS for the monumental screwup of not doing so, here''s what you do:
- get address of GDT, IDT (with sgdt, sidt instructions)
- note that the limit field you got shows that there''s space in the table (another big no-no).
- create a new code descriptor in the GDT (setting its DPL field to 0)
- patch the int0 trap descriptor in the IDT so that it points to your code (i.e. just change the segment selector field)
- divide by 0 to get a fault -> int0 handler is called -> you''re in CPL 0.
The GDT contains segment descriptors for code&data segments, while the IDT holds descriptors for traps, faults & interrupts. This HAS to be protected from user level access, or else you''re toast. After giving thanks to MS for the monumental screwup of not doing so, here''s what you do:
- get address of GDT, IDT (with sgdt, sidt instructions)
- note that the limit field you got shows that there''s space in the table (another big no-no).
- create a new code descriptor in the GDT (setting its DPL field to 0)
- patch the int0 trap descriptor in the IDT so that it points to your code (i.e. just change the segment selector field)
- divide by 0 to get a fault -> int0 handler is called -> you''re in CPL 0.
Thank you!!
I will download Intel''s System Programming book and after that I will try it. Thanks to everyone involved in this thread. and if you know more, just post...
Going to eat and watch Feyenoord (soccer, don''t ask
) and tomorrow will be the day that I will enter Ring0. Sorry, I keep thinking about Stargate all the time... 
Have a nice day!
I will download Intel''s System Programming book and after that I will try it. Thanks to everyone involved in this thread. and if you know more, just post...
Going to eat and watch Feyenoord (soccer, don''t ask
Have a nice day!
quote:
Original post by RavNaz
what exactly is ring0??
quote:
The processor has four privileges levels: Ring0, Ring1, Ring2, Ring3. Normal programmes run in Ring3. Ring3 has a lot of restrictions e.g. we can''t read debugg registers and then intructions with debugg register dont work (e.g. mov eax, dr7).
For us is good have more privileges and thefore we need Ring0. But there is problem, just some special programmes have Ring0 privileges. Device drivers run in Ring0, but code device driver isn''t simple.
(source: Ring 0)
I haven''t looked up much for doing it in NT or XP, but the Win9X''s have countless ways of getting into ring-0. Heres a few ways that come off the top of my head: patching the idt, passing through the call-gate using gdt, splicing VMM, making a device driver (this is probably the recommended way =), and interrupt 0x2E. There are many more ways too. I have to admit, breaking into ring-0 is a fun thing to do, but you still have to be very careful!
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement