Presentation is loading. Please wait.

Presentation is loading. Please wait.

An Examination of String Allocations: IE-9 Edition Chris Valasek, Director of Security Intelligence

Similar presentations


Presentation on theme: "An Examination of String Allocations: IE-9 Edition Chris Valasek, Director of Security Intelligence"— Presentation transcript:

1 An Examination of String Allocations: IE-9 Edition Chris Valasek, Director of Security Intelligence

2 An Examination of String Allocations: IE-9 Edition

3 An Examination of String Allocations: IE-9 & 10 Edition

4 An Examination of String Allocations: IE-9 to11 Edition Chris Valasek, Director of Security Intelligence

5 Introduction Chris Valasek Director of Security IOA <3 Windows memory stuff Car Hacking! Pittsburgh PA USA Chairman of Summercon Fun Fact: I like cheese

6 Overview Brief history of Javascript string allocations in IE6-7 JavaScript string changes in IE-9 IE-9 Core JavaScript Methods IE-9 DOM Strings Premier: heapLib2 Note: Non-comprehensive list Note: Algorithms seem to be the same for IE-10 and IE-11

7 Why? Nico’s APT talk at Blackhat USA 2010 mentioned the following: “IE 8 introduced a weak heap spray protection” There didn’t appear to be any public information explaining the statement Sotirov published “Heap Feng Shui” but no such information was available for IE-9 (Skipping IE-8 at this point…) Memory management makes me smile…then scream…then cry…then smile again.

8 Impact Browser exploitation requires knowledge of sizes / objects for subsequent allocation/de-allocation of those objects For example: Use-after-free bugs, to be exploited without ‘pray-after-free’, will require intricate knowledge of object sizes and subsequent allocations/frees Heap spraying still tends to be common during browser exploitation but has had limited updates since IE-8 See Corelan Team & Nico’s references in later slides Exploitation can take less time with added knowledge of JS and DOM objects

9 Requisite Reading Nico Waisman – “Aleatory Persistent Threat” Alex Sotirov – “Heap Feng Shui in JavaScript” Dowd, Smith, Dewey – “Attacking Interoperability”

10 History

11 History: I Heap spraying made wildly popular by Skylined in MS Wow, its been a long time Sotirov documented the allocation / de-allocation process Concatenating strings could cause allocations (jscript!JsStrConcat) Creating substrings could cause allocations (jscript!JsStrSubstrCore) Freeing of chunks could be achieved by setting a string to NULL and performing garbage collection It was quite easy to make allocations in IE6-7

12 History: II Each iteration of the loop would create a new copy of the string, storing it in the array

13 History: III The aforementioned method no longer worked in IE-8 Corelan Team suggested some variations https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial- part-11-heap-spraying-demystified/ https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial- part-11-heap-spraying-demystified/ Nico also suggested a work around (that inspired this research)

14 History: IV Substring? Array Assignment? Not really sure since I didn’t look at IE-8

15 IE-9 Strings

16 JavaScript Strings: IE-9 Not just a simple bstr object anymore Concatenation and substring calls don’t mindlessly allocate memory Jscript9.dll has replaced jscript.dll Jscript.dll is NOT loaded in IE-9 Versions Jscript9.dll (might be a few versions off) Mshtml.dll

17 Core Methods

18 Core: ArenaLiteralString Js::ArenaLiteralString::New Base for static strings created in JS Var a = “CHRIS”; Var b = new String(“Chris”); Var c = unescape(“%u9090”); Transformed as needed Example: unescape() == Js::StringBuilderString::New() The strings are allocated from an arena, so you won’t see allocations for individual strings in default heap Var a = “AAAABBBB” != malloc((a.length * 2) + 6) [Like it did in IE-6]

19 Core: ConcatString Js::ConcatString::New Stores pointers to the concat-er and concat-ee No longer will allocate per concatenation We’ll see later how and were allocations occur The strings passed can be any JavascriptString StringBuilderString, ArenaLiteralString, even another ConcatString Smells like:

20 Core: ConcatString cont. The ConcatString objects come from pre-allocated, page aligned HeapBuckets.

21 Core: ConcatString cont. II Pointers are stored instead of allocating/copying data.

22 Core: SubString Js::SubString::New Will expand the JavaScript string if need be Allocations will come from PageAllocator, so completely controlled allocations will not occur  Holds references and will expand/flatten only 1x Smells like:

23 Core: SubString cont.

24 Core: Example

