2013-10-21 12 views
5

Sto provando a scrivere uno shellcode che esegue execve. Il programma c equivalente è il seguente:shellcode: passa gli argomenti da eseguire nell'assembly x86_64

int main() 
{ 

    char *argv[3] = {"/bin/sh","-i", "/dev/tty", NULL}; 
    execve("/bin/sh", argv, NULL); 

    return 0; 
} 

Il programma c funziona correttamente. Poi mi tenta di scrivere il mio programma di test come questo (rivisto per spingere null):

#include<stdio.h> 
int main(){ 
    __asm__(
      "xor %rdx,%rdx\n\t" //rdx is the third argument for execve, null in this case. 
      "push %rdx\n\t" 
      "mov -8(%rbp),%rdx\n\t" 
      "mov $0x692d,%rdi\n\t" //$0x6924 is 'i-' 
      "push %rdi\n\t"   //push '-i' to the stack 
      "lea -16(%rbp),%rax\n\t" //now rax points to '-i' 
      "mov $0x31b7f54a83,%rdi\n\t" //the address of /bin/sh 
      "push %rdi\n\t"    //push it to the stack    
      "push %rdx\n\t"    //end the array with null 
      "mov $0x31b7e43bb3,%rdi\n\t" //the address of "/bin/sh" 
      "push %rdi\n\t"    //push the address of "/dev/tty to the stack 
      "push %rax\n\t"    //push the address of '-i' to the stack 
      "mov $0x31b7f54a83,%rdi\n\t" 
      "push %rdi\n\t"    //push the address of /bin/sh again to the stack 
      "mov %rsp,%rsi\n\t"   //rsi now points to the beginning of the array 
      "mov -24(%rbp),%rdi\n\t" //rdi now points to the addresss of "/bin/sh" 
      "mov $0x3b,%rax\n\t"    // syscall number = 59 
      "syscall\n\t" 
    ); 
    } 

ho gli indirizzi delle stringhe nella memoria qui e si può supporre che non cambierà. Ma non abbiamo l'indirizzo della stringa '-i'. Quindi quello che sto facendo qui sta spingendo gli argomenti nello stack in questo modo:


Low     ------------------------------------------------------------------    High 

|addressof"/bin/sh"(rsi points to here)|addressof"-i"|addressof"/dev/ssh"|addressof"/bin/sh"(rdi points to here)|-i| 

Non ha funzionato. Il programma è stato compilato correttamente, ma quando ho eseguito il programma, non è successo nulla.

Non ho familiarità con l'assembly e ho alcune preoccupazioni sul modo in cui gli argomenti vengono passati, ad esempio, come fa il compilatore a sapere quando l'argomento argv termina nella memoria?

EDIT

Grazie al suggerimento di sotto di Niklas B, ho usato traccia per vedere se execve corre in realtà. E ho ottenuto execve(0x31b7f54a83, [0x31b7f54a83, "-i", 0x31b7e43bb3, 0x31b7f54a83, 0x692d], [/* 0 vars */]) = -1 EFAULT (Bad address), il che significa che il secondo argomento è passato male. Tutto ciò che ho inserito nello stack è considerato parte dell'argomento Argv!

Dopo aver inserito i valori nulli nello stack, lo strace restituisce execve(0x31b7f54a83, [0x31b7f54a83, "-i", 0x31b7e43bb3], [/* 0 vars */]) = -1 EFAULT (Bad address). Questo è abbastanza vicino alla risposta giusta solo se gli indirizzi sono stringhe ...

Grazie a Brian, ora vedo dove si trova il problema ora. Gli indirizzi hardcoded sono nella libreria di condivisione di un altro programma. Quindi questo programma non dovrebbe funzionare fino a quando non viene effettivamente inserito in quel programma. Grazie a tutti, aggiornerò appena possibile. Se il problema è risolto, lo contrassegnerò come risolto.

+0

Terminazione null! Terminazione nulla! –

+0

@KerrekSB quindi devo inserire anche 0x00 nello stack? – Gnijuohz

+4

(Non dicendo che questo è legato al tuo problema.) Gli array devono essere terminati da un puntatore nullo. Inoltre, passare 'NULL' come argomento è un hack Linux non portabile, e non dovrebbe essere invocato. Vedi [il manuale] (http://man7.org/linux/man-pages/man2/execve.2.html). –

risposta

2

Come Kerrek SB e user9000 sottolineano nei commenti, la matrice argv doveva essere una matrice con terminazione null di stringhe.

Una volta che è fisso, l'esecuzione di questo programma autonomo ancora non funziona, come le corde "/bin/sh" e "/dev/tty" presumibilmente non esistono in quella posizione nel programma che avete appena compilato, ma piuttosto esiste in quella posizione nel programma che il codice shell è progettato per il targeting. È necessario iniettarlo effettivamente in quel programma in modo che venga eseguito lì, dove tali stringhe sono a tali indirizzi.

+0

Grazie mille, accetterò la tua risposta non appena l'avrò provata. – Gnijuohz

+0

Ciao, ha funzionato ... Ma quando l'ho usato come un attacco di buffer overflow, ho sempre avuto un errore Bus, nessuna idea del perché è successo? – Gnijuohz

+0

@Gnijuohz Non sono sicuro subito. Ti dispiacerebbe postare un'altra domanda con maggiori informazioni sul tuo nuovo problema? Mostra il codice esatto che stai iniettando, in cosa lo stai iniettando, come lo stai facendo e i risultati che ottieni. Sarebbe bene provare a rompere in GDB prima che colpisca il tuo codice e passare attraverso di esso per vedere esattamente dove stai ricevendo l'errore del bus. Questo potrebbe aiutarti a trovarlo, o ti potrebbe dare abbastanza informazioni per porre una nuova domanda in cui qualcuno sarà in grado di aiutarti. –

Problemi correlati