使用winpcap定制TCP包发送

来源:互联网 发布:天天射网络平台色情 编辑:程序博客网 时间:2024/05/16 06:21

导读:
  前些时候做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
*/
#include
#include
#include
#include
#include
#include
#include
#define IP_PROTO 0x0800
charLocalIP[20] = { 0 };
charInterfaceName[256] = { 0 };
charGatewayIP[20] = { 0 };
BYTE GatewayMac[6];
typedefstructet_header
{
unsignedchareh_dst[6];
unsignedchareh_src[6];
unsignedshorteh_type;
}ET_HEADER;
typedefstructip_hdr
{
unsignedcharh_verlen;
unsignedchartos;
unsignedshorttotal_len;
unsignedshortident;
unsignedshortfrag_and_flags;
unsignedcharttl;
unsignedcharproto;
unsignedshortchecksum;
unsignedintsourceIP;
unsignedintdestIP;
}IP_HEADER;
typedefstructtcp_hdr
{
unsignedshortth_sport;
unsignedshortth_dport;
unsignedintth_seq;
unsignedintth_ack;
unsignedcharth_lenres;
unsignedcharth_flag;
unsignedshortth_win;
unsignedshortth_sum;
unsignedshortth_urp;
}TCP_HEADER;
typedefstructtsd_hdr
{
unsignedlongsaddr;
unsignedlongdaddr;
charmbz;
charptcl;
unsignedshorttcpl;
}PSD_HEADER;
unsignedshortCheckSum(unsignedshort* buffer, intsize)
{
unsignedlongcksum = 0;
while(size >1)
{
cksum += *buffer++;
size -= sizeof(unsignedshort);
}
if(size)
{
cksum += *(unsignedchar*) buffer;
}
cksum = (cksum >>16) + (cksum &0xffff);
cksum += (cksum >>16);
return(unsignedshort) (~cksum);
}
/*
void GetLocalIP( )
{
WORD wVersionRequested;
WSADATA wsaData;
char name[255];
PHOSTENT hostinfo;
wVersionRequested = MAKEWORD( 2, 0 );
if( WSAStartup( wVersionRequested, &wsaData ) == 0 )
{
if( gethostname( name, sizeof(name) ) == 0 )
{
if( (hostinfo = gethostbyname(name) ) != NULL )
{
strcpy( LocalIP, inet_ntoa( *(struct in_addr*)*hostinfo->h_addr_list ) );
}
}
}
WSACleanup( );
}
*/
intGetDevices( )
{
pcap_if_t *alldevs;
pcap_if_t *d;
inti = 0;
charerrbuf[PCAP_ERRBUF_SIZE];
/* 获取本地机器设备列表 */
if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs_ex: %s/n", errbuf);
exit(1);
}
/* 打印列表 */
for( d = alldevs; d != NULL; d = d->next )
{
printf("%d. %s", ++i, d->name);
if(d->description)
{
printf( "(%s)", d->description );
}
if( d->addresses != NULL )
{
if( d->addresses->addr->sa_family == AF_INET )
{
printf( ": %s/n", inet_ntoa( ((structsockaddr_in *)d->addresses->addr)->sin_addr ) );
}
else
{
printf( "/n" );
}
}
else
{
printf("(No description available)/n");
}
}
if(i == 0)
{
printf("/nNo interfaces found! Make sure WinPcap is installed./n");
return-1;
}
printf( "/nPlease choose the index of your NetAdapter:" );
intAdapterIndex = 1;
scanf( "%d", &AdapterIndex );
if( AdapterIndex >i )
{
printf( "网卡选错啦/n" );
return-1;
}
d = alldevs;
for( intindex = 1; index {
d = d->next;
}
if( d->name == NULL || d->addresses == NULL )
{
printf( "网卡选错啦/n" );
return-1;
}
strcpy( InterfaceName, d->name );
strcpy( LocalIP, inet_ntoa( ((structsockaddr_in *)d->addresses->addr)->sin_addr ) );
/* 不再需要设备列表了,释放它 */
pcap_freealldevs(alldevs);
return1;
}
intGetGateWayMac( )
{
PIP_ADAPTER_INFO AdapterInfo;
ULONG OutBufLen = sizeof(IP_ADAPTER_INFO);
AdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
if( AdapterInfo == NULL )
{
printf("Error allocating memory needed to call GetAdaptersinfo/n");
return-1;
}
if( GetAdaptersInfo( AdapterInfo, &OutBufLen ) == ERROR_BUFFER_OVERFLOW )
{
free( AdapterInfo );
AdapterInfo = (IP_ADAPTER_INFO *)malloc( OutBufLen );
if( AdapterInfo == NULL )
{
printf("Error allocating memory needed to call GetAdaptersinfo/n");
return-1;
}
}
if( GetAdaptersInfo( AdapterInfo, &OutBufLen ) == NO_ERROR )
{
PIP_ADAPTER_INFO a = AdapterInfo;
BOOL Found = FALSE;
while( a )
{
if( strcmp(a->IpAddressList.IpAddress.String, LocalIP) == 0 )
{
strcpy( GatewayIP, a->GatewayList.IpAddress.String );
Found = TRUE;
break;
}
a = a->Next;
}
if( !Found )
{
printf( "Get gateway's ip error./n" );
free( AdapterInfo );
return-1;
}
else
{
free( AdapterInfo );
}
}
else
{
printf( "Get gateway's ip error./n" );
free( AdapterInfo );
return-1;
}
BYTE Mac[6];
ULONG MacLen = 6;
SendARP( inet_addr(GatewayIP), 0, (PULONG)&Mac, &MacLen );
memcpy( GatewayMac, Mac, MacLen );
/*
for( int index = 0; index {
printf( "%d: %02x/n", index, Mac[index] );
}
printf( "/n%d/n", MacLen );
*/
}
voidUsage( char*me )
{
printf( "Make tcp package 0.1, code by yunshu/n" );
printf( "%s: targetip targetport [flag]/n", me );
printf( "flag: /n" );
printf( "u|U set urg flag./n" );
printf( "a|A set ack flag./n" );
printf( "p|P set push flag./n" );
printf( "r|R set rst flag./n" );
printf( "s|S set syn flag./n" );
printf( "f|F set fin flag./n" );
printf( "default is syn flag, and you can use sa to set syn+ack, and more.../n" );
}
intmain( intargc, char*argv[] )
{
ET_HEADER EtHeader;
IP_HEADER IpHeader;
TCP_HEADER TcpHeader;
PSD_HEADER PsdHeader;
u_char Buffer[sizeof(ET_HEADER) + sizeof(IP_HEADER) + sizeof(TCP_HEADER)] = { 0 };
if( (argc != 3) &&(argc != 4) )
{
Usage( argv[0] );
exit( -1 );
}
intFlag = 2;
if( argc == 4 )
{
Flag = 0;
if( strchr(argv[3], 'U') || strchr(argv[3], 'u') )
{
Flag = Flag | 32;
}
if( strchr(argv[3], 'A') || strchr(argv[3], 'a') )
{
Flag = Flag | 16;
}
if( strchr(argv[3], 'P') || strchr(argv[3], 'p') )
{
Flag = Flag | 8;
}
if( strchr(argv[3], 'R') || strchr(argv[3], 'r') )
{
Flag = Flag | 4;
}
if( strchr(argv[3], 'S') || strchr(argv[3], 's') )
{
Flag = Flag | 2;
}
if( strchr(argv[3], 'F') || strchr(argv[3], 'f') )
{
Flag = Flag | 1;
}
}
//GetLocalIP( );
if( -1 == GetDevices( ) )
{
exit( -1 );
}
//printf( "Adapter is %s, ip is %s/n", InterfaceName, LocalIP );
if( -1 == GetGateWayMac( ) )
{
exit( -1 );
}
//printf( "Gateway IP is %s/n", GatewayIP );
//printf( "Gateway Mac is %x/n", *GatewayMac );
memcpy( EtHeader.eh_dst, GatewayMac, 6 );
memset( EtHeader.eh_src, 0xa, 6 );
EtHeader.eh_type = htons( IP_PROTO );
IpHeader.h_verlen = (4<<4 | sizeof(IpHeader)/sizeof(unsignedint));
IpHeader.tos = 0;
IpHeader.total_len = htons(sizeof(IpHeader)+sizeof(TcpHeader));
IpHeader.ident = 1;
IpHeader.frag_and_flags = 0x40;
IpHeader.ttl = 128;
IpHeader.proto = IPPROTO_TCP;
IpHeader.checksum = 0;
IpHeader.sourceIP = inet_addr( LocalIP );
IpHeader.destIP = inet_addr( argv[1] );
TcpHeader.th_sport = htons( rand()%60000 + 1024 );
TcpHeader.th_dport = htons( atoi(argv[2]) );
TcpHeader.th_seq = htonl( rand()%900000000 + 100000 );
TcpHeader.th_ack = 0;
TcpHeader.th_lenres = (sizeof(TcpHeader)/4<<4|0);
TcpHeader.th_flag = Flag;
TcpHeader.th_win = htons(512);
TcpHeader.th_sum = 0;
TcpHeader.th_urp = 0;
PsdHeader.saddr = inet_addr( LocalIP );
PsdHeader.daddr = IpHeader.destIP;
PsdHeader.mbz = 0;
PsdHeader.ptcl = IPPROTO_TCP;
PsdHeader.tcpl = htons(sizeof(TcpHeader));
memcpy( Buffer, &PsdHeader, sizeof(PsdHeader) );
memcpy( Buffer + sizeof(PsdHeader), &TcpHeader, sizeof(TcpHeader) );
TcpHeader.th_sum = CheckSum( (unsignedshort*)Buffer, sizeof(PsdHeader) + sizeof(TcpHeader) );
memset( Buffer, 0, sizeof(Buffer) );
memcpy( Buffer, &IpHeader, sizeof(IpHeader) );
IpHeader.checksum = CheckSum( (unsignedshort*)Buffer, sizeof(IpHeader) );
memset( Buffer, 0, sizeof(Buffer) );
memcpy( Buffer, (void*)&EtHeader, sizeof(ET_HEADER) );
memcpy( Buffer + sizeof(ET_HEADER), (void*)&IpHeader, sizeof(IP_HEADER) );
memcpy( Buffer + sizeof(ET_HEADER) + sizeof(IP_HEADER), (void*)&TcpHeader, sizeof(TCP_HEADER) );
charerrbuf[PCAP_ERRBUF_SIZE] = { 0 };
pcap_t *fp;
if( (fp= pcap_open( InterfaceName, 100, PCAP_OPENFLAG_PROMISCUOUS, 100, NULL, errbuf ) ) == NULL )
{
fprintf(stderr,"/nUnable to open the adapter. %s is not supported by WinPcap/n", InterfaceName );
return-1;
}
if( pcap_sendpacket( fp, Buffer, sizeof(Buffer) ) != 0 )
{
fprintf(stderr,"/nError sending the packet: /n", pcap_geterr(fp));
return-1;
}
printf( "send ok!/nData is:/n" );
for( inti = 0; i {
printf( "%02x ", Buffer );
}
return0;
}


 



本文转自
http://huaidan.org/archives/1966.html