25 Core: Example Part I Events Js::ArenaLiteralString::New with “%u9090%u9090%u9090%u9090” The string has yet to be unescaped at this point Also, the memory holding the string isn’t allocated from the default heap, instead it uses a page-based allocator for string objects Js::GlobalObject::EntryUnEscape Convert the values to 0x9090 0x9090 0x9090 Call the functions below…. Js::JavascriptConversion::ToString Js::StringBuilderString::New As you see, this does NOT have a precise allocation from the default heap

26 Core: Example Part II Iterations 1. ConcatString [LHS=>str_builder, RHS=>str_builder, length=>0x10] LHS => StringBuilderString | RHS = StringBuilderString 2. ConcatString [LHS=>str_builder, RHS=>str_builder, length=>0x20] LHS => ConcatString | RHS = ConcatString 3. ConcatString [LHS=>str_builder, RHS=>str_builder, length=>0x40] LHS => ConcatString | RHS = ConcatString 4. ConcatString [LHS=>str_builder, RHS=>str_builder, length=>0x80] LHS => ConcatString | RHS = ConcatString 5. ConcatString [LHS=>str_builder, RHS=>str_builder, length=>0x100] LHS => ConcatString | RHS = ConcatString After the 1 st iteration ‘str_builder’ is now a ConcatString No allocation occur during this process Also ConcatString->str == NULL

27 Core: Example Part III Events Js::Substring::New passing the ConcatString created in our loop If str_builder->str == NULL { str_builder->GetSz } This is the case, so Js::ConcatString::GetSz() will be called Js::ConcatString::GetSz() will call Js::ConcatString::Flatten Js::ConcatString::Flatten call Recycler::AllocLeaf Recycler::AllocLeaf check size If str_builder.length < 0x400 HeapBucket::SnailAlloc(Recycler, this, Round16(str_builder.length), 0); *This will allocate from the Recyler PagePool If str_builder.length >= 0x400 Recycler::TryLargeAlloc(str_builder.length, this, Recycler, 0); *This can possibly trigger a call to VirtualAlloc, but won’t be exact *VirtualMemory Allocation granularity Again, not precise direct allocations from default heap…

28 Core: Example Part IV Events Js::Substring::New passing the ConcatString created in our loop If str_builder->str == NULL { str_builder->GetSz } This is the case, so Js::ConcatString::GetSz() will be NOT called Since our ConcatString has been flattened / copied in the previous call to “substring” it doesn’t need to happen again String allocation from the pool only happens once to avoid the need of multiple copies of the same string

29 Core: Conclusion Static strings are allocated from a page-aligned memory i.e. var a = “CHRIS” does NOT directly hit the default heap JavaScript objects are allocated from HeapBuckets i.e. ConcatString, SubString, etc HeapBucket is pooled memory which will only alloc from default heap in pages Much more efficient an allocations for substrings/concatenations While not officially ‘heap spray protection’, it does prevent previous methods from achieving their goal Are there still ways to get allocations from the default process heap with JS strings? Hint: Yup

30 DOM Memory Management

31 DOM: Elements Most familiar piece of the Document Object Model Each tag is allocated from the default process heap Each tag also consists of a certain amount of bytes For example: Anchor Tag “ ” == 0x64 byte allocation Bold Tag “ ” == 0x30 byte allocation Simple way to create elements statically or dynamically for precise allocations from the default heap

32 DOM: Elements cont. I’ve created a script that will attempt to pull the allocation call for each HTML tag in MSHTML.DLL Nico’s chart in his APT talk. Instead of re-creating I wrote a script It’s called “get_elements.py”

33 DOM: Attributes Element attributes are allocated directly (well, sort of) from the default heap They last the lifetime of the page (or until you remove them) i.e. fully controlled Creates null terminated string They have a certain Variant type See Dowd, Smith, Dewey paper Certain global attributes exist for all elements, such as ‘title’ See mshtml_1.html

34 DOM: Custom Attributes HTML5 supports custom attributes For example: Hello Yes I know this breaks W3 standards. Should start with “data-” Above custom attribute with the name “wonk-attr” The value “specialvalue” will be allocated based on its string length from the default process heap! They last the lifetime of the page (or until you remove them) i.e. fully controlled Creates your typical bstr object See mshtml_2.html

35 DOM: Attribute Shellcode Since we know that attributes can be used to directly allocate user-controlled amounts of data from the default process heap… Let’s have UTF-8 and UTF-16 be our friends ‘html_spray.py’ Python code to generate massive payload statically in HTML Gzip from the server, drastically shrinking the size, and send to client *Note: I haven’t not thoroughly tested this, only saw allocations working See ‘html_spray.html’

