前些时候做DOS方面的测试,由于协议学得不够好,有些回应不记得,所以就首先想到用hping来定制一些包,看看远程主机的回应。结果下载 的hping死活都不发包,换了多个不同版本的winpcap都不行。一怒之下,决定自己写个简单的。首先想到的是perl来做,最后觉得一样要安装 winpcap还有很多别的模块,不如直接c来实现一下,来得更痛快。
需要说明一下的是,在以太网头那里我故意偷懒了,没有获取本机的MAC地址而是写了个错误的。所以给内网用户发包的话,能发出去,只是你收不到回应了,发给外网就没这个问题,这是因为同交换机下面靠MAC地址来定位的。
最后一点,这里所有的包,目的MAC地址都是写的MAC,通过网关把数据转发出去的。虽然同交换机下面可以直接通过MAC定位,但是我懒得判断,直接发送给网关再转发会比较简单。
/* Code By yunshu, 2008-05-08, Make tcp packet to send to remote server
* I don’t know which version of winpcap needed by hping, so I wrote this code.
* Under winpcap 4.0.2, Dev-CPP 4.9.9.2, windows xp professional sp2
*/
InBlock.gif#include <stdio.h>
InBlock.gif#include < string.h>
InBlock.gif#include <winsock2.h>
InBlock.gif#include <iphlpapi.h>
InBlock.gif#include <unistd.h>
InBlock.gif#include <pcap.h>
InBlock.gif#include <remote-ext.h>
InBlock.gif
InBlock.gif#define IP_PROTO    0×0800
InBlock.gif
InBlock.gif char    LocalIP[20] = { 0 };
InBlock.gif char    InterfaceName[256] = { 0 };
InBlock.gif char    GatewayIP[20] = { 0 };
InBlock.gifBYTE    GatewayMac[6];
InBlock.gif
InBlock.giftypedef struct et_header
InBlock.gif{
InBlock.gif    unsigned char   eh_dst[6];
InBlock.gif    unsigned char   eh_src[6];
InBlock.gif    unsigned short  eh_type;
InBlock.gif}ET_HEADER;
InBlock.gif
InBlock.giftypedef struct ip_hdr
InBlock.gif{
InBlock.gif    unsigned char       h_verlen;
InBlock.gif    unsigned char       tos;
InBlock.gif    unsigned short      total_len;
InBlock.gif    unsigned short      ident;
InBlock.gif    unsigned short      frag_and_flags;
InBlock.gif    unsigned char       ttl;
InBlock.gif    unsigned char       proto;
InBlock.gif    unsigned short      checksum;
InBlock.gif    unsigned int        sourceIP;
InBlock.gif    unsigned int        destIP;
InBlock.gif}IP_HEADER;
InBlock.gif
InBlock.giftypedef struct tcp_hdr
InBlock.gif{
InBlock.gif    unsigned short    th_sport;
InBlock.gif    unsigned short    th_dport;
InBlock.gif    unsigned int    th_seq;
InBlock.gif    unsigned int    th_ack;
InBlock.gif    unsigned char    th_lenres;
InBlock.gif    unsigned char    th_flag;
InBlock.gif    unsigned short    th_win;
InBlock.gif    unsigned short    th_sum;
InBlock.gif    unsigned short    th_urp;
InBlock.gif}TCP_HEADER;
InBlock.gif
InBlock.giftypedef struct tsd_hdr
InBlock.gif{
InBlock.gif    unsigned long    saddr;
InBlock.gif    unsigned long    daddr;
InBlock.gif     char            mbz;
InBlock.gif     char            ptcl;
InBlock.gif    unsigned short    tcpl;
InBlock.gif}PSD_HEADER;
InBlock.gif
InBlock.gifunsigned short CheckSum(unsigned short * buffer, int size)
InBlock.gif{
InBlock.gif    unsigned long   cksum = 0;
InBlock.gif
InBlock.gif     while (size > 1)
InBlock.gif    {
InBlock.gif        cksum += *buffer++;
InBlock.gif        size -= sizeof(unsigned short);
InBlock.gif    }
InBlock.gif     if (size)
InBlock.gif    {
InBlock.gif        cksum += *(unsigned char *) buffer;
InBlock.gif    }
InBlock.gif    cksum = (cksum >> 16) + (cksum & 0xffff);
InBlock.gif    cksum += (cksum >> 16);
InBlock.gif
InBlock.gif     return (unsigned short) (~cksum);
InBlock.gif}
InBlock.gif
InBlock.gif /*
InBlock.gifvoid GetLocalIP( )
InBlock.gif{
InBlock.gif    WORD        wVersionRequested;
InBlock.gif    WSADATA        wsaData;
InBlock.gif    char        name[255];
InBlock.gif    PHOSTENT    hostinfo;  
InBlock.gif
InBlock.gif    wVersionRequested = MAKEWORD( 2, 0 );
InBlock.gif
InBlock.gif    if( WSAStartup( wVersionRequested, &wsaData ) == 0 )
InBlock.gif    {
InBlock.gif        if( gethostname( name, sizeof(name) ) == 0 )
InBlock.gif        {
InBlock.gif            if( (hostinfo = gethostbyname(name) ) != NULL )
InBlock.gif            {
InBlock.gif                strcpy( LocalIP, inet_ntoa( *(struct in_addr*)*hostinfo->h_addr_list ) );
InBlock.gif            }
InBlock.gif        }
InBlock.gif    }
InBlock.gif
InBlock.gif    WSACleanup(   );
InBlock.gif}
InBlock.gif*/

