Log in

View Full Version : Mystery Vulnerability Theater 3000: Part I


Matasano
December 2nd, 2007, 17:40
Tom was telling me about a really quick way to do risk assessments on memory trespass/register control vulnerabilities. As it happens, the next day I found myself controlling some registers in an application, and figured I would see where it got me.

The basic idea is that when you find a vulnerability and don’t have the time to confirm exploitability via an exploit, you can mock it up in a debugger by setting breakpoints just before the instruction that causes the exception, and resetting the register you control to a valid memory address (I chose the stack).

Code:

sitio:~ root# !FOO
FOO=`ps -auxwww | grep XXXXX | grep -v grep | awk ‘{ print $2 }’` ; gdb -pid $FOO XXXXX
GNU gdb 6.1-20040303 (Apple version gdb-384) (Mon Mar 21 00:05:26 GMT 2005)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “powerpc-apple-darwin”…
Attaching to program: `XXXXX’, process 23276.
Reading symbols for shared libraries …………………………………………………………………………………………. done
Reading symbols for shared libraries ……………… done
0×9000ab48 in mach_msg_trap ()
(gdb) cont
Continuing.

We have attached and the process is running as normal. Lets see what happens when we send some bad input:

Code:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0×62626262
[Switching to process 23276 thread 0×7103]


0×62626262, eh? BBBBadness.

Code:

0×0224f864 in SomeRandomFunction ()
(gdb) bt
#0 0×0224f864 in SomeRandomFunction ()
#1 0×02257d2c in TotallyRandomFunction ()
#2 0×022570c0 in ReallyRandomFunction ()
Cannot access memory at address 0×61626364
Cannot access memory at address 0×6162636c


Yah I know, the 0×61626364’s look tempting… just ignore them.

Code:

(gdb) disas _SomeRandomFunction
Dump of assembler code for function _SomeRandomFunction:
0&#215;0224f84c <_SomeRandomFunction+0>: mflr r0
0&#215;0224f850 <_SomeRandomFunction+4>: stmw r29,-12(r1)
0&#215;0224f854 <_SomeRandomFunction+8>: stw r0,8(r1)
0&#215;0224f858 <_SomeRandomFunction+12>: mr r29,r3
0&#215;0224f85c <_SomeRandomFunction+16>: stwu r1,-80(r1)
0&#215;0224f860 <_SomeRandomFunction+20>: li r3,0
0&#215;0224f864 <_SomeRandomFunction+24>: lwz r4,0(r29)
0&#215;0224f868 <_SomeRandomFunction+28>: bl 0&#215;22547f4
0&#215;0224f86c <_SomeRandomFunction+32>: lwz r0,88(r1)
0&#215;0224f870 <_SomeRandomFunction+36>: addi r1,r1,80
0&#215;0224f874 <_SomeRandomFunction+40>: mr r4,r29
0&#215;0224f878 <_SomeRandomFunction+44>: mtlr r0
0&#215;0224f87c <_SomeRandomFunction+48>: li r3,0
0&#215;0224f880 <_SomeRandomFunction+52>: lmw r29,-12(r1)
0&#215;0224f884 <_SomeRandomFunction+56>: b 0&#215;22547f4
End of assembler dump.
(gdb) quit
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: `XXXXX’, process 23276 thread 0&#215;7103.


Looks like we grabbed control of a register. But it is control of r29. Since we are lazy, and want to see if we can quickly confirm exploitability, lets try something:

Code:

sitio:~ root# FOO=`ps -auxwww | grep XXXXX | grep -v grep | awk ‘{ print $2 }’` ; gdb -pid $FOO XXXXX
GNU gdb 6.1-20040303 (Apple version gdb-384) (Mon Mar 21 00:05:26 GMT 2005)
… Attaching to program: `XXXXX’, process 23324. 0&#215;9000ab48 in mach_msg_trap ()
(gdb) break *0&#215;0224f860
Breakpoint 1 at 0&#215;224f860
(gdb) cont
Continuing.
[Switching to process 23324 thread 0&#215;8403]


Same as before… only this time we set our break point to one instruction prior to the invalid access prior to continuing execution. Now we send the same malicious input, and…

Code:

Breakpoint 1, 0&#215;0224f860 in SomeRandomFunction ()
(gdb) x/2i 0&#215;0224f860
0&#215;224f860 <_SomeRandomFunction+20>: li r3,0
0&#215;224f864 <_SomeRandomFunction+24>: lwz r4,0(r29) (gdb) set $r29=0xbffffd30
(gdb) cont
Continuing.


Now that we have hit our breakpoint, we modify the value of r29 back to a valid memory address and continue. Lets see what happens next…

Code:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0&#215;6262626a
0&#215;02257f6c in SomeWhereElseRandom ()
(gdb) bt
#0 0&#215;02257f6c in SomeWhereElseRandom ()
#1 0&#215;02257d44 in TotallyRandomFunction ()
#2 0&#215;022570c0 in ReallyRandomFunction ()
Cannot access memory at address 0&#215;61626364
Cannot access memory at address 0&#215;6162636c
(gdb)


Oh look, we’ve moved past it. Lets check out our execution window:

Code:

XXXXX(23324,0&#215;2842a00) malloc: *** Deallocation of a pointer
not malloced: 0&#215;64676f6c; This could be a double free(), or
free() called with the middle of an allocated block; Try setting
environment variable MallocHelp to see tools to help debug
XXXXX(23324,0&#215;2842a00) malloc: *** Deallocation of a pointer
not malloced: 0xbffffd30; This could be a double free(), or
free() called with the middle of an allocated block; Try setting
environment variable MallocHelp to see tools to help debug


Alas, calls to free() on OS X are validated to make sure they are pointing to currently malloc()ed memory. This doesn’t necessarily mean that what I have found isn’t exploitable. But I am not off to a good start.

What I like about this technique is that you can confirm whether something is exploitable quickly.

What I dislike about this technique is that you can’t confirm something isn’t exploitable. For example, assuming that it was a double free implementation that I could exploit, the application in question tosses my user input through an isalpha(). I wouldn’t have known that by solely relying on this trick.

Live and learn…



http://www.matasano.com/log/642/mystery-vulnerability-theater-3000-part-i/