Re: Is GOT exploitable in solaris?

From: Shaun Clowes (shaunat_private)
Date: Thu Dec 27 2001 - 13:41:44 PST

  • Next message: scott [gts]: "Grokster and possible trojan"

    Hi,
    
    Long post, apologies in advance.
    
    >The entry of Global Offset Table in linux is pointer to 
    >piece of executable code( say printf), so overwrite the 
    >pointer will force the process run your shellcode or 
    >whatever..
    
    Not really, there is an important distinction here, under IA32 
    the normal ELF Procedure Linkage Table (which is really what is 
    being manipulated here) has as its first entry an instruction 
    like
       
       call *<addr in GOT>
    
    This allows lazy binding of functions (i.e the dynamic linker 
    fills in the correct address in the GOT slot when it works out
    where the function is on demand). 
    
    This is clearly not possible on Sparc since there is no way to
    do jump to an in memory address. You have two types of pc 
    modification instructions, branch and call instructions (which
    are PC relative) and the jmpl instruction which is register 
    indirect.
    
    >Maybe a mistake/illusion after too much beer,  I found 
    >the Solaris implmentation of GOT entry is actually not 
    >pointer, but starting point of 3 instructions which 
    >finally jump to say, printf executable code. 
    
    Exactly, a typical Sparc PLT entry looks like this before 
    dynamic binding:
    
    0x207cc <printf>:   sethi  %hi(0x1e000), %g1
    0x207d0 <printf+4>: b,a   0x20754 <_PROCEDURE_LINKAGE_TABLE_>
    0x207d4 <printf+8>: nop
    
    So it basically sets the high bits of g1 to indicate to the
    dynamic linker which symbol needs to be resolved and then
    branches relative the start of the PLT which always contains
    a binding to the dynamic linker resolution routine.
    
    After dynamic binding (which is what you're seeing):
    
    0x207cc <printf>:   sethi  %hi(0x1e000), %g1
    0x207d0 <printf+4>: sethi  %hi(0x50075000), %g1
    0x207d4 <printf+8>: jmp  %g1 + 0x1e8        ! 0x500751e8 <printf>
    
    printf has been resolved to 0x500751e8, in order to achieve 
    a jump absolute (since a jump absolute with immediate operand
    isn't possible, given a instruction width of 32bits, too 
    small to contain the complete operand) the high bits of g1 are
    set with sethi then a register relative jump is used. 
    
    > So 
    >overwrite the entry with your shell code address 
    >simply corrupt these instruction but not control the 
    >process.
    
    Yep, clearly this won't work.
    
    I take it you need to get to your shellcode and have to do it
    with one instruction (one 4 byte format string overwrite)? If 
    your code is on the stack you're going to be in trouble because 
    the best you could do is a CALL instruction with 30 bits of 
    displacement which isn't enough to reach from low memory (the 
    PLT) to high memory (the stack). If your code is on the heap 
    you may be able to reach it (though I guess even that is 
    unlikely).
    
    I've never tried what you're attempting to do but if you can
    exploit the format string multiple times you could overwrite
    a couple of instructions in the PLT and create a JMPL 
    instruction. 
    
    Hope this comes in helpful,
    Shaun
    



    This archive was generated by hypermail 2b30 : Thu Dec 27 2001 - 13:41:46 PST