If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Defeating Exploits

This is a pretty interesting Paper, some nice ideas. Well explained ;-)

Defeating Exploits
**************
The ideas in this "paper" present a method for defeating exploits; not the
actual vulnerability. Before getting to the details let's consider slammer
(again).

What made slammer so successful?
The overriding factor that made slammer so successful was it's ability to
spread. What made it's spread a foregone conclusion was the fact that every
vulnerable SQL Server/MSDE had a "jmp esp" instruction at address
0x42B0C9DC. This was the address that was used to gain control of the SQL
Server's path of execution to a point where the worm's payload, the
"arbitrary code", would be executed.

This address is in a dynamic link library (DLL) , sqlsort.dll which has an
"image base" of 0x42AE0000.

Every image file, DLL or executable, has an "Image Base" and this base is
the preferred location where the file should be loaded into memory by the
Windows Loader. [I don't want to digress, here, as to what happens if
there's a conflict. See the references at the end.] Now if this Image Base
on one particular system had been 0x42AF0000 then the worm would have failed
to infect this particular box; the "jmp esp" instruction that should've been
at 0x42B0C9DC on this system would be found at 0x42B1C9DC so the worm would
have been off target. The SQL Server running on this system, whilst still
being "vulnerable" to the buffer overflow vulnerability would have been
invulnerable to this worm. Sure - the SQL Server may have crashed - but it
would not have been compromised.

It's like sickle cell. Someone born with the gene that causes sickle cell
anaemia, a blood disorder that affects many people of a West African origin,
or carriers of the gene, sickle cell trait, do not suffer from the ill
affects of malaria, a disease caused by a parasite and most commonly spread
by mosquitoes. Whilst someone with sickle cell trait can still catch
malaria, the gene mutates the haemoglobin in their blood in such a way that
they are invulnerable to the debilitating side effects and syptoms of the
disease such as mental confusion, coma and death. There is an obvious
evolutionary advantage to sickle cell trait; remember that the evolution of
the species cares not about how long a person lives, only that they live
long enough to pass on their genes. (Those with anaemia may suffer from
crises, periods of acute pain so the trade off is somewhat questionable.)

In areas where malaria is a common cause of death, being a carrier of the
sick cell gene can help ensure that this person lives long enough to have
progeny. This is Darwinian natural selection in progress.

Rebasing
*******
The problem with operating systems is that they all have pretty much the
same "genetic code" which makes each and every one of them vulnerable to a
new exploit. So we need to make them different and this can be achieved
through rebasing. Rebasing is the process of changing the Image Base of an
image file. By doing this the DLL/EXE is loaded into a different location in
the virtual address space.

Going back to Slammer, had I have rebased sqlsort.dll giving it a new base
of 0x41410000 my box would have been invulnerable to the worm. If another
worm were written, though, that used an address that contained a "jmp esp"
instruction in kernel32.dll then I would be vulnerable. So I rebase
kernel32.dll. But then another worm uses another DLL so I rebase that one,
too. Eventually I've rebased all of the DLLs used by SQL Server mutating
it's "genetic code", making it considerably different to any other SQL
Server install on the planet. In fact if I rebase every DLL on my system and
every executable then I can make my box almost invulnerable to a given
exploit, past, present or future. It's not that my box is invulnerable to a
buffer overflow vulnerability - it's just invulnerable to the exploits for
it. To gain control of a system protected in such a way
would require that the author of the exploit know the location of loaded
DLLs.

So how easy is it to rebase DLLs and executables? Very. Microsoft have
provided a function to do this, ReBaseImage(), exported by imagehlp.dll. If
you rebase an image the new base must be on a 64K boundary - i.e. if the
image base mod 64000 !=0 the base is not valid.

The only other problem is Windows File Protection. Once you've rebased a
copy of the DLL you need to copy the new DLL over the old one but Windows
File Protection won't allow you to do this. To get around the problem use
the MoveFileEx and specifying the MOVEFILE_DELAY_UNTIL_REBOOT flag. Doing
this will add a registry value, "PendingFileRenameOperations" to
HKLM\System\CurrentControlSet\Control\Session Manager\. You then need to add
another DWORD value "AllowProtectedRenames" and set it to 1. Then restart
the system. On reboot the new DLLs, with their new image bases, will be
loaded. For example - here is sample output of listdlls after kernel32.dll
and ws2_32.dll have been rebased.

Now all the way through this I've been saying things like "almost
invulnerable" etc. Here's the reason. For some vulnerabilities it may be
sufficient to overwrite a saved return address, function pointer or whatever
by only a few bytes. For example assume a saved return address is 0x44784500
and at address 0x44784536 is a "jmp ebx" instruction and ebx points to our
code. Then we only need to overwrite the saved return address by 1 byte -
with 0x36. So knowledge of the DLL load address is not needed. However, this
scenario is going to happen so infrequently (if ever) that it does not
detract from the idea of rebasing your system. There may other ways to
bypass this method.

Some ideas to further help prevent exploits from working.

Use addresses such as 0x**000000 or 0x00**0000 for the new image base. With
there being a NULL in much of the image's address space this will help.
(This of course won't make a difference with unicode overflows)

Ensure at least one (core) DLL has a base of 0x00119400 . This will ensure
that a common stack location 0x00120000 has been assigned forcing the OS to
chose another location for the stack. You get the idea.

Rebasing system DLLs is tricky business. Although they include relocation information they also make certain assumptions about where in memory they will be loaded. If you rebase some of the system DLLs, your system will become unstable or will fail to start. Also, many EXEs do not include relocation and since EXEs are loaded first they are not supposed to be relocated in normal operation. You will not be able to rebase them either.

This is just an addition to your outstanding article.

Our scars have the power to remind us that our past was real. -- Hannibal Lecter.
Talent is God given. Be humble. Fame is man-given. Be grateful. Conceit is self-given. Be careful. -- John Wooden

Additionally - and I am only really guessing here 'cos this is a little out of my knowledge area - this would result in an un-infected machine but also a high probability of total denial of service, (possibly a complete machine hang), until the machine is rebooted - or am I completely off base with that?

Don\'t SYN us.... We\'ll SYN you..... \"A nation that draws too broad a difference between its scholars and its warriors will have its thinking done by cowards, and its fighting done by fools.\" - Thucydides