36 DOM: Static Attributes All the attributes we talked about in the last few slides would static. i.e. known before the DOM has been laid out Follow the call chain: MSHTML!BASICPROPPARAMS::SetString =>MSHTML!CAttrArray::SetString => CAttrValue::InitVariant => MSHTML!_HeapAllocString _HeapAllocString will allocate the amount of bytes in the string from the default process heap and copy the data But I don’t wanna create all the elements before hand….

37 DOM: Credit Corelan Team had the right idea Certain attributes exist for all elements, such as ‘title’ https://www.corelan.be/index.php/2013/02/19/deps-precise- heap-spray-on-firefox-and-ie10/ https://www.corelan.be/index.php/2013/02/19/deps-precise- heap-spray-on-firefox-and-ie10/ There’s a reason this works really well ‘title’ is a slightly different variant type as opposed to custom attribute Attributes are just another Variant type in IE See Dowd, Smith, Dewey paper

38 Custom Attributes

39 Custom Attibutes: Creation I’m a learn by example type of guy….

40 Custom Attributes: Creation cont. Call to ‘setAttribute()’ will marshal the JavascriptString to a bstr used by the DOM DispatchHelper::MarshalJsVarsToVariants This lazy allocation ensures that the PageAllocator is used for JS strings while the default process heap is only required when necessary, such as augmenting the DOM Dynamically Created Custom Attribute: Call chain MSHTML!CAttrArray::SetAt => MSHTML!CAttrValue::InitVariant (Type 0x08) => MSHTML!EdUtil::FormsAllocStringW => OLEAUT32!SysAllocString => OLEAUT32!SysAllocStringLen => OLEAUT32!APP_DATA::AllocCachedMem That last one looks familiar!

41 Dynamic Attribute Assign: Sidebar Not all attributes are created equal Global Attribute (title, class, lang, etc) MSHTML!CAttrArray::SetString => MSHTML!CAttrArray::Set => MSHTML!CAttrValue::InitVariant (Type 0x31) => MSHTML!_HeapAllocString You can see, for instance, that the ‘title’ attribute would bypass the cache allocator, directly accessing the default process heap Good work Corelan Team, just wanted to point out intricacies ;) Hint: There are probably more. Look for XREFS to _HeapAllocString

42 Custom Attributes: Destruction Can we free memory at will too? Sure we can! In the previous example we saw that ‘setAttribute(name, value)’ was used to allocate memory All we have to do is ‘setAttribute(name, null)’ and the value will be freed! MSHTML!CAttrArray::SetAt => MSHTML!CAttrValue::Free => kernel32!HeapFree => ntdll!RtlFreeHeap Now we have a plan for heap massaging!

43 heapLib2

44 heapLib2: Overview I saw that dynamic custom attributes were allocated from OLEAUT32!APP_DATA::AllocCachedMem After investigation, I realized the allocator hasn’t changed since IE-6 So long as I can refactor the plunger technique written by Sotirov years ago, we can have precision allocations See: Steps Populate cache before freeing Clear cache before allocating Also, since we can create large strings in JS and marshal them to the default process heap, we can heap spray like it’s 2004 Note: There is overhead with creating attributes malloc(0x60) being one of many….

45 heapLib2: Example

46 heapLib2: Demo

47 Conclusions

48 Precise allocations are nearly impossible to achieve directly from Javascript in IE-9 This seems like ‘heap spray protection’ but I think was more of an architecture change Someone from MSFT let me know if I’m wrong To make allocations directly from the default process heap one can leverage the DOM I found that custom attributes were a nifty way of doing this heapLib2 permits allocations of arbitrary sizes and provides functionality to do easy heap sprays There is a bunch more research to be had The Recyler is really neat / confusing

49 Continuation! I’ll be releasing a white paper at some point Much more information about DOM / JS objects Detailed notes: Recycler, HeapBuckets, PoolAllocator, etc Follow me on Twitter and check the IOActive blog as I’ll be putting slides, examples, and heapLib2 for public download Alex Sotirov should get most of the credit as he figured all this stuff out years ago, I just augmented it to work w/ IE-9 – IE-11 Thanks!

50 Questions? Chris Valasek @nudehaberdasher


Download ppt "An Examination of String Allocations: IE-9 Edition Chris Valasek, Director of Security Intelligence"

Similar presentations


Ads by Google