Langsung ke konten utama

Notes On Windows Uniscribe Fuzzing

Posted past times Mateusz Jurczyk of Google

Among the total of 119 vulnerabilities amongst CVEs fixed past times Microsoft inwards the [1][2] together with fuzzing [3][4]. However, what makes this attempt a chip dissimilar from the previous ones is the fact that Uniscribe is a little-known user-mode component, which had non been widely recognized as a feasible laid on vector before, as opposed to the kernel-mode font implementations included inwards the win32k.sys together with ATMFD.DLL drivers. In this post, nosotros outline a brief history together with description of Uniscribe, explicate how nosotros approached at-scale fuzzing of the library, together with highlight some of the to a greater extent than interesting discoveries nosotros have got made so far. All the raw reports of the bugs we’re referring to (as they were submitted to Microsoft), together amongst the corresponding proof-of-concept samples, tin live on constitute inwards the official põrnikas tracker [5]. Enjoy!

Introduction

It was Nov 2016 when nosotros started yet some other iteration of our Windows font fuzzing task (whose architecture was thoroughly described inwards [4]). At that point, the gist laid on surface was generally fuzz-clean amongst regards to the techniques nosotros were using, but nosotros soundless similar to play amongst the configuration together with input corpus from fourth dimension to fourth dimension to consider if nosotros tin crush out whatsoever to a greater extent than bugs amongst the existing infrastructure. What nosotros ended upward amongst a several days afterward were a bunch of samples which supposedly crashed the invitee Windows organization running within of Bochs. When nosotros fed them to our reproduction pipeline, none of the bugchecks occurred 1 time again for unclear reasons. As disappointing as that was, at that topographic point also was 1 interesting together with unexpected result: for 1 of the essay cases, the user-mode harness crashed itself, without bringing the whole OS downward at the same time. This could betoken either that at that topographic point was a põrnikas inwards our code, or that at that topographic point was some unanticipated font parsing going on inwards ring-3. When nosotros started earthworks deeper, nosotros constitute out that the unhandled exception took house inwards the next context:

(4464.11b4): Access violation - code c0000005 (first chance)
First adventure exceptions are reported earlier whatsoever exception handling.
This exception may live on expected together with handled.
eax=0933d8bf ebx=00000000 ecx=09340ffc edx=00001b9f esi=0026ecac edi=00000009
eip=752378f3 esp=0026ec24 ebp=0026ec2c iopl=0         nv upward ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
USP10!ScriptPositionSingleGlyph+0x28533:
752378f3 668b4c5002      mov     cx,word ptr [eax+edx*2+2] ds:002b:09340fff=????

Until that moment, nosotros didn’t fully realize that our tools were triggering whatsoever font-handling code beyond the well-known gist implementation (despite some related bugs having been publicly fixed inwards the past, e.g. CVE-2016-7274 [6]). As a result, the fuzzing organization was non prepared to grab user-mode faults, together with thus whatsoever such crashes had remained completely undetected inwards favor of organization bugchecks, which caused total machine restarts.

We rapidly determined that the usp10.dll library corresponded to “Uniscribe Unicode script processor” (in Microsoft’s ain words) [7]. It is a relatively large module (600-800 kB depending on organization version together with bitness) responsible for rendering Unicode-encoded text, as the call suggests. From a safety perspective, it’s of import that the code base of operations dates dorsum to Windows 2000, together with includes a C++ implementation of the parsing of diverse complex TrueType/OpenType structures, inwards improver to what is already implemented inwards the kernel. The specific tables that Uniscribe touches on are primarily Advanced Typography Tables (“GDEF”, “GSUB”, “GPOS”, “BASE”, “JSTF”), but also “OS/2”, “cmap” together with “maxp” to some extent. What’s every bit pregnant is that the code tin live on reached only past times calling the DrawText [8] or other equivalent API amongst Unicode-encoded text together with an attacker-controlled font. Since no special calls other than the typical ones are necessary to execute the most exposed areas of the library, it makes for a keen laid on vector inwards applications which occupation GDI to homecoming text amongst fonts originating from untrusted sources. This is also evidenced past times the stack describe of the master crash, together with the fact that it occurred inwards a computer programme which didn’t include whatsoever usp10-specific code:

0:000> kb
ChildEBP RetAddr
0026ec2c 09340ffc USP10!otlChainRuleSetTable::rule+0x13
0026eccc 0133d7d2 USP10!otlChainingLookup::apply+0x7d3
0026ed48 0026f09c USP10!ApplyLookup+0x261
0026ef4c 0026f078 USP10!ApplyFeatures+0x481
0026ef98 09342f40 USP10!SubstituteOtlGlyphs+0x1bf
0026efd4 0026f0b4 USP10!SubstituteOtlChars+0x220
0026f250 0026f370 USP10!HebrewEngineGetGlyphs+0x690
0026f310 0026f370 USP10!ShapingGetGlyphs+0x36a
0026f3fc 09316318 USP10!ShlShape+0x2ef
0026f440 09316318 USP10!ScriptShape+0x15f
0026f4a0 0026f520 USP10!RenderItemNoFallback+0xfa
0026f4cc 0026f520 USP10!RenderItemWithFallback+0x104
0026f4f0 09316124 USP10!RenderItem+0x22
0026f534 2d011da2 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0026f54c 0000000a USP10!ScriptStringAnalyse+0x284
0026f598 0000000a LPK!LpkStringAnalyse+0xe5
0026f694 00000000 LPK!LpkCharsetDraw+0x332
0026f6c8 00000000 LPK!LpkDrawTextEx+0x40
0026f708 00000000 USER32!DT_DrawStr+0x13c
0026f754 0026fa30 USER32!DT_GetLineBreak+0x78
0026f800 0000000a USER32!DrawTextExWorker+0x255
0026f824 ffffffff USER32!DrawTextExW+0x1e

As tin live on seen here, the Uniscribe functionality was invoked internally past times user32.dll through the lpk.dll (Language Pack) library. As before long as nosotros learned most this novel laid on vector, nosotros jumped at the kickoff adventure to fuzz it. Most of the infrastructure was already inwards place, since both user- together with kernel-mode font fuzzing portion a large number of the pieces. The extra piece of work that nosotros had to practise was generally related to filtering the input corpus, piffling amongst the mutator configuration, adjusting the organization configuration together with implementing logic for the detection of user-mode crashes (both inwards the essay harness together with Bochs instrumentation). All of these steps are discussed inwards item below. After a few days, nosotros had everything working as planned, together with after some other couple, at that topographic point were already over lxxx crashes at unique addresses waiting for triage. Below is a summary of the issues that were constitute inwards the kickoff fuzzing run together with reported to Microsoft inwards Dec 2016.

Results at a glance

Since lxxx was soundless a fairly manageable number of crashes to triage manually, nosotros tried to reproduce each of them past times hand, deduplicating them together with writing downward their details at the same time. When nosotros finished, nosotros ended upward amongst 8 class high-severity issues that could potentially allow remote code execution:

Tracker ID
Memory access type at crash
Crashing function
CVE
Invalid write of n bytes (memcpy)
usp10!otlList::insertAt
CVE-2017-0108
Invalid read / write of 2 bytes
usp10!AssignGlyphTypes
CVE-2017-0084
Invalid write of n bytes (memset)
usp10!otlCacheManager::GlyphsSubstituted
CVE-2017-0086
Invalid write of n bytes (memcpy)
usp10!MergeLigRecords
CVE-2017-0087
Invalid write of 2 bytes
usp10!ttoGetTableData
CVE-2017-0088
Invalid write of 2 bytes
usp10!UpdateGlyphFlags
CVE-2017-0089
Invalid write of n bytes
usp10!BuildFSM together with nearby functions
CVE-2017-0090
Invalid write of n bytes
usp10!FillAlternatesList
CVE-2017-0072

All of the bugs but 1 were triggered through a criterion DrawText telephone telephone together with resulted inwards heap retention corruption. The 1 exception was the #1030 issue, which resided inwards a documented Uniscribe-specific ScriptGetFontAlternateGlyphs API function. The routine is responsible for retrieving a listing of alternate glyphs for a specified character, together with the interesting fact most the põrnikas is that it wasn’t a job amongst operating on whatsoever internal structures. Instead, the role failed to honor the value of the cMaxAlternates argument, together with could thence write to a greater extent than output information to the pAlternateGlyphs buffer than was allowed past times the role caller. This meant that the buffer overflow was non specific to whatsoever particular retention type – depending on what pointer the customer passed in, the overflow would have got house on the stack, heap or static memory. The exploitability of such a põrnikas would greatly depend on the computer programme pattern together with compilation options used to construct it. We must admit, however, that it is unclear what the real-world clients of the role are, together with whether whatsoever of them would encounter the requirements to conk a feasible laid on target.

