荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: kid (晤), 信区: Program
标  题: 如何突破网关的种种限制与外界自由通讯(2)
发信站: 荔园晨风BBS站 (Sun Mar 31 09:38:05 2002), 转信

发信人: XSL (eXtentedStyleLanguage), 信区: XML
标  题: 如何突破网关的种种限制与外界自由通讯(2)
发信站: 逸仙时空 Yat-sen (Fri Oct 19 13:14:48 2001) , 站内信件

如何突破网关的种种限制与外界自由通讯
作者:ey4s<ey4s@21cn.com>

<<第二部分:通过socket代理上IRC>>
通常公司不但会封锁QQ,而且只允许员工浏览网页。例如在网关上做限制,除了允

访问外面的TCP 80端口,连接外面的其他端口的请求都会被丢弃。这时候我们想上
IRC去

和朋友们交流,聊天的时候,就不能如愿了。QQ和IRC都是上网必备之品?不是么
?呵呵


反正我一上网就上IRC和QQ的,呵呵。
OK!我们怎么来突破呢?也比较简单。网关不是允许我们访问外面服务器的TCP 80
端口
么,那么我们找个端口是80的socket代理就解决问题了。但是,如果我们自己动手
来解


这个问题,感觉不是更爽么,我们提倡的是DIY[Do It Yourself]。当然这也不是
说什么


西都要自己来写,只是各人的兴趣罢了,呵呵。当初也曾雄心壮志的想写个
socket代理


程序,但看了一会儿socket 5代理的RFC后,我就晕的不行了,NND,英文的,咱看
不懂


也罢,以后再说,hoho~
复杂的socket 5代理程序咱不会,咱写个简单的socket数据转发程序还不行吗,呵
呵。

OK!程序流程是这样的,我们找一台互联网上的机器来给我们做数据转发,这样的
机器很


易找,不是吗?呵呵。习惯性的,我们称这个为肉鸡吧。假如肉鸡的IP是202.
202.202.
20
2,
那么在肉鸡上运行一个我们写的程序TCPAgent.exe,监听TCP 80端口[没办法啊,
网关只

允许我们连接外面的80端口,rcch这个可怜虫所在的公司就是这样压迫他的,哈哈
],假

如这个端口已经被IIS占用的话,那么就换一台没有启动IIS服务器的机器吧,重用
端口


稳定。OK!启动IRC客户段[我以前喜欢用cjcbot2000,现在改用HIRC了,呵呵],在
IRC
服务器栏填202.202.202.202这个地址,端口是80。当我们的TCPAgent检测到我们
的IRC

客户端已经连接上来后,马上创建一个socket,连接到真正的IRC 服务器202.
109.72.4
0

的TCP 6667端口[这个IP是irc.sunnet.org的IP,我常去的IRC,喜欢去哪个IRC,
随便
换好了,呵呵]。OK!这样数据通道就建好了,HIRC??肉鸡??IRC Server,HIRC把发

服务器的数据发送到了肉鸡,然后肉鸡把它转发给服务器,肉鸡再把服务器的返回
数据


给HIRC。很简单,不是吗?呵呵。
这个程序其实是我在<<突破TCP-IP过滤-防火墙进入内网(一)>>这篇文章里面提高

程序的改进版本,这个版本代码相对更加精简和高效了,但其实还是很烂,请各位
老大


指点:))。提到的文章在我的破主页http://eyas.3322.net上有,呵呵。
程序代码如下:
/**********************************************************************

Module Name:TCPAgent.c
Date:2001/6/2
Author:ey4s<ey4s@21cn.com>
http://eyas.3322.net
说明:TCP数据包转发工具,或者也可以叫端口重定向工具吧,在网关上运行,
把端口重定向到内网的IP、PORT,就可以进入内网了
**********************************************************************/

#include <winsock2.h>
#include <stdio.h>

#pragma comment(lib,"ws2_32.lib")

