zoukankan      html  css  js  c++  java
  • ip欺骗(原始套接字系列九)

    由于使用Raw Socket的时候,IP报头可完全由程序员自定义,所以我们可以任意地修改本地发送包的IP地址,使得接收方错误的认为IP报文是由欺骗地址发出的。

      下面的程序演示了向某目标发送IP地址伪装的UDP报文的过程:

    void sendPesuoIpUDP(void)
    {
     WSADATA wsd;
     if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
     {
      printf("WSAStartup() failed: %d ", GetLastError());
      return;
     } 
     SOCKET s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,WSA_FLAG_OVERLAPPED); // Create a raw socket
     if (s == INVALID_SOCKET)
     {
      printf("WSASocket() failed: %d ", WSAGetLastError());
      return - 1;
     }

     BOOL bOpt = TRUE;
     int ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char*) &bOpt, sizeof(bOpt));
     // 使用IP_HDRINCL
     if (ret == SOCKET_ERROR)
     {
      printf("setsockopt(IP_HDRINCL) failed: %d ", WSAGetLastError());
      return - 1;
     }

     const int BUFFER_SIZE = 80;
     char buffer[BUFFER_SIZE];

     const char *strMessage = "treat demo"; // Message to send

     // Set IP header
     IP_HDR ipHdr;
     UDP_HDR udpHdr;

     const unsigned short iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
     const unsigned short iIPVersion = 4;
     ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
     ipHdr.ip_tos = 0; // IP type of service
     const unsigned short iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + strlen(strMessage);
     ipHdr.ip_totallength = htons(iTotalSize); // Total packet len
     ipHdr.ip_id = 0; // Unique identifier: set to 0
     ipHdr.ip_offset = 0; // Fragment offset field
     ipHdr.ip_ttl = 128; // Time to live
     ipHdr.ip_protocol = 0x11; // Protocol(UDP)
     ipHdr.ip_checksum = 0; // IP checksum
     const char *target_ip_address = "192.168.0.102";
     const char *treat_ip_address = "1.0.5.7";
     ipHdr.ip_destaddr = inet_addr(target_ip_address); // 接收方IP地址
     ipHdr.ip_srcaddr = inet_addr(treat_ip_address); // 发送方伪造的IP地址

     // Set UDP header
     const u_short uToPort = 8000;
     udpHdr.dst_portno = htons(uToPort); // 接收方端口

     const u_short uFromPort = 1000;
     udpHdr.src_portno = htons(uFromPort); // 发送伪造的端口

     const unsigned short iUdpSize = sizeof(udpHdr) + strlen(strMessage);
     udpHdr.udp_length = htons(iUdpSize);
     udpHdr.udp_checksum = 0;

     // 组建待发送的UDP报文
     ZeroMemory(buffer, BUFFER_SIZE);
     char *ptr = buffer;

     memcpy(ptr, &ipHdr, sizeof(ipHdr));

     ptr += sizeof(ipHdr);
     memcpy(ptr, &udpHdr, sizeof(udpHdr));

     ptr += sizeof(udpHdr);
     memcpy(ptr, strMessage, strlen(strMessage));

     // Apparently, this SOCKADDR_IN structure makes no difference.
     // Whatever we put as the destination IP addr in the IP header is what goes.
     // Specifying a different destination in remote will be ignored.

     sockaddr_in remote;
     remote.sin_family = AF_INET;
     remote.sin_port = htons(8000);
     remote.sin_addr.s_addr = inet_addr("192.168.0.102");

     printf("TO %s:%d ", target_ip_address, uToPort);

     ret = sendto(s, buffer, iTotalSize, 0, (SOCKADDR*) &remote, sizeof(remote));
     // 发送伪造的报文
     if (ret == SOCKET_ERROR)
     {
      printf("sendto() failed: %d ", WSAGetLastError());
     }
     else
      printf("sent %d bytes ", ret);

     closesocket(s);
     WSACleanup();
     return;
    }


      如果我们在第4节描述的ICMP FLOOD攻击中伪造IP地址,则对方将无法检测出究竟是谁在对其进行攻击,实际上,这也是一种非常常用的黑客攻击中隐藏自身的途径。

  • 相关阅读:
    nginx虚拟主机解决企业内外网访问
    oarcle mysql 字段的区别和互换
    大话“扁平化设计”
    使用OGR创建弧形图形
    socket连接和http连接的区别
    nginx tomcat 配置集群负载
    GDAL工具使用示例(一)
    无法解析或打开软件包的列表或是状态文件 解决方案
    程序员们必看,不要让光环效应毁了你辛辛苦苦做的软件
    [spring]Bean注入——在XML中配置
  • 原文地址:https://www.cnblogs.com/happy-pm/p/3809527.html
Copyright © 2011-2022 走看看