(Reproduced) Get core variables for Windows systems

xiaoxiao2021-03-06  81

Get the kernel variable of the Windows system into:

http://www.xfocus.net

Creation time: 2004-08-05

Article attribute: original

Article submission:

Tombkeeper (T0MBKEEPER_AT_HOTMAIL.COM)

Get core variables for Windows systems

Servers: Yu

Email: Tombkeeper [0x40] nsfocus [0x2e] COM

Tombkeeper [0x40] xfocus [0x2e] org

Completed in: 2004.07.30

Keywords: PslinedModuleList, PsactiveProcesshead, NTSystemdebugControl

PSNTOSIMAGEBASE, KDVERSIONBLOCK, KDDEBUGERDATABLOCK, kernel variable

The important kernel variables such as psloadedModuleList are not exported by ntoskrnl.exe, nor open letters.

Number can be obtained. And these core variables are used for rootkit, anti-rootkit, and core overflow.

is crucial.

Here we take PslineDModuleList, PSActiveProcesshead, etc., introduced these

Method of variables.

For Windows NT 4.0 and Windows 2000, there is no "gentle" approach to get these variables.

The ideal method is also the characteristic code search, which is very effective, generally

No problem; for Windows XP and Windows 2003, we found some more elegant options.

The method of the feature code search is first introduced.

[DWORD KERNELBASE]

To perform a feature code search, first position Ntoskrnl.exe in the loading address of the kernel KERNELBASE.

This address can pass the SystemModuleInformation of ZwQuerySysteminformation Class 10

Come. Reference resource [1] is given. In fact, the value of kernelbase is the same.

Union is very fixed, you can use it as a constant:

Windows NT: 0x80100000

Windows 2000: 0x80400000

Windows XP: 0x804d1000

Windows 2003: 0x804e0000

Windows NT 4.0 ntoskrnl.exe OptionalHeader-> ImageBase = 0x80100000,

NTLDR will also load the kernel according to this value, but it is not the case from Windows 2000. Maybe

For this historical reason, the * (dword *) PSNTOSIMAGEBASE of each system is always initialized to 0x80100000.

In addition, the kernel variables PSNTOSIMAGEBASE, KDPNTOSIMAGEBASE, etc. also points to kernelbase:

KernelBase = * (dword *) PSNTOSIMAGEBASE

KernelBase = * (dword *) KDPNTOSIMAGEBASE

[LIST_ENTRY PSLOADMODULIST]

PSLoadedModuLIST This global variable points to a bidirectional linked list that holds the loaded drive information.

Through it, it can enumerate all drive modules in the system.

Although many kernel functions have been used in psloadedModuleList, most of them have not been exported, and

Singing from the base address is very spent. For Windows 2000, it is a good idea from the following place:

NT! mmgetsystemRoutineaddress 0x66: 804f0ed0 8b35f0E84680 MOV ESI, [NT! PslineAdModuleList (8046e8f0)]

804f0ed6 81FEF0E84680 CMP ESI, 0X8046E8F0

The process is as follows:

1, ImageBase = loadingLibrarya ("Ntoskrnl.exe")

2, getProcaddress (ImageBase, "MmgetsystemRoutineaddress")

3. Search character code:

* (Word *) (MmgetsystemRoutineaddress i) = 0x358B && /

* (Word *) (MmgetsystemRoutineaddress i 6) = 0xfe81

&&&&

* (DWORD *) (MMgetsystemRoutineaddress i 2) == /

* (DWORD *) (MmgetsystemRoutineadDress i 8)

4, position the address in the kernel:

PslinedModuleList = /

* (DWORD *) (MmgetsystemRoutineaddress i 2) (kernelbase - imagebase)

From SP0 to SP4, I is not the same, but it is definitely not more than 0x100.

For Windows NT, it is not so lucky, there is no ideal API that can be used for positioning, only from

Start search. The following code has a good stability and uniqueness to SP1 ~ SP6A:

801CEB1C: 8B 4D 08 MOV ECX, DWORD PTR [EBP 8]

801ceb1f: 89 01 MOV DWORD PTR [ECX], EAX

801ceb21: 8b 45 0c MOV Eax, DWORD PTR [EBP 0CH]

801 CEB24: 89 10 MOV DWORD PTR [EAX], EDX

801CEB26: 8B 36 MOV ESI, DWORD PTR [ESI]

801 CEB28: 81 Fe 70 0B 15 80 CMP ESI, 80150B70H // PslineedModuleList

