WEB开发网
开发学院软件开发VC 突破TCP-IP过滤/防火墙进入内网(icmp篇) 阅读

突破TCP-IP过滤/防火墙进入内网(icmp篇)

 2006-07-21 11:12:27 来源:WEB开发网   
核心提示: sock[0][0]=socket(AF_INET,SOCK_DGRAM,0); //创建基于UDP协议的套接字bind(sock[0][0],(struct sockaddr *)&sin[0][1],addrlen); //绑定到指定地址,指定端口上iret=recvfrom(sock
sock[0][0]=socket(AF_INET,SOCK_DGRAM,0);          //创建基于UDP协议的套接字
bind(sock[0][0],(struct sockaddr *)&sin[0][1],addrlen);      //绑定到指定地址,指定端口上
iret=recvfrom(sock[0][0],msgrecv,sizeof(msgrecv),0,(struct sockaddr *)&tempr,&addrlen);  //接收来自QQ客户端的UDP数据
然后以ICMP数据报的形式发送到QQicmp(g),在此需要自己构造ICMP Echo Reply数据报,并将接收到的UDP数据填充到ICMP报文的数据段, sock[0][1]=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); //创建ICMP协议的原始套接字,用来发送自定义数据报
bind(sock[0][1],(struct sockaddr *)&sin[0][2],addrlen);   //并捆绑到指定地址,指定端口上
if(istbcs==0)         //填充ICMP数据报头部
{
  icmphdr.type=0;      //类型:echo reply
  icmphdr.code=0;      //代码
  icmphdr.checksum=0;   //先将校验和设置为零
  icmphdr.id=htons(65456);  //序号
  icmphdr.seq=htons(65456); //标志符,用以过滤数据报
  memset(msgsend,0,sizeof(msgsend));
  memcpy(msgsend,&icmphdr,sizeof(icmphdr));
  istbcs+=sizeof(icmphdr);
}
memcpy(msgsend+istbcs,msgrecv,iret); //将接收到的UDP数据报的内容提取,放到即将发送的ICMP数据报内
icmphdr.checksum=checksum((USHORT *)&msgsend,ileft);    //计算ICMP校验和
memcpy(msgsend,&icmphdr,sizeof(icmphdr));       //重新填充ICMP头部
iret=sendto(sock[0][1],msgsend,istbcs,0,(struct sockaddr *)&sin[0][3],addrlen); //发送ICMP数据报网关
同时,QQicmp(l)监听通过本机的IP数据报,筛选出来自QQicmp(g)既网关的数据报, sock[1][0]=socket(AF_INET,SOCK_RAW,IPPROTO_IP);      //创建原始套接字,接收所有的IP数据报
bind(sock[1][0],(struct sockaddr *)&sin[1][1],addrlen);    //绑定到指定地址,指定端口上
DWORD  dwbufferlen[10];
DWORD  dwbufferinlen=1;
DWORD  dwbytesreturned=0;
  WSAIoctl(sock[1][0],SIO_RCVALL,&dwbufferinlen,sizeof(dwbufferinlen),&dwbufferlen,sizeof(dwbufferlen),&dwbytesreturned,NULL,NULL);
//设置为接收所有的数据报,需要mstcpip.h头文件。
iret=recvfrom(sock[1][0],msgrecv,sizeof(msgrecv),0,(struct sockaddr *)&temp1,&addrlen);  //接收所有数据报
if(iret<=28)   //文件过小
{
  continue;
}
if((icmphdr->type!=0) || (icmphdr->code!=0) || ((icmphdr->id)!=htons(65456)) || ((icmphdr->seq)!=htons(65456))) 
//不符合接收条件
{
  continue;
}
memcpy(msgsend+istbcs,msgrecv,iret);  //将接收到的ICMP数据报的内容提取,准备以UDP的形式发送
解包后,用UDP数据报将接收到的来自网关的ICMP数据发送到QQ客户端, idx=28;             //ICMP数据报的前20字节是IP头部,接着的8字节是ICMP头部
iret=sendto(sock[1][1],&msgsend[idx],ileft,0,(struct sockaddr *)&sin[1][3],addrlen);  //发送到QQ客户端
我们创建了两个线程在两个方向(udp-->icmp,icmp-->udp)上接收并传送数据,如果某个线程出错,就重新创建该线程,而未出错的线程则保持不变, hthreads[0]=CreateThread(NULL,0,u2i,(LPVOID)0,NULL,&hthreadid[0]);  //创建接收udp数据,发送icmp数据的线程0
hthreads[1]=CreateThread(NULL,0,i2u,(LPVOID)1,NULL,&hthreadid[1]);  //创建接收icmp数据,发送udp数据的线程1
while(1)
{
  dwret=WaitForMultipleObjects(2,hthreads,false,INFINITE);    //等待某个线程的结束
  if(dwret==WAIT_FAILED)                     //出错
  {
    cout<<"WaitForMultipleObjects Error: "<<GetLastError()<<endl;
    return -1;
  }
  log=dwret-WAIT_OBJECT_0;
  if(log==0)                                //线程0结束
  {
    CloseHandle(hthreads[0]);                    //关闭线程handle
         closesocket(sock[0][1]);                      //关闭套接字
         hthreads[0]=CreateThread(NULL,0,u2i,(LPVOID)0,NULL,&hthreadid[0]); //重新创建线程0
  }
  else if(log==1)                             //线程1结束
  {
    CloseHandle(hthreads[1]);
        closesocket(sock[1][0]);
         hthreads[1]=CreateThread(NULL,0,i2u,(LPVOID)1,NULL,&hthreadid[1]);
  }

上一页  1 2 3 4  下一页

Tags:突破 TCP IP

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接