Re: WordPad/riched20.dll buffer overflow

From: Solar Eclipse (solareclipseat_private)
Date: Mon Nov 22 1999 - 16:57:16 PST

  • Next message: CyberPsychotic: "Re: Caldera Pine Advisory"

    On Sat, 20 Nov 1999 00:43:26 -0000
    Mnemonix <mnemonixat_private> wrote:
    
    > This is exploitable. On both Windows NT4 and Windows 2000 the payload can be
    > found at the ESP - but there is a difference between the two OSs.
    > NT 4 seems to do a tolower() on the string turning "AAAA" to "aaaa" where as
    > Windows 2000 preserves the case. Both OS's have the return address
    > over-written so all you have do do is find an instruction in the memory
    > space that does a JMP ESP - there are quite a few floating around the place.
    
    The problem is getting the return address pointing to something usefull.
    Due to the nature of the code that overflows the buffer, we can only put
    lowercase letters from 'a' to 'z' in the buffer. (I am talking about NT)
    
    This means that the return address will point to some memory area
    between 61616161 and 7A7A7A7A. On my machine (NT4, SP5) all of this area
    was empty/nonpaged or whatever the proper word is.
    
    Even if you had some way to jump back to the stack, your shell code
    should be using only 'a'-'z' letters. This is hard. Also, you can not
    put more then 200 bytes of code in the buffer.
    
    There is a simple solution to this problem. Before processing the RTF
    file, RICHED32.DLL reads all of it into the memory. The file is stored
    in a buffer in the heap. This buffer is raw, so if you put some
    executable code in the RTF file, it will be copied to the heap unchanged
    (we can even use NULLs - wow!). How do you use this? Remeber how
    RICHED32.DLL uses the buffer that we overflow? It copies a string from
    the RTF file to the buffer. Guess what, the string is read from the
    buffer in the heap I was talking about. There is a source pointer that
    is incremented while copying. After the copying finishes (because a non
    'a'-'z' character is reached), this pointer points to the first
    offending character, in the heap. After you smash the stack this pointer
    is located at esp+130 (I am not sure this is the exact offset, but it's
    close).
    
    If you have a file like this:
    
    {\rtf\AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOO\PPPPPPPPPP}
    
    The first string will be copied into the buffer and will oveflow it. The
    return address will become 'kkkk'. See the backslash between the O and
    the P ? The function will stop copying when it reaches the backslash.
    The pointer at esp+130 will point to the backslash after you smash the
    stack.
    
    You can put some shell code instead of the Ps. The size is practicly
    unlimited - I tried 40KB and it worked fine. You can also use NULLs.
    
    How do you get the execution flow to jump to the shell code?
    Imagine that you have a single RET instruction at address 61626364 (this
    is 'abcd'. You can put it instead of the 'kkkk' and make the execution
    flow jump to the RET. What will happen next? The RET instruction will
    decrement the ESP and read the next return address. You can put 'abcd'
    there too. You can fill the stack will 'abcd', causing the same RET
    instruction to be called many times. If you put 50 'abcd'-s in your
    string, the next dword on the stack after your last 'abcd' will be the
    pointer at esp-50. The last RET instruction will read the address from
    there and the execution flow will jump to the heap.
    
    When I tried this, I found out that code CAN be executed on the heap,
    although the heap descriptor has no execute permissions. I don't know
    why. If somebody can confirm this it would be great.
    
    This way, you can execute the code that you put after the backslash.
    
    The only catch is that you need a reachable RET instruction. On my
    system (NT4, SP5) there were no such instructions.
    
    Can somebody verify this with a 9x and 2000 machine?
    
    Mnemonix wrote that the shell code is not lowercased on Win2K. Are there
    any other restrictions? Can you use characters > 128 ?
    
    What about Win9x?
    
    Are there any DLLs loaded in the 6161616-7A7A7A7A range on there
    machines?
    
    Solar Eclipse
    solareclipseat_private
    www.solareclipse.org
    
    Just find me a single RET instruction and I will rule the world!
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:13:51 PDT