If you use the driver to do this, you don't have to violent search, fuzen_op (fuzen_op@yahoo.com)

In Fu_Rootkit 2.0 (Reference Resources [2]) used a more clever code:

DWORD FINDPSLOADMODULIST (in PDRIVER_Object DriverObject)

{

PModule_ENTRY PM_CURRENT;

IF (driverObject == null)

Return 0;

PM_CURRENT = * ((PModule_Entry *) ((DWORD) DriverObject 0x14));

IF (pm_current == null)

Return 0;

Gul_psloadedModuleList = pm_current;

While (PModule_Entry) PM_Current-> le_mod.flink! = gul_psloadedModuleList) {

IF ((pm_current-> unk1 == 0x00000000) && /

(pm_current-> driver_path.length == 0))))

{

Return (DWORD) PM_CURRENT;

}

PM_Current = (Module_ENTRY *) PM_CURRENT-> Le_Mod.flink;

}

Return 0;

}

[List_entry psactiveprocesshead]

In theory, PSACTIVEPROCESSHEAD can also be taken by search code, but there is a simpler

method.

Ntoskrnl.exe exported psinitialsystemprocess is a peprocess, pointing to System into

Cheng's EPROCESS. This Eprocess's structural member eProcess.ActiveProcessLinks.blink is

PSactiveProcesshead:

KD> DT _eprocess ActiveProcessLinks.blink Poi (psinitialsystemprocess)

0x0A0 ActiveProcessLinks: [0x81356900 - 0x8046e728]

0x004 blink: 0x8046e728 [0x81a2fb00 - 0xff5a4CE0]

KD>? PSactiveProcessheadhead

Evaluate Expression: -2142836952 = 8046e728

This structure is different in different operating systems and needs to be treated separately.

[struct _kddebugger_data64 kddebuggerdatablock]

Windows 2000 starts, the system introduces the variable kddebuggerdatablock. It contains a lot of

The kernel variable. If you can get it, you can solve many problems. Unfortunately, there is no in Windows NT.

This variable. WDBGEXTS.H of Windbg SDK contains its structure:

Typedef struct _kddebugger_data64

Because it is relatively long, it is not quoted here.

From the reverse engineering result of the 5.0.2195.6902 version Ntoskrnl.exe, only two functions are used

The variable is not exported, and the two functions are not exported, and there is no obvious feature before and after the code, and it cannot be searched directly.

Code is obtained.

However, we found that ntoskrnl.exe exports KDENABLEDEBUGGER, KDENABLEDEBUGGER

Call KDINITSYSTEM, and KDINITSYSTEM quoted KDDebuggerDataBlock:

N <100

Windows 2000:

KDENABLEDEBUGER N:

6A 00 Push 0

6A 00 Push 0

C6 05 28 41 48 00 01 MOV _poHiberinProgress, 1

E8 1C DC 10 00 Call _kdinitsystem @ 8; kdinitsystem (x, x)

Kdinitsystem N:

68 70 02 00 00 Push 270H // Sizeof (KDDebuggerDataBlock) B9 50 D1 54 00 MOV ECX, Offset _kdpdebuggerDataListHead

68 D8 FA 46 00 Push Offset KddebuggerDataBlock

8b 40 18 MOV EAX, [EAX 18H]

68 4B 44 42 47 Push 4742444BH // "KDBG", can be used as a searcher

A3 3C D1 54 00 MOV DS: _KDPNTOSIMAGEBASE, EAX

89 0D 54 D1 54 00 MOV DS: DWORD_54D154, ECX

89 0D 50 D1 54 00 MOV DS: _KDPDebuggerDataListhead, ECX

Windows XP

KDENABLEDEBUGER N:

6A 00 Push 0

6A 00 Push 0

C6 05 8c 98 47 00 01 MOV _poHiberinProgress, 1

E8 2b 17 13 00 Call _kdinitsystem @ 8; kdinitsystem (x, x)

Kdinitsystem N:

68 90 02 00 00 Push 290h

68 E0 9D 46 00 push offset kddebuggerdatablock

BE 74 96 59 00 MOV ESI, Offset _kdpdebuggerDataListHead

68 4B 44 42 47 Push 4742444BH

89 35 78 96 59 00 MOV DS: DWORD_599678, ESI

89 35 74 96 59 00 MOV DS: _KdpdebuggerDataListHead, ESI

WINDOWS 2003

KDENABLEDEBUGER N:

56 Push ESI

56 Push ESI