#define BuffSize 20*1024 //缓冲区大小20k
////////////////////////////////////////////////////////////////////////
////
//
/
//
//定义&初始化全局变量
//
char TargetIP[50]={0};//目标IP
int TargetPort,//目标端口
ListenPort;//本地监听的端口
////////////////////////////////////////////////////////////////////////
////
//
/
//显示错误信息函数
void ShowError(char *);
//TCP数据转发函数
DWORD WINAPI TCPDataRedird(LPVOID);
////////////////////////////////////////////////////////////////////////
////
//
/
int main(int argc,char **argv)
{
WSADATA wsd;
SOCKET sListen=INVALID_SOCKET,//本机监听的socket
sock1[2],sock2[2];
struct sockaddr_in Local,Client,Target;
int iAddrSize;
HANDLE hThread[2]={NULL,NULL};
DWORD dwThreadID,dwRet;

//检查参数
if(argc!=4)
{
printf("\nTCPAgent use for TCP socket date redird"
"\nPower by ey4s<ey4s@21cn.com>"
"\nhttp://eyas.3322.net
"\n2001/6/2"
"\n\nUsage:%s <TargetIP> <TargetPort> <ListenPort>\n",argv[0]);
return 1;
}
strncpy(TargetIP,argv[1],sizeof(TargetIP)-1);
TargetPort=atoi(argv[2]);
ListenPort=atoi(argv[3]);

__try
{
//FreeConsole();
//load winsock library
if(WSAStartup(MAKEWORD(1,1),&wsd)!=0)
{
ShowError("WSAStartup");
__leave;
}
//创建一个socket
sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sListen==INVALID_SOCKET)
{
ShowError("Create listen socket");
__leave;
}

Local.sin_addr.s_addr=htonl(INADDR_ANY);
Local.sin_family=AF_INET;
Local.sin_port=htons(ListenPort);

Target.sin_family=AF_INET;
Target.sin_addr.s_addr=inet_addr(TargetIP);
Target.sin_port=htons(TargetPort);
//bind socket
if(bind(sListen,(struct sockaddr *)&Local,
sizeof(Local))==SOCKET_ERROR)
{
ShowError("bind");
__leave;
}
//listen
if(listen(sListen,1)==SOCKET_ERROR)
{
ShowError("listen");
__leave;
}
//开始循环接受客户连接
while(1)
{
printf("\n\n*************Waiting Client Connect to**************\n\n");

iAddrSize=sizeof(Client);
//等待客户连接
sock1[0]=accept(sListen,(struct sockaddr *)&Client,&iAddrSize);
if(sock1[0]==INVALID_SOCKET)
{
ShowError("accept");
break;
}
printf("\nAccept
client==>%s:%d",inet_ntoa(Client.sin_addr),ntohs(Client.sin_port));
//创建一个socket用于和最终目标连接
sock1[1]=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sock1[1]==INVALID_SOCKET)
{
ShowError("create socket");
break;
}
//连接到最终目标
if(connect(sock1[1],(struct sockaddr
*)&Target,sizeof(Target))==SOCKET_ERROR)
{
ShowError("connect");
break;
}
printf("\nconnect to %s %d success!",TargetIP,TargetPort);
//创建两个线程进行数据转发,双工效率高,感谢shotgun<shotgun@xici.net>给
的提示:)))

hThread[0]=CreateThread(NULL,0,TCPDataRedird,(LPVOID)sock1,0,
&dwThreadID);
if(hThread[0]==NULL)
{
ShowError("create thread 1");
break;
}
//变换一下socket的顺序,作为参数传递给第二个线程
sock2[0]=sock1[1];
sock2[1]=sock1[0];

