PDA

Bekijk Volledige Versie : Preventing /*exploitation with*/ rebasing



Riley Hassell
06/02/03, 18:02
So the course of this talk with most likely go into generating a totally
dynamic address space and once again, end in another theoretical solution,
to an overly complex problem.

Defeating Rebasing
-------------------------------------

Many operating systems with fault handling features and refined
multitasking, reference address spaces with segments to permit these
features and aid general performance. The majority of this behavior can be
studied by following process creation and task switching. Start from the
user API and step through until the entry point of the executable is
reached.

TEB: Thread Environment Block
TIB: Thread Information Block
PEB: Process Environment Block

The TEB/TIB fs:[] segment references originated in the OS2 days and have
since passed down into 9x client systems, and of course, Windows NT. During
the process creation the PEB and TIB are initialized into the new virt and
can be referenced by the fs segment. Modifying the address space referenced
by fs and how fs is setup is possible... but by the time you're done you're
designing a new operating system.

As Ryan might say... It's all data ;) The data referenced in this delta can
be referenced during a ret. You just need to find a set of bytes that forms
the needed instruction. You may be able to modify this arena in a way that
you can insert your own instructions. Maybe some of the TLS storage can be
controlled by supplying malformed sizes in your exploit session... ;)

Note: PEB locking pointers can be overwritten with format bugs and control
structure based heap overflows.

7FFDF000 00010000
7FFDF004 FFFFFFFF
7FFDF008 01000000 <- Executable image base ;)
7FFDF00C 00071E90
7FFDF010 00020000
7FFDF014 00000000
7FFDF018 00070000
7FFDF01C 77FCF170 <- PEB fast Lock entry point
7FFDF020 77F8313C <- PEB lock entry point
7FFDF024 77F8316D <- PEB unlock entry point

Brett Moore wrote me several months ago with a very interesting exploit
concept using multiple writes. The first write you insert your needed
instruction into writeable memory somewhere. The second write you overwrite
some writeable entry point or hook, with the address of the inserted
instruction.

There's not much out there if you're interested in learning about the TIB
and the PEB. If you really want to understand these structures and general
loading behavior, learn Polish and Russian, then hit up some VX'er archives.
If you end up talking to any of them, tell them that somebody is trying to
stop exploits by rebasing dll's :)

Rebasing... There's a reason why relocation sections exist. While doing your
own relocations is possible, the design of such a system is extremely, and
I'll say again, extremely complex. Just differentiating all the instructions
from data is a fairly painful process. Maybe the ETCH guys did this at one
point but as far as I know this has been a big hurdle in image modifcation
for quite some time.

Michal Zalewski provided some great examples of issue's you'll run into:

MZ> Also, what if I wanted to pass a value 4325404 (0x42001c) to this
MZ> function, and it is not a pointer, only looks this way? For example,some
MZ> FOO_ASYNC flag is defined as 0x400000, FOO_LOCK as 0x020000, and
voila,OR
MZ> them and you have "a pointer".
MZ> In other cases, say, with register calls, it is getting even nastier,
MZ> because even if, one way or another, you managed to find out how every
MZ> single function is going to use its parameters (not likely), register
MZ> calls are still black magic.

GetProcAddress ACL's...

>
> It is possible to intercept every call to GetProcAddress and determine
> whether or not the call should be authorized based on a predetermined list
> of known valid callers (runtime call stack analysis).

Simply rewrite a micro GetProcAddress. GetProcAddress is basically an
overstuffed RVA engine. This is defeated by "The payload brings the tools
concept". Most userland hooking schemes can also easily be bypassed by using
direct gates "Ex: Interupts Gates". You could also intercept a thread that
has the neccesary privelege by snagging a hook in it's path.

> This list of authorized callers must be constructed through the use of
forensic profiling
> tools in the case of other people's binaries, but can be constructed with
> the help of additional API calls in the case of one's own code. Call a
> profiling/tracing API before calling GetProcAddress. After compilation but
> before deployment to production boxes you simply execute the code in
profile
> mode to generate a list of authorized callers. This list is then
configured
> as a static security setting adhered to by the security layer that sits
> between GetProcAddress and the rest of the virtual world.

Who's an authorized caller?

Someone who has a "safe" caller address on the stack....

If a the attacker start's offering instructions to your CPU... kiss your ass
goodbye.
Research AV/VX trends from the late 80's and early 90's.

-R

Riley Hassell
Security Research Associate
eEye Digital Security

[DOW]

dullien@gmx.de
07/02/03, 17:09
Hey Riley, all,

RH> Research AV/VX trends from the late 80's and early 90's.

First off, thanks for this line. Reading some old VX magazines could
do some good here. The fact that most shellcodes still use hardcoded
addresses to retrieve GetProcAddress/GetModuleHandle should make
everyone think -- VLAD Boza (the first PE infector ever) did the same,
and was thus not very successful. VX folks abandoned the concept of
hardcoding offsets for KERNEL32 in about 1996-97. Ahwell. It's just
5-6 years. And it's not like you have to have clever ideas yourself,
it's all in easy-to-digest tutorial format.

Thanks for addressing the bogus idea of hooking GetProcAddress(),
too. Most serious win32 shellcodes do not use it anymore but do their
own PE parsing anyhow, so this would be (aside from being easily
bypassed otherwise) completely ineffective. User-mode policy
enforcement (e.g. doing policy enforcement on the same privilege level
as the malicious code) is bound to fail.

Concerning information on TIB and PEB: If you're too lazy to learn
russian/polish, you might consider taking (a) the wine header files
(which attempt to document parts of these structures) and (b) a
debugger and go spellunking yourself.
Oh, and MS does provide some limited information:
http://msdn.microsoft.com/msdnmag/issues/02/08/EscapefromDLLHell/default.aspx

Cheers,
dullien@gmx.de

Shaun Clowes
08/02/03, 09:12
Hey All,

At 08:57 PM 7/02/2003 +0100, dullien@gmx.de wrote:
>Concerning information on TIB and PEB: If you're too lazy to learn
>russian/polish, you might consider taking (a) the wine header files
>(which attempt to document parts of these structures) and (b) a
>debugger and go spellunking yourself.
>Oh, and MS does provide some limited information:
>http://msdn.microsoft.com/msdnmag/issues/02/08/EscapefromDLLHell/default.aspx

Incase anyone is wondering about these Russian papers on the reverse
engineered contents of the PEB and TIB there have been a number of posts to
the newsgroups with the structures in question. You don't have to
understand Russian given that the field names make most of them pretty
obvious, check out:

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&q=_NT_TEB&btnG=Google+Search

Cheers,
Shaun