InBlock.gif
InBlock.gif int GetDevices( )
InBlock.gif{
InBlock.gif    pcap_if_t    *alldevs;
InBlock.gif    pcap_if_t    *d;
InBlock.gif
InBlock.gif     int i = 0;
InBlock.gif     char errbuf[PCAP_ERRBUF_SIZE];
InBlock.gif
InBlock.gif     /* 获取本地机器设备列表 */
InBlock.gif     if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
InBlock.gif    {
InBlock.gif        fprintf(stderr,”Error in pcap_findalldevs_ex: %s\n“, errbuf);
InBlock.gif        exit(1);
InBlock.gif    }
InBlock.gif
InBlock.gif     /* 打印列表 */
InBlock.gif     for( d = alldevs; d != NULL; d = d->next )
InBlock.gif    {
InBlock.gif        printf(”%d. %s“, ++i, d->name);
InBlock.gif
InBlock.gif         if (d->description)
InBlock.gif        {
InBlock.gif            printf( “ (%s)“, d->description );
InBlock.gif        }
InBlock.gif
InBlock.gif         if( d->addresses != NULL )
InBlock.gif        {
InBlock.gif             if( d->addresses->addr->sa_family == AF_INET )
InBlock.gif            {
InBlock.gif
InBlock.gif                printf( “: %s\n“, inet_ntoa( (( struct sockaddr_in *)d->addresses->addr)->sin_addr ) );
InBlock.gif            }
InBlock.gif             else
InBlock.gif            {
InBlock.gif                printf( “\n” );
InBlock.gif            }
InBlock.gif        }
InBlock.gif         else
InBlock.gif        {
InBlock.gif            printf(” (No description available)\n“);
InBlock.gif        }
InBlock.gif    }
InBlock.gif
InBlock.gif     if (i == 0)
InBlock.gif    {
InBlock.gif        printf(”\nNo interfaces found! Make sure WinPcap is installed.\n“);
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif
InBlock.gif    printf( “\nPlease choose the index of your NetAdapter:” );
InBlock.gif     int    AdapterIndex = 1;
InBlock.gif    scanf( “%d“, &AdapterIndex );
InBlock.gif     if( AdapterIndex > i )
InBlock.gif    {
InBlock.gif        printf( “网卡选错啦\n” );
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif
InBlock.gif    d = alldevs;
InBlock.gif     for( int index = 1; index < AdapterIndex; index ++ )
InBlock.gif    {
InBlock.gif        d = d->next;
InBlock.gif    }
InBlock.gif
InBlock.gif     if( d->name == NULL || d->addresses == NULL )
InBlock.gif    {
InBlock.gif        printf( “网卡选错啦\n” );
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif
InBlock.gif    strcpy( InterfaceName, d->name );
InBlock.gif    strcpy( LocalIP, inet_ntoa( (( struct sockaddr_in *)d->addresses->addr)->sin_addr ) );
InBlock.gif
InBlock.gif     /* 不再需要设备列表了,释放它 */
InBlock.gif    pcap_freealldevs(alldevs);
InBlock.gif
InBlock.gif     return 1;
InBlock.gif}
InBlock.gif
InBlock.gif int GetGateWayMac( )
InBlock.gif{
InBlock.gif    PIP_ADAPTER_INFO AdapterInfo;
InBlock.gif
InBlock.gif    ULONG    OutBufLen = sizeof(IP_ADAPTER_INFO);
InBlock.gif    AdapterInfo = (IP_ADAPTER_INFO *)malloc( sizeof (IP_ADAPTER_INFO));
InBlock.gif     if( AdapterInfo == NULL )
InBlock.gif    {
InBlock.gif        printf(”Error allocating memory needed to call GetAdaptersinfo\n“);
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif
InBlock.gif     if( GetAdaptersInfo( AdapterInfo, &OutBufLen ) == ERROR_BUFFER_OVERFLOW )
InBlock.gif    {
InBlock.gif        free( AdapterInfo );
InBlock.gif        AdapterInfo = (IP_ADAPTER_INFO *)malloc( OutBufLen );
InBlock.gif         if( AdapterInfo == NULL )
InBlock.gif        {
InBlock.gif            printf(”Error allocating memory needed to call GetAdaptersinfo\n“);
InBlock.gif             return -1;
InBlock.gif        }
InBlock.gif    }
InBlock.gif
InBlock.gif     if( GetAdaptersInfo( AdapterInfo, &OutBufLen ) == NO_ERROR )
InBlock.gif    {
InBlock.gif        PIP_ADAPTER_INFO    a = AdapterInfo;
InBlock.gif        BOOL                Found = FALSE;
InBlock.gif
InBlock.gif         while( a )
InBlock.gif        {
InBlock.gif             if( strcmp(a->IpAddressList.IpAddress.String, LocalIP) == 0 )
InBlock.gif            {
InBlock.gif                strcpy( GatewayIP, a->GatewayList.IpAddress.String );
InBlock.gif                Found = TRUE;
InBlock.gif                 break;
InBlock.gif            }
InBlock.gif            a = a->Next;
InBlock.gif        }
InBlock.gif         if( !Found )
InBlock.gif        {
InBlock.gif            printf( “Get gateway’s ip error.\n” );
InBlock.gif            free( AdapterInfo );
InBlock.gif             return -1;
InBlock.gif        }
InBlock.gif         else
InBlock.gif        {
InBlock.gif            free( AdapterInfo );
InBlock.gif        }
InBlock.gif    }
InBlock.gif     else
InBlock.gif    {
InBlock.gif        printf( “Get gateway’s ip error.\n” );
InBlock.gif        free( AdapterInfo );
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif
InBlock.gif    BYTE    Mac[6];
InBlock.gif    ULONG    MacLen = 6;
InBlock.gif    SendARP( inet_addr(GatewayIP), 0, (PULONG)&Mac, &MacLen );
InBlock.gif    memcpy( GatewayMac, Mac, MacLen );
InBlock.gif
InBlock.gif     /*
InBlock.gif    for( int index = 0; index < MacLen; index ++ )
InBlock.gif    {
InBlock.gif        printf( “%d: %02x\n”, index, Mac[index] );
InBlock.gif    }
InBlock.gif    printf( “\n%d\n”, MacLen );
InBlock.gif    */

InBlock.gif}
InBlock.gif
InBlock.gif void Usage( char *me )
InBlock.gif{
InBlock.gif    printf( “Make tcp package 0.1, code by yunshu\n” );
InBlock.gif    printf( “%s:   targetip  targetport [flag]\n“, me );
InBlock.gif    printf( “flag: \n” );
InBlock.gif    printf( “      u|U     set urg flag.\n” );
InBlock.gif    printf( “      a|A     set ack flag.\n” );
InBlock.gif    printf( “      p|P     set push flag.\n” );
InBlock.gif    printf( “      r|R     set rst flag.\n” );
InBlock.gif    printf( “      s|S     set syn flag.\n” );
InBlock.gif    printf( “      f|F     set fin flag.\n” );
InBlock.gif    printf( “       default is syn flag, and you can use sa to set syn+ack, and more…\n” );
InBlock.gif}
InBlock.gif
InBlock.gif int main( int argc, char *argv[] )
InBlock.gif{
InBlock.gif    ET_HEADER    EtHeader;
InBlock.gif    IP_HEADER    IpHeader;
InBlock.gif    TCP_HEADER    TcpHeader;
InBlock.gif    PSD_HEADER    PsdHeader;
InBlock.gif    u_char        Buffer[ sizeof(ET_HEADER) + sizeof(IP_HEADER) + sizeof(TCP_HEADER)] = { 0 };
InBlock.gif
InBlock.gif     if( (argc != 3) && (argc != 4) )
InBlock.gif    {
InBlock.gif        Usage( argv[0] );
InBlock.gif        exit( -1 );
InBlock.gif    }
InBlock.gif
InBlock.gif     int    Flag = 2;
InBlock.gif     if( argc == 4 )
InBlock.gif    {
InBlock.gif        Flag = 0;
InBlock.gif         if( strchr(argv[3], ‘U’) || strchr(argv[3], ‘u’) )
InBlock.gif        {
InBlock.gif            Flag = Flag | 32;
InBlock.gif        }
InBlock.gif         if( strchr(argv[3], ‘A’) || strchr(argv[3], ‘a’) )
InBlock.gif        {
InBlock.gif            Flag = Flag | 16;
InBlock.gif        }
InBlock.gif         if( strchr(argv[3], ‘P’) || strchr(argv[3], ‘p’) )
InBlock.gif        {
InBlock.gif            Flag = Flag | 8;
InBlock.gif        }
InBlock.gif         if( strchr(argv[3], ‘R’) || strchr(argv[3], ‘r’) )
InBlock.gif        {
InBlock.gif            Flag = Flag | 4;
InBlock.gif        }
InBlock.gif         if( strchr(argv[3], ‘S’) || strchr(argv[3], ’s’) )
InBlock.gif        {
InBlock.gif            Flag = Flag | 2;
InBlock.gif        }
InBlock.gif         if( strchr(argv[3], ‘F’) || strchr(argv[3], ‘f’) )
InBlock.gif        {
InBlock.gif            Flag = Flag | 1;
InBlock.gif        }
InBlock.gif    }
InBlock.gif
InBlock.gif     //GetLocalIP( );
InBlock.gif     if( -1 == GetDevices( ) )
InBlock.gif    {
InBlock.gif        exit( -1 );
InBlock.gif    }
InBlock.gif
InBlock.gif     //printf( “Adapter is %s, ip is %s\n”, InterfaceName, LocalIP );
InBlock.gif
InBlock.gif     if( -1 == GetGateWayMac( ) )
InBlock.gif    {
InBlock.gif        exit( -1 );
InBlock.gif    }
InBlock.gif
InBlock.gif     //printf( “Gateway IP is %s\n”, GatewayIP );
InBlock.gif     //printf( “Gateway Mac is %x\n”, *GatewayMac );
InBlock.gif
InBlock.gif    memcpy( EtHeader.eh_dst, GatewayMac, 6 );
InBlock.gif    memset( EtHeader.eh_src, 0xa, 6 );
InBlock.gif    EtHeader.eh_type = htons( IP_PROTO );
InBlock.gif
InBlock.gif    IpHeader.h_verlen = (4<<4 | sizeof(IpHeader)/ sizeof(unsigned int));
InBlock.gif    IpHeader.tos = 0;
InBlock.gif    IpHeader.total_len = htons( sizeof(IpHeader)+ sizeof(TcpHeader));
InBlock.gif    IpHeader.ident = 1;
InBlock.gif    IpHeader.frag_and_flags = 0×40;
InBlock.gif    IpHeader.ttl = 128;
InBlock.gif    IpHeader.proto = IPPROTO_TCP;
InBlock.gif    IpHeader.checksum = 0;
InBlock.gif    IpHeader.sourceIP = inet_addr( LocalIP );
InBlock.gif    IpHeader.destIP = inet_addr( argv[1] );
InBlock.gif
InBlock.gif    TcpHeader.th_sport = htons( rand()%60000 + 1024 );
InBlock.gif    TcpHeader.th_dport = htons( atoi(argv[2]) );
InBlock.gif    TcpHeader.th_seq = htonl( rand()%900000000 + 100000 );
InBlock.gif    TcpHeader.th_ack = 0;
InBlock.gif    TcpHeader.th_lenres = ( sizeof(TcpHeader)/4<<4|0);
InBlock.gif    TcpHeader.th_flag = Flag;
InBlock.gif    TcpHeader.th_win = htons(512);
InBlock.gif    TcpHeader.th_sum = 0;
InBlock.gif    TcpHeader.th_urp = 0;
InBlock.gif
InBlock.gif    PsdHeader.saddr = inet_addr( LocalIP );
InBlock.gif    PsdHeader.daddr = IpHeader.destIP;
InBlock.gif    PsdHeader.mbz = 0;
InBlock.gif    PsdHeader.ptcl = IPPROTO_TCP;
InBlock.gif    PsdHeader.tcpl = htons( sizeof(TcpHeader));
InBlock.gif
InBlock.gif    memcpy( Buffer, &PsdHeader, sizeof(PsdHeader) );
InBlock.gif    memcpy( Buffer + sizeof(PsdHeader), &TcpHeader, sizeof(TcpHeader) );
InBlock.gif    TcpHeader.th_sum = CheckSum( (unsigned short *)Buffer, sizeof(PsdHeader) + sizeof(TcpHeader) );
InBlock.gif
InBlock.gif    memset( Buffer, 0, sizeof(Buffer) );
InBlock.gif    memcpy( Buffer, &IpHeader, sizeof(IpHeader) );
InBlock.gif    IpHeader.checksum = CheckSum( (unsigned short *)Buffer, sizeof(IpHeader) );
InBlock.gif
InBlock.gif    memset( Buffer, 0, sizeof(Buffer) );
InBlock.gif    memcpy( Buffer, ( void *)&EtHeader, sizeof(ET_HEADER) );
InBlock.gif    memcpy( Buffer + sizeof(ET_HEADER), ( void *)&IpHeader, sizeof(IP_HEADER) );
InBlock.gif    memcpy( Buffer + sizeof(ET_HEADER) + sizeof(IP_HEADER), ( void *)&TcpHeader, sizeof(TCP_HEADER) );
InBlock.gif
InBlock.gif     char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
InBlock.gif    pcap_t *fp;
InBlock.gif     if ( (fp= pcap_open( InterfaceName, 100, PCAP_OPENFLAG_PROMISCUOUS, 100, NULL, errbuf ) ) == NULL )
InBlock.gif    {
InBlock.gif        fprintf(stderr,”\nUnable to open the adapter. %s is not supported by WinPcap\n“, InterfaceName );
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif
InBlock.gif     if ( pcap_sendpacket( fp, Buffer, sizeof(Buffer) ) != 0 )
InBlock.gif    {
InBlock.gif        fprintf(stderr,”\nError sending the packet: \n“, pcap_geterr(fp));
InBlock.gif         return -1;
InBlock.gif    }
InBlock.gif    printf( “send ok!\nData is:\n” );
InBlock.gif
InBlock.gif     for( int i = 0; i < sizeof(Buffer); i ++ )
InBlock.gif    {
InBlock.gif         printf( “%02x “, Buffer );
InBlock.gif    }
InBlock.gif
InBlock.gif     return 0;
InBlock.gif}