hThread[1]=CreateThread(NULL,0,TCPDataRedird,(LPVOID)sock2,0,
&dwThreadID);
if(hThread[1]==NULL)
{
ShowError("create thread 2");
break;
}
//等待两个线程中的其中一个结束,一个线程结束后立即中断另一个线程
dwRet=WaitForMultipleObjects(2,hThread,FALSE,INFINITE);
if(dwRet==WAIT_FAILED)
{
ShowError("WaitForMultipleObjects");
break;
}
if((dwRet-WAIT_OBJECT_0)==0)
TerminateThread(hThread[1],1);
else
TerminateThread(hThread[0],1);
//关闭线程句柄
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
//关闭socket
closesocket(sock1[0]);
closesocket(sock1[1]);
closesocket(sock2[0]);
closesocket(sock2[1]);
printf("\n\n*****************Connection Close*******************\n\n");

}//end of sock外循环
}//end of try
__finally
{
if(sListen!=INVALID_SOCKET) closesocket(sListen);
if(sock1[0]!=INVALID_SOCKET) closesocket(sock1[0]);
if(sock1[1]!=INVALID_SOCKET) closesocket(sock1[1]);
if(sock2[0]!=INVALID_SOCKET) closesocket(sock2[0]);
if(sock2[1]!=INVALID_SOCKET) closesocket(sock2[1]);
if(hThread[0]!=NULL) CloseHandle(hThread[0]);
if(hThread[1]!=NULL) CloseHandle(hThread[1]);
WSACleanup();
}
return 0;
}
////////////////////////////////////////////////////////////////////////
////
//
//////
void ShowError(char *msg)
{
printf("\n%s failed:%d",msg,GetLastError());
}
////////////////////////////////////////////////////////////////////////
////
//
//////
//
//TCP socket数据转发函数,从s[0]接收数据,转发到s[1]
//
DWORD WINAPI TCPDataRedird(SOCKET *s)
{
int iRet,
ret=-1,//select 返回值
iLeft,
idx,
iSTBCS=0;//STBCS=SendToBuffCurrentSize
char szSendTo[BuffSize]={0},
szRecvFrom[BuffSize]={0};
fd_set fdread,fdwrite;
DWORD dwThreadID=GetCurrentThreadId();

//开始一个循环来转发数据
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(s[0],&fdread);
FD_SET(s[1],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
ShowError("select");
break;
}
if(ret>0)
{
//s[0]可读
if(FD_ISSET(s[0],&fdread))
{
//接收s[0]发送来的数据
iRet=recv(s[0],szRecvFrom,BuffSize,0);
if(iRet==SOCKET_ERROR)
{
ShowError("recv");
break;
}
else if(iRet==0)
break;
printf("\nThread %d recv %d bytes.",dwThreadID,iRet);
//把从s[0]接收到的数据存添加到s[1]的缓冲区
memcpy(szSendTo+iSTBCS,szRecvFrom,iRet);
//刷新s[1]的数据缓冲区当前buff大小
iSTBCS+=iRet;
//清空接收s[0]数据的缓冲区
memset(szRecvFrom,0,BuffSize);
}
//s[1]可写,把从cRecvFrom接收到的数据发送到s[1]
if(FD_ISSET(s[1],&fdwrite))
{
iLeft=iSTBCS;
idx=0;
while(iLeft>0)
{
iRet=send(s[1],&szSendTo[idx],iLeft,0);
if(iRet==SOCKET_ERROR)
{
ShowError("send");
break;
}
printf("\nThread %d send %d bytes.",dwThreadID,iRet);
iLeft-=iRet;
idx+=iRet;
}
//清空缓冲区
memset(szSendTo,0,BuffSize);
//重置发往target的数据缓冲区当前buff大小
iSTBCS=0;
}
}//end of select
Sleep(1);
}//end of while
return 0;
}
////////////////////////////////////////////////////////////////////////
////
//
//
程序在VC++6.0,windows2k下编译通过,编译好的程序在我的主页上有下载。
恩!如果可恶的网管连TCP 80都不让我们上,把全部TCP数据包都在网关上封杀了

那咱怎么办啊?有办法。第一部分和第二部分后面提到的问题在第三部分一起写吧
,呵






--
※ 来源:.逸仙时空 Yat-senWWW bbs.zsu.edu.cn. [FROM: 192.168.45.225]

--
          ╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳
            ︳╳  ︳轻  ︳易  ︳就  ︳把  ︳我  ︳╳  ︳
          ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳
          ╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳ ̄╳╳
          ︳困  ︳在  ︳了  ︳网  ︳的  ︳中  ︳央  ︳
          ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳  ╳╳

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.32.62]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店