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.
Terminazione null! Terminazione nulla! –
@KerrekSB quindi devo inserire anche 0x00 nello stack? – Gnijuohz
(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). –