Furthermore, nosotros extracted 27 unique crashes caused past times invalid retention reads from non-NULL addresses, which could potentially Pb to information disclosure of secrets stored inwards the procedure address space. Due to the large book of these crashes, nosotros were unable to analyze each of them inwards much item or perform whatsoever advanced deduplication. Instead, nosotros partitioned them past times the top-level exception address, together with filed all of them as a unmarried entry #1031 inwards the põrnikas tracker:

  1. usp10!otlMultiSubstLookup::apply+0xa8
  2. usp10!otlSingleSubstLookup::applyToSingleGlyph+0x98
  3. usp10!otlSingleSubstLookup::apply+0xa9
  4. usp10!otlMultiSubstLookup::getCoverageTable+0x2c
  5. usp10!otlMark2Array::mark2Anchor+0x18
  6. usp10!GetSubstGlyph+0x2e
  7. usp10!BuildTableCache+0x1ca
  8. usp10!otlMkMkPosLookup::apply+0x1b4
  9. usp10!otlLookupTable::markFilteringSet+0x1a
  10. usp10!otlSinglePosLookup::getCoverageTable+0x12
  11. usp10!BuildTableCache+0x1e7
  12. usp10!otlChainingLookup::getCoverageTable+0x15
  13. usp10!otlReverseChainingLookup::getCoverageTable+0x15
  14. usp10!otlLigCaretListTable::coverage+0x7
  15. usp10!otlMultiSubstLookup::apply+0x99
  16. usp10!otlTableCacheData::FindLookupList+0x9
  17. usp10!ttoGetTableData+0x4b4
  18. usp10!GetSubtableCoverage+0x1ab
  19. usp10!otlChainingLookup::apply+0x2d
  20. usp10!MergeLigRecords+0x132
  21. usp10!otlLookupTable::subTable+0x23
  22. usp10!GetMaxParameter+0x53
  23. usp10!ApplyLookup+0xc3
  24. usp10!ApplyLookupToSingleGlyph+0x6f
  25. usp10!ttoGetTableData+0x19f6
  26. usp10!otlExtensionLookup::extensionSubTable+0x1d
  27. usp10!ttoGetTableData+0x1a77

In the end, it turned out that these 27 crashes manifested 21 actual bugs, which were fixed past times Microsoft as CVE-2017-0083, CVE-2017-0091, CVE-2017-0092 together with CVE-2017-0111 to CVE-2017-0128 inwards the MS17-011 safety bulletin.

Lastly, nosotros also reported vii unique NULL pointer dereference issues amongst no deadline, amongst the promise that having whatsoever of them fixed would potentially enable our fuzzer to regain other, to a greater extent than severe bugs. On March 17th, MSRC responded that they investigated the cases together with concluded that they were low-severity DoS problems only, together with would non live on fixed as constituent of a safety bulletin inwards the nigh future.

Input corpus, mutation configuration together with adjusting the essay harness

Gathering a corporation corpus of input samples is arguably 1 of the most of import parts of fuzzing preparation, particularly if code coverage feedback is non involved, making it impossible for the corpus to gradually evolve into a to a greater extent than optimal form. We were lucky plenty to already have got had several font corpora at our disposal from previous fuzzing runs. We decided to occupation the same laid of files that had helped us regain [4]). It was originally generated past times running a corpus distillation algorithm over a large number of fonts crawled off the web, using an instrumented construct of the FreeType2 open-source library, together with consisted of 14848 TrueType together with 4659 OpenType files, for a total of 2.4G of disk space. In gild to tailor the corpus amend for Uniscribe, nosotros reduced it to precisely the files that contained at to the lowest degree 1 of the “GDEF”, “GSUB”, “GPOS”, “BASE” or “JSTF” tables, which are parsed past times the library. This left us amongst 3768 TrueType together with 2520 OpenType fonts consuming 1.68G on disk, which were much to a greater extent than probable to expose bugs inwards Uniscribe than whatsoever of the removed ones. That was the finally corpus that nosotros worked with.

The mutator configuration was also pretty similar to what nosotros did for the kernel: nosotros used the same v criterion bitflipping, byteflipping, chunkspew, special ints together with binary arithmetic algorithms amongst the precalculated per-table mutation ratio ranges. The entirely alter made specifically for Uniscribe was to add together mutations for the “BASE” together with “JSTF” tables, which were previously non accounted for.

