2015-08-08 12 views
5

Sto cercando di imparare a eseguire shellcode da un programma, ma non riesco a ottenere nemmeno il codice di base da eseguire. Il seguente codice dovrebbe uscire dal terminale quando viene eseguito:Trasmissione di una stringa di caratteri come funzione

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <sys/mman.h> 

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80"; 

int main() { 
    int (*func)(); 
    func = (int (*)())exitcode; 
    (int)(*func)(); 
    return 0; 
} 

Ma tutto quello che ottengo è un segfault. GDB dice che sta accadendo quando il programma accede alla locazione di memoria di exitcode [at (int) (* func)(); ], ma non sono sicuro del motivo per cui ciò sta causando un problema. Sono in esecuzione un sistema operativo Linux Mint a 64 bit. Qualsiasi aiuto è molto apprezzato.

+0

Se la memoria per lo shellcode si trova in una regione non eseguibile, questo non funzionerà. La maggior parte dei sistemi operativi moderni probabilmente non lo consentiranno. Dovresti anche assicurarti che lo shellcode sia corretto per la tua architettura. –

+1

È quello per C o C++? Semantica e possibili risposte possono essere diverse. – Olaf

+0

Lanciare un puntatore a un puntatore a una funzione è _undefined behaviour_. Tutto può succedere – Olaf

risposta

6

I sistemi operativi moderni utilizzano la protezione della memoria. Le pagine di memoria hanno diritti di accesso come i file: leggibili, scrivibili, eseguibili. Il segmento di dati del tuo programma si trova in genere in una pagina non eseguibile, il tentativo di eseguirlo risulta in un segfault.

Se si desidera eseguire codice binario scritto dinamicamente dal programma su linux, è necessario prima mappare una pagina utilizzando mmap() a cui è possibile scrivere, quindi inserire il proprio codice lì e quindi modificarlo in sola lettura, eseguibile utilizzando mprotect(). POI puoi saltare lì.

Si potrebbe ad esempio read this article per i dettagli.

EDIT: Se si tratta di violazioni della sicurezza, si noti che lo stack in genere non è eseguibile anche oggi ... quindi tutte queste vecchie "esercitazioni di hacking" non funzioneranno più. Se ti interessano le tecniche più recenti, leggi la programmazione orientata al ritorno.

0

tuo shellcode è:

mov $0x1,%al 
xor %ebx,%ebx 
int $0x80 

ci sono due problemi:

  1. Syscall 0x1 è uno sys_write a 64 bit (ma a 32 bit è sys_exit)
  2. È necessario assegnare a% rax, non% al. % rax conterrà gli avanzi in bit alti.
4

Il codice deve essere contrassegnato come codice eseguibile. Un modo per farlo è copiare questo codice macchina binaria nel buffer eseguibile.

#include <unistd.h> 
#include <sys/mman.h> 
#include <string.h> 

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80"; 

int main(int argc, char **argv) 
{ 
    void *buf; 

    /* copy code to executable buffer */  
    buf = mmap (0,sizeof(exitcode),PROT_READ|PROT_WRITE|PROT_EXEC, 
       MAP_PRIVATE|MAP_ANON,-1,0); 
    memcpy (buf, exitcode, sizeof(code)); 

    /* run code */ 
    int i = ((int (*) (void))buf)(); 
    printf("OK. returned: %d", i); 
return 0; 
} 
0

Ho avuto questo problema e ho cercato molto per risolverlo.

È necessario utilizzare questo codice per compilare il codice C (Per disattivare la protezione dello stack e renderlo eseguibile):

gcc -fno-stack-protector -z execstack -o hello hello.c 

testato in Kali 32/64 bit. Nessun segfault più.

Buona fortuna

Problemi correlati