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