Last but non least, nosotros extended the functionality of the invitee fuzzing harness, responsible for invoking the tested font-related API (mostly displaying all of the font’s glyphs at diverse dot sizes, but also querying a number of properties etc.). While it was clear that some of the relevant code was executed automatically through user32!DrawText amongst no modifications required, nosotros wanted to maximize the coverage of Uniscribe code as much possible. Influenza A virus subtype H5N1 total reference of all its externally available functions tin live on constitute on MSDN [9]. After skimming through the documentation, nosotros added calls to ScriptCacheGetHeight, ScriptGetFontProperties, ScriptGetCMap, ScriptGetFontAlternateGlyphs, ScriptSubstituteSingleGlyph together with ScriptFreeCache. This rapidly proved to live on a successful idea, as it allowed us to regain the aforementioned generic põrnikas inwards ScriptGetFontAlternateGlyphs. Furthermore, nosotros decided to withdraw invocations of the GetKerningPairs together with GetGlyphOutline API functions, as their corresponding logic was located inwards the kernel, piece our focus had instantly shifted strictly to user-mode. As such, they wouldn’t Pb to the uncovering of whatsoever novel bugs inwards Uniscribe, but would instead tiresome the overall fuzzing procedure down. Apart from these tike modifications, the core of the essay harness remained unchanged.

By taking the measures listed above, nosotros hoped that they were sufficient to trigger most of the depression hanging fruit bugs. With this assumption, the entirely constituent left was to brand certain that the crashes would live on reliably caught together with reported to the fuzzer. This dependent area is discussed inwards the adjacent section.

Crash detection

The kickoff stair nosotros took to regain Uniscribe crashes effectively was disabling Special Pools for win32k.sys together with ATMFD.DLL (which caused unnecessary overhead for no gain inwards user-mode), piece enabling the PageHeap pick inwards Application Verifier for the harness process. This was done to improve our chances at detecting invalid retention accesses, together with brand reproduction together with deduplication to a greater extent than reliable.

Thanks to the fact that the fuzz-tested code inwards usp10.dll executed inwards the same context as the residue of the harness logic, nosotros didn’t have got to write a full-fledged Windows debugger to supervise some other process. Instead, nosotros precisely laid upward a top-level exception handler amongst the SetUnhandledExceptionFilter function, which so got called every fourth dimension a fatal exception was generated inwards the process. The handler’s task was to ship out the the world of the crashing CPU context (passed inwards through ExceptionInfo->ContextRecord) to the hypervisor (i.e. the Bochs instrumentation) through the “debug print” hypercall, together with so genuinely written report that the crash occurred at the specific address.

In the gist font fuzzing scenario, crashes were detected past times the Bochs instrumentation amongst the BX_INSTR_RESET instrumentation callback. This approach worked because the invitee organization was configured to automatically reboot on bugcheck, consequently triggering the bx_instr_reset handler. The easiest agency to integrate this approach amongst user-mode fuzzing would live on thence to precisely add together a ExitWindowsEx telephone telephone inwards the epilogue of the exception handler, making everything piece of work out of the box without fifty-fifty touching the existing Bochs instrumentation. However, the method would resultant inwards losing information most the crash location, making automated deduplication impossible. In gild to address this problem, nosotros introduced a novel “crash encountered” hypercall, which received the address of the faulting didactics inwards the declaration from the guest, together with passed this information farther downward our scalable fuzzing infrastructure. Having the crashes grouped past times the exception address correct from the start saved us a ton of postprocessing time, together with express the number of essay cases nosotros had to human face at to a bare minimum.

This is the terminate of a listing of differences betwixt the Windows gist font fuzzing setup we’ve been using for nearly ii years now, together with an equivalent setup for user-mode fuzzing that nosotros entirely built a few months ago, but has already proven real effective. Everything else has remained the same as described inwards the “font fuzzing techniques” article from finally twelvemonth [4].

Conclusions

It is a fascinating but dire realization that fifty-fifty for such a good known class of põrnikas hunting targets as font parsing implementations, it is soundless possible to regain novel laid on vectors dating dorsum to the previous century, having remained largely unaudited until now, together with existence as exposed as the interfaces nosotros already know about. We believe that this is a keen instance of how gradually ascension the bar for a multifariousness of software tin have got much to a greater extent than comport upon than trying to kill every finally põrnikas inwards a narrow hit of code. It is also illustrative of the fact that the fourth dimension spent on thoroughly analyzing the laid on surface together with looking for little-known targets may plough out real fruitful, as the safety community soundless doesn’t have got a total agreement of the laid on vectors inwards every of import information processing stack (such as the Windows font treatment inwards this case).

