30 de abril de 2010

Funcionalidades pouco conhecidas ou usadas do Netcat

Introdução

Ainda que haja muitos artigos sobre esse tema, talvez muitas pessoas utilizam o Netcat apenas para conseguir um shell reverso ou descobrir o sistema operacional de um alvo e varrer suas portas.

Além das operações citadas, há muitas outras funcionalidades que esse canivete suíço nos oferece, e que em algum dado momento possa nos servir de ajuda.

Esse artigo não pretende ser um guia completo, mas simplesmente um ponto de partida para atiçar a curiosidade em explorar um pouco mais os possíveis usos do Netcat.

Transferência de arquivos

Há momento em que precisamos transferir arquivos de um host à outro e não sabemos como, e o Netcat nos oferece um caminho fácil de conseguí-lo, sem necessidade de montar um servidor FTP ou qualquer outra coisa do tipo.

É tão fácil como o que está a seguir.

No servidor:

# netcat -l -p 5050 > pass.txt

No cliente:

# cat pass.txt | netcat ip_server 5050

Com isso conseguimos enviar sem problemas um simples arquivo de texto, mas... O que acontece se quisermos ir mais além e enviar um binário (um executável, um arquivo do OpenOffice.org ,...)?

Vamos tentar o seguinte.

No servidor:

# netcat -l -p 5050 > exemplo.odt

No cliente:

# cat saida.odt | netcat ip_server 5050

E agora vamos comprovar (supondo que o exemplo tenha sido realizado na mesma máquina):

# diff exemplo.odt saida.odt

Como vemos, não há NENHUMA diferença, assim podemos transferir binários sem problemas...


Relays utilizando Netcat

Para esse exercício precisamos de 3 máquinas diferentes. Criaremos um relay na máquina Linux utilizando o Netcat executando-o no modo de escuta e como cliente. Esse encaminhamento dirigirá os dados de uma primeira máquina (A) para outra (B).

Esta máquina de encaminhamento conectará a primeira máquina, executando o Netcat em modo cliente, com uma terceira máquina (C) executando o Netcat em modo servidor, ou de escuta.

Uma vez estabelecida a conexão, o encaminhamento permitirá o acesso a esta última máquina a partir da máquina original.

O host intermediário serve de proxy, de forma que nos conectamos à ele e ele nos conecta ao servidor final, deste modo conseguindo que seja mais difícil nos rastrear, já que nos logs do servidor aparecerá o IP do host relay. Obviamente que quanto mais hosts intermediários utilizarmos, mais difícil será a tarefa de nos rastrear.

Uma maneira de criarmos relays, é unir a entrada e a saída de um cliente e servidor Netcat utilizando um arquivo especial denominado FIFO (Firts In, First Out). Podemos criar um arquivo FIFO e utilizá-lo para unir um Netcat em modo servidor com um cliente através dos seguintes comandos:

# mknod backpipe p
# nc -l -p [portaA] 0backpipe


Onde a portaA é a porta onde o relay está escutando e Porta_Destino a porta da máquina destino (IP_Destino) onde configuramos um backdoor com o shell. É importante não colocar espaços nos direcionamentos (>,<). Estes redirecionamentos permitem dirigir a entrada e saída padrão para um backpipe e não podem ter espaços neles.

Para que isso funcione, é necessário que caso tenhamos um filtro de pacotes rodando, permitamos o envio de pacotes à máquina C. É possível que se estivermos com o iptables ativo (funcionando como firewall), isso não será permitido. Podemos desativar o iptables do seguinte modo:

# /etc/init.d/iptables stop

Bem, mãos à obra, como escrevi antes, vamos precisar de três máquina (no meu caso, o próprio host onde trabalho, e 2 máquinas virtuais), os IPs são os seguintes:
  • Servidor: 192.168.1.129
  • Relay: 172.16.72.135
  • Cliente: 172.16.72.136

Vamos em frente.

No servidor, deixamos o Netcat escutando uma porta com um shell de presente:

# nc -l -p 5555

No relay, criamos o FIFO, e através dos direcionamentos fazemos as conexões:

# mknod buffer p
# netcat -l -p 1111 0buffer


Como podemos observar, primeiro criamos o buffer com ajuda do mknod, e depois usamos o mesmo para unir a entrada padrão (que nesse caso será aquilo que o cliente nos enviará através do Netcat) com a conexão no servidor e armazenar de novo a saída dessa última conexão no buffer, que será encaminhado para o cliente.

Finalmente, nos conectamos a partir do nosso cliente e observamos que temos o shell com o servidor:

# netcat 172.16.72.135
# pwd

/home/XXXX

Para nos asseguramos que a conexão a partir de nosso cliente até o servidor, tenha sido "mascarada" pelo relay, verificamos no servidor as conexões ativas, filtrando, por exemplo, a porta 5555 que é onde estamos "escutando", e obtemos o seguinte:

# netstat -aveptn | grep 5555
tcp 0 0 192.168.1.129:5555 172.16.72.135:51220 ESTABELECIDO 1000 44068 9038/bash

Vemos que, efetivamente, alguém se conectou em nossa porta 5555, que possui um shell (bash) e que a conexão vem do relay (172.16.72.135:51220).


Uso como scanner

Podemos encontrar alguma situação em que não temos o NMap ou algum outro programa à mão, no entanto, sempre poderemos lançar mão do Netcat e usá-lo como um scanner de portas (um pouco barulhento e tosco... rs).

Por exemplo:

# nc -vv 127.0.0.1 22-25
localhost [127.0.0.1] 25 (smtp) : Connection refused
localhost [127.0.0.1] 24 (?) : Connection refused
localhost [127.0.0.1] 23 (telnet) : Connection refused
localhost [127.0.0.1] 22 (ssh) open
SSH-2.0-OpenSSH_4.7p1 Debian

Enviar e-mail

É sempre divertido interagir com protocolos de rede baseados em texto com nada mais do que o Netcat e um teclado. Segue um pequeno exemplo mostrando como enviar e-mails comunicando-se com um servidor SMTP. O SMTP está descrito na RFC 5321, mas não é necessário muito sobre o protocolo para enviar uma simples mensagem. O serviço está vinculado à porta 25, e utilizaremos o parâmetro -C porque o mesmo é requerido para finalizações de linha (CRLF). O exemplo abaixo possui a transcrição de uma sessão:

$ ncat -C mail.exemplo.com 25
220 mail.exemplo.com ESMTP
HELO cliente.exemplo.com
250 mail.exemplo.com Olá cliente.exemplo.com
MAIL FROM:a@exemplo.com
250 OK
RCPT TO:b@exemplo.com
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
From: a@exemplo.com
To: b@exemplo.com
Subject: Saudações!

Olá. Esta é uma pequena mensagem enviado pelo netcat.
.

250 OK
QUIT
221 mail.exemplo.com closing connection

Para fazer esse exemplo funcionar, altere o mail.exemplo.com para o seu servidor SMTP e o cliente.exemplo.com para o seu domínio. Naturalmente mudará o endereço de e-mail e a mensagem também. Isso funcionará utilizando seu servidor de e-mail válido, com seu endereço real, ou quando utilizar o servidor de e-mail do remetente (procure pelo registro MX para o domínio em seu endereço de e-mail).

Obviamente que esta técnica pode ser utilizada para mais do que apenas enviar emails. Netcat é uma grande ferramenta de debug para qualquer protocolo baseado em texto. O debug é feito algumas vezes com o comando telnet, pois ele provê algo como uma resposta em texto bruto. Porém, o Netcat possui algumas vantagens sobre o telnet. O Netcat não exibe nada além do que é enviado pelo host remoto. O telnet não é tão bom para dados binários arbitrários, pois reserva alguns bytes como caracteres de controle. Além do mais, telnet não funciona com o protocolo UDP.


Encadeando netcats

Netcat foi desenvolvido para trabalhar com um pipeline, então naturalmente a saída de uma instância do Netcat pode alimentar a entrada de outro. Abaixo segue uma maneira de enviar um arquivo de log de um host para outro através de um intermediário:

host3# ncat -l > log.txt
host2# ncat -l | ncat host3
host1# ncat --send-only host2 <>

Um possível problema com esta técnica é que funciona em "mão única": host1 pode enviar, mas não é possível para o host3 enviar qualquer coisa para o host1. Nesse caso não importa, mas isso pode ser feito com algumas pequenas mudanças. Vejamos:

host3# ncat -l > log.txt
host2# ncat -l --sh-exec "ncat host3"
host1# ncat --send-only host2 <>

O Netcat em modo de escuta no host2, ao receber uma conexão cria um "novo netcat" para falar com o host3 e conecta a entrada e saída do programa em execução no host1 e host3 encadeando-os. Esse mesmo "macete" pode ser utilizado em um host local também. O exemplo a seguir direciona a porta 8080 para o servidor web exemplo.org.br:

# ncat -l localhost 8080 --sh-exec "ncat exemplo.org.br 80"

Simulando SSL

Suponhamos que precise conectar em um servidor IMAP que requeira SSL, mas seu leitor de e-mails mão suporta SSL. O Netcat pode agir como uma ponta criptografada para conectar o cliente e o servidor. Conectaremos o cliente de e-mail à uma porta local e o Netcat encaminhará o tráfego, encriptado, para o servidor. Abaixo está como conectar o IMAP (porta 143) no host local ao IMAP com SSL (porta 993) no imap.exemplo.com.

# ncat -l localhost 143 --sh-exec "ncat --ssl imap.exemplo.com 993"

Uma vez que isso tenha sido executado, instrua o cliente de e-mail a conectar ao servidor IMAP no host local (localhost).

Esse "macete" funciona com protocolos que enviem o tráfego estritamente entre dois hosts. Não funciona muito bem para HTTP porque envolve hostnames e frequentemente envolve múltiplos hosts.

SSH através de um túnel Netcat

Com o Netcat e OpenSSH, é possível executar o SSH para um host atrás de um roteador com NAT sem precisar direcionar as portas no roteador. O roteador precisa ter o Netcat instalado. Abaixo segue como conectar via SSH à um host através de um roteador:

# ssh -o ProxyCommand="ssh -q ncat %h %p"

A opção ProxyCommand do ssh diz como abrir a conexão SSH para o host. Isso é feito abrindo outra sessão SSH para o roteador e conectando-o ao host com o Netcat.

E mais...

Há muitas coisas mais que podemos fazer com essa fantástica ferramenta, como por exemplo:
  • um programa de força bruta (bruteforce): poderíamos criar um dicionário e mandar palavra por palavra à uma porta, de forma que quando encontre a senha correta, faça o registro.
  • enumeração de serviços: basta conectar-se com a porta que queremos extrair a informação do serviço e guardar sua resposta para analisá-la posteriormente.
  • mini-chat: ainda que não acredite, isso pode ser feito :-)

E isso é apenas a ponta do iceberg...

Um comentário:

  1. Olá, Luiz Vieira

    Sou do PR da Ogilvy e preciso enviar um email a você. Pode por gentileza me enviar seu contato no email amanda.voltolini@ogilvy.com?
    Obrigada

    ResponderExcluir