C6 05 0C 08 49 00 01 MOV PoHiberinProgres, 1

E8 CB AD 15 00 Call _kdinitsystem @ 8; kdinitsystem (x, x)

Kdinitsystem N:

68 18 03 00 00 push 318h

68 D0 A3 47 00 Push Offset KddebuggerDataBlock

BE 18 10 5D 00 MOV ESI, Offset _kdpdebuggerDataListhead

68 4B 44 42 47 Push 4742444BH

89 35 1C 10 5D 00 MOV DS: DWORD_5D101C, ESI

89 35 18 10 5D 00 MOV DS: _KDPDebuggerDataListhead, ESI

It can be seen that the uniqueness of the above code characteristics is very good. It is no problem for searching for search. I am at the same time.

List three system code, just for comparison, in fact, it is not necessary to take such violent means for Windows XP and Windows 2003.

The following describes how to make Windows XP and Windows 2003.

[struct _dbgkd_get_version64 kdversionblock]

OPC0DE and EDGAR Barbosa mentioned in Reference Resources [3], Windows XP and Windows 2003 introduced

A new kernel variable: kdversionblock, which contains psloadedModuleList.

The structure of KdversionBlock in WDBGEXTS.H of Windbg SDK:

TYPEDEF STRUCT _DBGKD_GET_VERSION64 {

Ushort Majorversion;

Ushort minorversion;

Ushort protocolversion;

Ushort flags;

USHORT MACHINETYPE;

Uchar maxpackettype;

Uchar maxStatechange;

Uchar maxmanipulate;

Uchar simulation;

Ushort unused [1];

Ulong64 kernbase;

Ulong64 pslineedmodulelist;

Ulong64 debuggerDataList;

} DBGKD_GET_VERSION64, * PDBGKD_GET_VERSION64;

KDVERSIONBLOCK is a member of KPCR:

LKD> DT _KPCR ffdff000

NT! _KPCR

0x000 NTTIB: _NT_TIB

0x000 Used_exceptionList: 0xf717dbcc

0x004 USED_STACKBASE: (NULL)

0x008 Perfglobalgroupmask: (NULL)

0x00c TSSCopy: 0x80042000

0x010 Contextswitches: 0x1f8b07a

0x014 setmembercopy: 1

0x018 Used_sel: 0x7ffde000

0x01c Selfpcr: 0xffdff000

0x020 PRCB: 0xffdff120

0x024 Irql: 0x2 ''

0x028 IRR: 0

0x02c Irractive: 0

0x030 IDR: 0xffff24e0

0x034 kdversionblock: 0x8055a3a8 <-

0x038 IDT: 0x8003F400

0x03c GDT: 0x8003F000

0x040 TSS: 0x80042000

0x044 Majorversion: 1

0x046 MinorVersion: 1

0x048 setmember: 1

0x04c stallscalefactor: 0x64

0x050 spareunused: 0 ''

0x051 Number: 0 '' 0x052 SPARE0: 0 ''

0x053 SecondlevelCacheassociative: 0x8 ''

0x054 vdmalert: 0

0x058 kernelreserved: [14] 0

0x090 SecondlevelCachesize: 0x80000

0x094 halnderved: [16] 0

0x0D4 InterruptMode: 0

0x0D8 spare1: 0 ''

0x0dc kernelreserved2: [17] 0

0x120 prcbdata: _Kprcb

The KPCR of Windows 2000 and NT is no such member:

KD> DT _KPCR ffdff000

NT! _KPCR

0x000 NTTIB: _NT_TIB

0x01c Selfpcr: 0xffdff000

0x020 PRCB: 0xffdff120

0x024 Irql: 0 ''

0x028 IRR: 0

0x02c Irractive: 0

0x030 idR: 0xffffffff

0x034 reserved2: 0 <-

0x038 IDT: 0x80036400

0x03c gdt: 0x80036000

0x040 TSS: 0x802a4000

0x044 Majorversion: 1

0x046 MinorVersion: 1

0x048 setmember: 1

0x04c stallscalefactor: 0x64

0x050 DebugActive: 0 ''

0x051 Number: 0 ''

0x052 vdmalert: 0 ''

0x053 Reserved: [1] ""

0x054 kernelreserved: [15] 0

0x090 SECONDLEVELCACECHESIZE: 0

0x094 halnderved: [16] 0

0x0D4 InterruptMode: 0

0x0D8 spare1: 0 ''

0x0dc kernelreserved2: [17] 0

0x120 prcbdata: _Kprcb