This attempt together with its results demo that fuzzing is a real universal technique, together with most of its components tin live on easily reused from 1 target to another, particularly within the compass of a unmarried file format. Finally, it has proven that it is possible to fuzz non precisely the Windows kernel, but also regular user-mode code, regardless of the surround of the host organization (which was Linux inwards our case). While the Bochs x86 emulator incurs a pregnant overhead as compared to native execution speed, it tin oft live on scaled against to soundless attain a internet gain inwards the number of iterations per second. As an interesting fact, issues #993 (Windows gist registry hive loading), #1042 (EMF+ processing inwards GDI+), #1052 together with #1054 (color profile processing) fixed inwards the finally Patch Tuesday were also constitute amongst fuzzing Windows on Bochs, but amongst slightly dissimilar input samples, essay harnesses together with mutation strategies. :)

References

  1. The “One font vulnerability to dominion them all” serial starting amongst https://plantillasnowcrystalsdelui.blogspot.com//search?q=one-font-vulnerability-to-rule-them-all
  2. https://msdn.microsoft.com/pl-pl/library/windows/desktop/dd374093(v=vs.85).aspx

Komentar

Postingan populer dari blog ini

Exception-Oriented Exploitation On Ios

Posted past times Ian Beer, This postal service covers the regain in addition to exploitation of CVE-2017-2370 , a heap buffer overflow inwards the mach_voucher_extract_attr_recipe_trap mach trap. It covers the bug, the evolution of an exploitation technique which involves repeatedly in addition to deliberately crashing in addition to how to build alive meat introspection features using onetime meat exploits. It’s a trap! Alongside a large number of BSD syscalls (like ioctl, mmap, execve in addition to so on) XNU also has a pocket-sized number of extra syscalls supporting the MACH side of the meat called mach traps. Mach trap syscall numbers start at 0x1000000. Here’s a snippet from the syscall_sw.c file where the trap tabular array is defined: /* 12 */ MACH_TRAP(_kernelrpc_mach_vm_deallocate_trap, 3, 5, munge_wll), /* xiii */ MACH_TRAP(kern_invalid, 0, 0, NULL), /* xiv */ MACH_TRAP(_kernelrpc_mach_vm_protect_trap, 5, 7, munge_wllww), Most of the mach traps a

Lifting The (Hyper) Visor: Bypassing Samsung’S Real-Time Total Protection

Posted yesteryear Gal Beniamini, Traditionally, the operating system’s total is the concluding security boundary standing betwixt an assaulter together with total command over a target system. As such, additional aid must hold upwards taken inwards lodge to ensure the integrity of the kernel. First, when a organization boots, the integrity of its primal components, including that of the operating system’s kernel, must hold upwards verified. This is achieved on Android yesteryear the verified kicking chain . However, only booting an authenticated total is insufficient—what most maintaining the integrity of the total spell the organization is executing? Imagine a scenario where an assaulter is able to abide by together with exploit a vulnerability inwards the operating system’s kernel. Using such a vulnerability, the assaulter may endeavor to subvert the integrity of the total itself, either yesteryear modifying the contents of its code, or yesteryear introducing novel attacker-co

Chrome Bone Exploit: 1 Byte Overflow As Well As Symlinks

The next article is an invitee weblog post from an external researcher (i.e. the writer is non a or Google researcher). This post is most a Chrome OS exploit I reported to Chrome VRP inward September. The folks were squeamish to allow me do a invitee post most it, therefore hither goes. The study includes a detailed writeup , therefore this post volition have got less detail. 1 byte overflow inward a DNS library In Apr I constitute a TCP port listening on localhost inward Chrome OS. It was an HTTP proxy built into shill, the Chrome OS network manager. The proxy has at nowadays been removed equally component of a fix, but its source tin give notice nonetheless move seen from an one-time revision: shill/http_proxy.cc . The code is unproblematic in addition to doesn’t seem to incorporate whatever obvious exploitable bugs, although it is real liberal inward what it accepts equally incoming HTTP. It calls into the c-ares library for resolving DNS. There was a possible 1 byte ov