[12696] in bugtraq

home help back first fref pref prev next nref lref last post

Re: WordPad/riched20.dll buffer overflow

daemon@ATHENA.MIT.EDU (Solar Eclipse)
Tue Nov 23 13:14:23 1999

Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Message-Id:  <3839E66C4E.41BDSOLARECLIPSE@smtp.softhome.net>
Date:         Mon, 22 Nov 1999 18:57:16 -0600
Reply-To: Solar Eclipse <solareclipse@SOFTHOME.NET>
From: Solar Eclipse <solareclipse@SOFTHOME.NET>
X-To:         bugtraq@securityfocus.com
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <001101bf32f0$42925790$b8aa93c3@cerberusinfosec.co.uk>

On Sat, 20 Nov 1999 00:43:26 -0000
Mnemonix <mnemonix@GLOBALNET.CO.UK> 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
solareclipse@phreedom.org
www.solareclipse.org

Just find me a single RET instruction and I will rule the world!

home help back first fref pref prev next nref lref last post