KPCR's value on each version of the Windows system is fixed 0xffdff000, which gives us another

Method for obtaining PSLoadedModuleList:

#define kpcr 0xffdff000

PSLoadedModuleList = * (DWORD *) (* (DWORD *) (KPCR 0x34) 0x18)

The structural members of KdversionBlock actually KdpdebuggerDataListhead, and:

KdpdebuggerDataListHead.flink = kddebuggerdatablock

KdpdebuggerDataListHead.blink = kddebuggerdatablock

That is, KDVersionBlock has also obtained KDDebuggerDataBlock.

[NTSYSTEMDEBUGCONTROL to get KDVERSIONBLOCK]

On Windows XP and Windows 2003, KD is running in using the "-kl" parameter, even

There is a load symbol table, which is still able to give the correct PSLoadedModuleList:

Windows Server 2003 Kernel Version 3790 Up Free X86 Compatible

Product: Server, Suite: TerminalServer Singleunrts

Built by: 3790.srv03_rtm.030324-2048

KERNEL BASE = 0x804e0000 psloadedModuleList = 0x8056ac08

Obviously, Windows 5.1 provides a machine that gets psloadedmodulelist and kernelbase

system. Debug the KD with Windbg (boiled bean burning ...) found that dbgeng.dll calls an unknown

Native API NTSystemdebugControl, I got the KDVERSIONBLOCK mentioned above. Call

The process is as follows:

DBGENG! DebugClient :: WaitForEvent

DBGENG! RawwaitForevent

Dbgeng! WaitForanyTarget

DBGENG! LOCALLIVEKERNELTARGETINFO :: WaitForevent

DBGENG! LivekernelTargetInfo :: initfromkdversion

DBGENG! LOCALLIVEKERNELTARGETINFO :: GetTargetkDVersion

NTDLL! NTSYSTEMDEBUGCONTROL

For NTSystemDebugControl, in addition to a vulnerability report of Bugtraq ID 9694, interconnected

No relevant information is found online. (In fact, the question of the author is not a vulnerability, because,

To perform this API, you must have a sedebugprivilege privilege, and under normal circumstances, only administrator users

There is only this privilege. For this vulnerability, see Reference Resources [4]).

The results of reverse engineering show, on Windows XP and Windows 2003, NTSystemDebugControl

Function number 7 will call internal functions KdpsysgetVersion:

__stdcall kdpsysgetversion (x)

Arg_0 = dword PTR 0ch

PUSH ESI

Push EDI

Mov EDI, [ESP ARG_0]

Push 0ah

POP ECX

Mov ESI, Offset _kdversionBlock

REP MOVSD

POP EDI

POP ESI

Retn 4

With NTSystemdebugControl, you can get KDVERSIONBLOCK: TYPEDEF ENUM _DEBUG_CONTROL_CODE {

DebuggetkDVersionBlock = 7

} Debug_control_code;

EnablePrivilege (SE_DEBUG_NAME);

ZWSystemDebugControl

DebuggetkDVersionBlock,

NULL,

0,

& Kdversionblock,

Sizeof (kdversionblock),

NULL

);

Printf ("kernbase: 0x% .8x / n", kdversionblock.kernbase;

Printf ("PslineDModuleList: 0x% .8x / N", KDVERSIONBLOCK.PSLOADMODULELIST);

Printf ("DebuggerDataList: 0x% .8x / N", KDVERSIONBLOCK.DEBUGGGERDATALIST);

In addition to getting KDVERSIONBLOCK, NtsystemDebugControl has a lot of powerful features, I

Will introduce in another document.

Summary now.

For Windows 2000, the most important thing is to search for code, get KDDebuggerDataBlock, get

This, actually gets psloadedmodulelist, psactiveprocesshead, and so on.

For Windows XP and Windows 2003, the best way is to directly use NTSystemDebugControl

Go to KDVERSIONBLOCK and then get KddebuggerDataBlock.

Reference resources:

[1] Several implementation and application of internal nuclear level hook

http://www.xfocus.net/articles/200303/499.html

[2] fu_rootkit 2.0

https://www.rootkit.com/vault/fuzen_op/fu_rootkit.zip

[3] Finding Some Non-Exported Kernel Variables in Windows XP

http://www.rootkit.com/vault/opc0de/getvarxp.pdf

[4] Microsoft Windows NTSystemdebugControl () Kernel API Function Privilege

Escalation Vulnerability

http://www.securityfocus.com/bid/9694

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

New Post(0)