Exception or exploit by qfc10548


									                  Hacking QuickTime:
                  Exception or Exploit?

                         Jared DeMott
                Crucial Security Business Area

Presentation1                                    5-Sep-10
Quote to Remember

• ―Bugs are found in a variety of ways. But good
  exploits are created in a debugger, by someone who
  knows the trade well.‖

What am I talking about?

• The scoop
        – Former student of mine, says the hardest part about
          his job (he extends and uses fuzzers) is
                • ―identifying what my exceptions are and what causes
• The answer
        – Ok, well maybe not ―the‖ answer, but this talk is
          tended to introduce you to this problem set and shed
          some light on finding the answer

• How long does it take to create an exploit anyway,
  once you think you‘ve got a good bug?

It depends … on a lot of things

    Heap Overflow on Vista could take 36-94 work days (or more)
      to determine/develop reliable exploit
                         -- Nicolás Waisman
                                   from ―Apology of 0days”

    ―One researcher's obscure crash is another researcher's reliable
      exploit. What determines the difference between 'just a bug'
      and 'fully exploitable' is often a mix of skill, determination and
      sheer chance‖
           (but once patch is out stating exploitability)
    ―Considering the skill levels of modern public security
      researchers, the time frame from security update to exploit
      has gone down from weeks to – in some cases – hours.‖
                            -- Bas Alberts
                                   from ―A Bounds Check on the Microsoft
                                   Exploitability Index”
What does it depend on again?

• Platform protections
        – /gs, aslr, dep, SEHOP, etc
• Type of vulnerability
        – Not memory corruption
                • Most like web app data input like XSS or SQL injection
        – Memory corruption
                • generally read or write issue to heap or stack
• Skill of researcher
        – Some simply know more than others
        – Have a stronger support team, peers, or mentors
        – Funding and time allocated to researcher

MS uses the color by number system

        ―We have established that an exploitability index is an indicator of
                likelihood and hence, not an exact science … All this represents a
                considerable effort, but it is an effort that has to be made if an
                exploitability index is to represent something meaningful. The
                Microsoft Exploitability Index represents a major public
                commitment of the security….‖

• As it stands, Microsoft commits to three different
  degrees of exploitability for the index:
        “1 - Consistent exploit code likely”
        “2 - Inconsistant exploit code likely”
        “3 - Functioning exploit code unlikely”

Quick Disclaimer

• We‘ll see as we move through - not an exact science
• If it were easy Microsoft would be right more than
        – As to rather exploit code will show up or not for a
          particular bug
                • http://tech.slashdot.org/article.pl?sid=08/11/14/0617229
• Other the other hand, getting a handle on the basics
  is certainly possible in a 1hr talk
        – Getting hands on practice is of course something
          different … so go and fuzz something
                • The hardest part of most projects is still getting started

Target Background

• It goes without saying that we‘ll assume you have
  some idea of the type of exploit you‘re hoping to
        – Working a client side for vista will be much different
          than working an old server exploit for SCO Unix

Most Interesting Target(s)

 • For Windows, client side exploitation is probably the
   most interesting currently
          – Server side stuff is hard to exploit, and less gain if
            you‘re a spammer, adware, malware type
                • More heavily/knowledgably monitored as well
          – Plus, with client side stuff … you get the yummy land
            of browserhood
                • Stack overflows in plug-ins are nice
                  – Example: In Vista, could leverage techniques like the .Net
                    or Java RWX heap, to gain control of the victim if you
                    have the plug-in attack ready
                  – XP is even easier since strait heap spraying works

Fuzzing Background

• The idea with fuzzing is to monitor an application
  while you ―run it through it‘s paces‖ with semi-valid
  and ideally semi-intelligent data
• When the monitor (normally a debugger or the like)
  records an exception, you know you have a bug
• But, if you‘re new to the game, and just cooked up
  your first fuzzer, what do you make of those

• Exploit or Exception?

8 Main Steps for Bit Flipper

    •      Find/Create Fuzzer
    •      Find sample files
    •      Generate semi-invalid samples
    •      Fuzz Application
             – Log such that you know which file caused fault
    • Review Faults
    • AptDiff( GoodFile , Mutated file)
    • Change each difference back, to identify the byte
      that caused the fault
    • Verify/Debug to determine exploitability

A Fuzzer in Action – Example 1

• One simple fuzzer from our book (Chpt 9)
        – Randomly flips a few bytes in sample
        – DEMO: Finds crashes in QuickTime
        – Here‘s one such example
                 •   Process:     QuickTime Player [44996]
                 •   Code Type:      X86 (Native)
                 •   Parent Process: bash [36856]
                 •   Date/Time:     2008-07-22 14:09:41.453 -0400
                 •   OS Version:    Mac OS X 10.5.4 (9E17)
                 •   Report Version: 6
                 •   Exception Type: EXC_ARITHMETIC (SIGFPE)
                 •   Exception Codes: EXC_I386_DIV (divide by zero)
                 •   Crashed Thread: 0

So is that bug Serious?

• Well, all bugs are serious to the development team
        – But we want to know if we could turn this into and exploit and
          make some cash selling it
• First, what was the exception code? ―SIGFPE‖
        – type ‗kill –l‘ if you‘re not sure of the name  numbers
        1) SIGHUP              2) SIGINT       3) SIGQUIT 4) SIGILL
        5) SIGTRAP             6) SIGABRT 7) SIGEMT         8) SIGFPE
        9) SIGKILL            10) SIGBUS 11) SIGSEGV 12) SIGSYS
        13) SIGPIPE           14) SIGALRM 15) SIGTERM 16) SIGURG
        17) SIGSTOP           18) SIGTSTP 19) SIGCONT 20) SIGCHLD
        21) SIGTTIN           22) SIGTTOU 23) SIGIO        24) SIGXCPU
        25) SIGXFSZ          26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
        29) SIGINFO           30) SIGUSR1 31) SIGUSR2

This is the part of the talk
where you hate me

• And that‘s because security researches are
  constantly coming up with new ways/techniques to
  exploit bugs previously thought unexploitable
        – The classic example of this comes from:
                 • ―The vulnerability in question is an exploitable NULL-
                   pointer dereference of …‖
• So really, it‘s tough to say ―this isn‘t exploitable‖ if an
  exploit cannot be developed. But provable to say
  exploitable if you can develop an exploit.

So then what can we say?

• If we think it is exploitable…
        – And can prove it is; case closed
• If we think it‘s iffy…
        – Good chance could be exploitable, but we just don‘t know how
                 • But, if in your organization, it looks to be beyond a reasonable
                   level of effort, that‘s fine. Move on.
• If we think it‘s not…
        – Since there‘s no known/clear way to exploit
        – And you don‘t currently have time/budget to research totally new
          exploitation techniques
                 • Normally a good idea to close the books on it and move to more
                   fertile ground. If you can find one crash, good chance you can
                   find two.

        Prioritization is where next generation fuzzers are headed…

Given that, what‟s the point of
this Talk?

• Training
        – While it‘s true it‘s tough to positively rule a crash out,
          you can ―triage‖ or weed through a bunch of
          exceptions quickly, so that you can focus on the ones
          that stand a better chance of being exploitable
        – This is only possible if you know about different
          exception types

Yes, perhaps I do have
• But that‘s why were here, so back to the QuickTime
  crash from my Mac
        – SIGFPE is the signal sent to computer programs that perform
                 erroneous arithmetic operations on POSIX compliant platforms. The
                 symbolic constant for SIGFPE is defined in the header file signal.h.
                 Symbolic signal names are used because signal numbers can vary
                 across platforms.
• So….. is it exploitable or not? Probably not.
        – Why? Because the chance for memory corruption, and
          thus execution redirection looks minimal. See
                     int main() {
                       int x = 42/0;
                       return 0; /* Never reached */


• Ok, so, true, if QuickTime wasn‘t crashing on a
  normal movie, but after a few bytes flipped we get
  the SIGFPE, how can we rule this out as exploitable
  condition without extensive reverse engineering?
        – I hear that. You really always need to reverse each
          exception to gain full understanding of the crash
                 • GET TO THE ROOT CAUSE VIA REing
                   – If the value is used to influence allocation or similar
                     functions, it could still have a chance of being exploitable
        – On the other hand, no invalid memory access is
          directly happening here, so the chances that it would
          be exploitable seems very thin

Reverse, Reverse, Reverse

• Manually Twiddling bits
        – Identify the fuzzy byte that caused the crash, and try to
          give a proper byte(s)
                 • Helps with REing
• File format specifications
        – I‘ve found good docs from Apple in the past like the
          one describing QT movies
• Dynamic analysis
        – gdb, olly, …
• Static analysis
        – IDA pro
• whatever it takes

What exceptions are the most

    • Signal 11– SIGSEGV
             – Always the hottest because it means we‘re already
               dealing with a memory read/write issue
    • Signal 6 – SIGABRT
             – On Linux (glibc) Interesting since this often indicates
               heap issues when fuzzing
    • Other signals
             – Have to be considered less interesting and prioritized
               for reverse engineering as such
                 • BUT, again could still be issues!
                 • In fact, there could be issues that don‘t show up as
                   signals at all – oh … missed bugs…

Say that again?

• Yah, sorry, the worst case, and toughest exception to
  analyze is the one you didn‘t get

• It‘s not just about the exceptions though
        – Out of bounds READS aren‘t normally all that helpful
          for exploitation
                 • We want a SEGV based on a write operation

Is there more advanced

• Sure, you can get as fancy as it as you like
        – Monitoring things like memory allocations, CPU usage,
          and more
        – Occasionally used in fuzzing
                 • But that type of stuff is more for the traditional QA expert
                 • Exception understanding in terms of exploitation is more
                   geared toward security testing
        – Building complex tools is cool and needed
                 • But right now for soft targets like QT… no need

Example 2: Malloc Failure in
QT (in a .mov file)
• Noticed this entry in system.log
        – Jan 15 14:31:19 jared-demotts-macbook-pro
          QuickTime Player[30572]: QuickTime
          Player(30572,0xa025b720) malloc: ***
          mmap(size=1593843712) failed (error code=12)\n***
          error: can't allocate region\n*** set a breakpoint in
          malloc_error_break to debug
• Did not cause a crash like the SIGFPE which makes
  this possibly less attractive

Which byte(s) are the issue?

• I use AptDiff
        – Compare original file vs. Mutated file

• Change each modified byte back to original until you
  identify the one byte(s) that caused the issue
        – Should probably automate this, but I‘ve found it to be
          easy enough by hand

File formats

• A container format is a computer file format that
  can contain various types of data, compressed by
  means of standardized audio/video codecs
• The container file is used to identify and interleave
  the different data types
        – Simpler container formats can contain different types
          of audio codecs
        – more advanced container formats can support multiple
          audio and video streams, subtitles, chapter-
          information, and meta-data (tags) — along with the
          synchronization information needed to play back the
          various streams together

 Simple Reversing the File
Go and get http://developer.apple.com/DOCUMENTATION/QuickTime/QTFF/qtff.pdf


Use sample size atoms to
specify the size of each
sample in the media. Sample
size atoms have an atom type
of 'stsz'.

The sample size atom contains
the sample count and a table
giving the size of each sample.
This allows the media data
itself to be unframed. The total
number of samples in the
media is always indicated in
the sample count. If the default
size is indicated, then no table


  •      Size (01 00 00 01)
           – A 32-bit integer that specifies the number of bytes in this sample size atom.
  •      Type (‗stsz‘)
           – A 32-bit integer that identifies the atom type; this field must be set to 'stsz'.
  •      Version (7a)
           – A 1-byte specification of the version of this sample size atom.
  •      Flags (00 00 00)
           – A 3-byte space for sample size flags. Set this field to 0.
  •      Sample size (00 00 00 00)
           – A 32-bit integer specifying the sample size. If all the samples are the same size, this
             field contains that size value. If this field is set to 0, then the samples have different
             sizes, and those sizes are stored in the sample size table.
  •      Number of entries (00 00 00 00)
           – A 32-bit integer containing the count of entries in the sample size table.
  •      Sample size table (01 00 00 3c)
           – A table containing the sample size information. The sample size table contains an
             entry for every sample in the media‘s data stream. Each table entry contains a size
             field. The size field contains the size, in bytes, of the sample in question. The table is
             indexed by sample number—the first entry corresponds to the first sample, the
             second entry is for the second sample, and so on.

Things that make you go

                 70707070 is the number that gets used as a bad malloc size

.gdbinit file to get QT in GDB

                 break ptrace
                   commands 1

The BackTrace in GDB

Breakpoint 2, 0x91eec4a9 in malloc_error_break ()   #18 0x12984770 in internalDoAction ()
(gdb) bt                                            #19 0x12975732 in _MCIdle ()
#0 0x91eec4a9 in malloc_error_break ()              #20 0x1297097d in _MCComponentDispatch ()
#1 0x91ee7497 in szone_error ()                     #21 0x96060a95 in CallComponentDispatch ()
#2 0x91e148d6 in allocate_pages ()                  #22 0x00517db3 in MCIdle ()
#3 0x91e150c2 in large_and_huge_malloc ()           #23 0x00516196 in QTOMovieObject::SendCommand
#4 0x91e0c228 in szone_malloc ()                    #24 0x004169ae in DispatchQTMsg ()
#5 0x91e0c018 in malloc_zone_malloc ()              #25 0x004166d5 in
#6 0x91e0bfac in malloc ()                              QTObjectTokenPriv::SendMessageToObject ()
#7 0x128b4621 in loadTheChunk ()                    #26 0x00415ca6 in
#8 0x128b8bf3 in addNewSchedule ()                      QTObjectTokenPriv::DispatchMessage ()
#9 0x128b9610 in LoadAFrame ()                      #27 0x0051601a in QTSendToObject ()
#10 0x128be76b in v2m_doWhatTheMentorTellsUs ()     …
#11 0x128c0375 in Video2MoviesTask ()
#12 0x9606112f in CallComponentFunctionCommon ()
#13 0x128af505 in Video2ComponentDispatch ()
#14 0x96060a95 in CallComponentDispatch ()
#15 0x004d1003 in MediaMoviesTask ()
#16 0x0042cf54 in TaskMovie_priv ()
#17 0x129758d1 in doIdleMovie ()

 Register Dump

gdb) up                                     eax         0x0 0
#1 0x91ee7497 in szone_error ()             ecx        0xbfffd66c    -1073752468
#2 0x91e148d6 in allocate_pages ()          edx         0x91e0b1c6   -1847545402
(gdb)                                       ebx         0x91e0bfd5   -1847541803
#3 0x91e150c2 in large_and_huge_malloc ()   esp         0xbfffd8c0   0xbfffd8c0
(gdb)                                       ebp         0xbfffd8d8   0xbfffd8d8
#4 0x91e0c228 in szone_malloc ()
(gdb)                                       esi       0x0 0
#5 0x91e0c018 in malloc_zone_malloc ()      edi        0x70707084    1886417028
(gdb)                                       eip        0x91e0bfac    0x91e0bfac
#6 0x91e0bfac in malloc ()                      <malloc+55>
(gdb) i r                                   eflags      0x246        582
                                            cs        0x17 23
                                            ss        0x1f 31
                                            ds         0x1f 31
                                            es         0x1f 31
            DEMO                            fs        0x0 0
                                            gs         0x37 55
Final Guesstimate

 • I can twiddle the 70707070 number to get large mallocs
          – Tried boundaries
                 •   ffffffff
                 •   00000000
                 •   7fffffff
                 •   etc.
          – None caused crashes
                 • Probably QT validates if the number is negative and such?
                 • only see the malloc issue with inputs 5dxxxxxx – 7fxxxxxx
          – Exploitation seems unlikely since a crash was not found
                 • GuardMalloc didn‘t allow such large allocations

Example 3: Non-aligned Free
in QT (in a .3g2 file)
• Noticed this entry in system.log
        – Jan 22 12:58:06 jared-demotts-macbook-pro
          QuickTime Player[449]: QuickTime
          Player(449,0xa025b720) malloc: *** error for object
          0xbfffd408: Non-aligned pointer being freed\n*** set a
          breakpoint in malloc_error_break to debug
• Also did not cause a crash
        – GuardMalloc didn‘t like this saying
                 • ―Freeing a pointer that we didn‘t allocate that was not
                   claimed by any registered zone‖

esds this time


• An MPEG-4 elementary stream descriptor atom
        – This extension is required for MPEG-4 video
                 • MPEG-4 is a collection of methods defining compression
                   of audio and visual (AV) digital data
        – .3g2 was the file extension
                 • 3GP is a multimedia container format defined by the
                   Third Generation Partnership Project (3GPP) for use on
                   3G mobile phones but can also be played on some 2G
                   and 4G phones.

esds header data

• Size ( ca 00 00 00)
        – An unsigned 32-bit integer holding the size of the
          elementary stream descriptor atom.
• Type (‗esds‘)
        – An unsigned 32-bit field containing the four-character code
• Version (00)
        – An unsigned 8-bit integer set to zero.
• Flags (00 00 00)
        – A 24-bit field reserved for flags, currently set to zero.
• Elementary Stream Descriptor (rest of data in this block?)
        – An elementary stream descriptor for MPEG-4 video, as
          defined in the MPEG-4 specification ISO/IEC14496-1 and
          subject to the restrictions for storage in MPEG-4 files
          specified in ISO/IEC 14496-14.

Elementary Stream
• Trouble finding a solid file format
• ‗QLCMfmt‘ and ‗Qcelp 13K‘ turn up
        – http://www.potaroo.net/ietf/idref/draft-garudadri-qcp/
        – Explains bytes from QLCMfmt on, but our issues is
          before that
• Found this
        – http://red5.googlecode.com/svn/java/server/branches/

Dug this out of that paper

• 8+ bytes vers. 2 ES Descriptor box = long unsigned
  offset + long ASCII text string 'esds‗
• if encoded to ISO/IEC 14496-10 AVC standards then
  optionally use:
        = long unsigned offset + long ASCII text string 'm4ds‗
        4 bytes version/flags = 8-bit hex version + 24-bit hex flag
          (current = 0)
        -> 1 byte decoder specific descriptor type tag
                          = 8-bit hex value 0x05 (ours was 0x7A)

    Back Trace

(gdb) bt                                           #13 0x95c789d9 in
#0 0x9710a4a9 in malloc_error_break ()                 threegpp2moov_ProcessGenericAtomList ()
#1 0x97105497 in szone_error ()                    #14 0x95c78d8d in
#2 0x9702f523 in szone_free ()                         threegpp2moov_ProcessMediaInfoAtom ()
#3 0x9702f38d in free ()                           #15 0x95c785cf in
                                                       threegpp2moov_ProcessAtomContainer ()
#4 0x901ab755 in CSMemDisposePtr ()
                                                   #16 0x95c789d9 in
#5 0x901ab716 in CSMemDisposeHandle ()                 threegpp2moov_ProcessGenericAtomList ()
#6 0x901ab6c1 in DisposeHandle ()                  #17 0x95c78bdc in threegpp2moov_ProcessMediaAtom
#7 0x95c8319e in                                       ()
    QCelpUtilsMapMP4AudioEntryToSoundDescription #18 0x95c785cf in
    ()                                                 threegpp2moov_ProcessAtomContainer ()
#8 0x95c7ac0c in                                   #19 0x95c789d9 in
    threegpp2moov_ProcessSampleDescriptionsAtom ()     threegpp2moov_ProcessGenericAtomList ()
#9 0x95c785cf in                                   #20 0x95c78afa in threegpp2moov_ProcessTrackAtom
    threegpp2moov_ProcessAtomContainer ()              ()
#10 0x95c789d9 in                                  #21 0x95c785cf in
    threegpp2moov_ProcessGenericAtomList ()            threegpp2moov_ProcessAtomContainer ()
#11 0x95c78e1c in                                  #22 0x95c789d9 in
    threegpp2moov_ProcessSampleTableAtom ()            threegpp2moov_ProcessGenericAtomList ()
#12 0x95c785cf in
    threegpp2moov_ProcessAtomContainer ()

Tried to free Null Pointer

 0x9702f381 <free+94>: mov %esi,(%esp)
 0x9702f384 <free+97>: mov %eax,0x4(%esp)
 0x9702f388 <free+101>: call 0xa0a9d547
 0x9702f38d <free+106>: add $0x2c,%esp

 (gdb) i r
 eax             0x0   0

Example 4: Crash from a
• Exception Type: EXC_BAD_ACCESS (SIGSEGV)
• Exception Codes: KERN_INVALID_ADDRESS at
• Thread 0 Crashed:                   DEMO
• 0 ...ickTimeComponents.component
     0x927188cb marker_detect + 273
• 1 ...ickTimeComponents.component
     0x92721702 jpegpredecompress + 280
• 2 ...ickTimeComponents.component
     0x926e87da JPEG_DDrawBand + 1374

This part of the file format is
simpler get Meaning for

                 Movie Data Atom Type          ―mdat‖
                 JPEG Start Of Image
                                               FF D8
                 Motion-JPEG APP1 marker       FF E0

                 Marker Content Length         00 10
                 (Other markers, for example
                 JFIF )


• So why would changing the ―JPEG Start Of Image
  marker‖ from FF D8  FF F2 cause a crash?
• Pretty sure it‘s a heap issue since guard malloc
  catches it, but otherwise goes unnoticed
• If you‘ve ever put QuickTimeComponents into IDA …
  it‘s well, it‘s huge!
• But anyway it obviously has to do with
        – jpegpredecompress  marker_detect

Marker_Detect at a Glance

Used static and dynamic REing

• Using gdb, back up to a point above where the bad
  memory access occurs
        – Trace forward to the error and see what happens
          along the way
        – Interesting, we build a number out of the current
          (heap) memory pointer to the mdat record + 2 bytes
                 •   ptr -> ff f2 ff e0
                 •   newptr = ptr + ff e0
                 •   mov [newptr] -> esi
                 •   cmp [esi], ff
        – The crash happens when newptr points to invalid
          memory and we try to READ from it
                 • Doesn‘t regularly crash, commonly happens to point to
                   valid memory
Ideas toward popular heap
exploitation techniques

• Clobber function pointer on Heap with overwrite
• Get that function called

                 – Other Notes:
                   • File is 16k long, cannot write negative, so pointer would have
                     to be after file on heap ~50k range
                   • The big problem here is that the pointer we create doesn‘t
                     seem to be used to write to anything
                        • The pointer we supply is searched for the byte 0xff

Final Guesstimate

        0:000> !load winext\msec.dll
        0:000> !exploitable
        Exploitability Classification: UNKNOWN
        Recommended Bug Title: Read Access Violation starting
          at QuickTime!JPEG_DComponentDispatch+0x7573

• UPDATE: Fixed

Example 5: From a .mpg

• Exception Type: EXC_BAD_ACCESS (SIGSEGV)
• Exception Codes: KERN_INVALID_ADDRESS at
• Thread 10 Crashed:
        – 0 ...ple.QuickTimeMPEG.component 0x00660147
          ParseMpaLayer2IntensityStereo + 1921
        – 1 ...ple.QuickTimeMPEG.component 0x0065b352
          SetupThenDoMpaFrameDecode + 452
        – 2 ...ple.QuickTimeMPEG.component 0x006587c0
          AudioThreadEntry + 1751
        – 3 ...ple.QuickTimeMPEG.component 0x0063313a
          MacThreadFunc + 136
        – 4 libSystem.B.dylib         0x9085d095 _pthread_start
          + 321
        – 5 libSystem.B.dylib         0x9085cf52 thread_start +

Darn, no 4 byte string tags

 Tried some values other than ‗6A‘: AA, FF, 00, & 80.
 But only ‗6A‘ crashed. From another file that caused a crash I see ‘78‘ also works.
 It‘s not immediately obvious to me what‘s special about 6A and 78.

Another diff

           Repeating pattern: I see ‗FF FD 42 40 88 55 6D‘ a lot in the file.

           What is it?

 •      (gdb) i r
 •      eax        0x714a70e8         ecx     0x13        edx        0x295110ebx      0x45f9d7
 •      esp         0xb06203b0        ebp      0xb0620e78            esi      0x0       0edi
 •      eip        0x460147           <ParseMpaLayer2IntensityStereo+1921>
 •       (gdb) disass $eip-40 $eip+40
 •      Dump of assembler code from 0x46011f to 0x46016f: add %eax,(%eax)
        <ParseMpaLayer2IntensityStereo+1883>: add %bh,0x20(%ecx)
        <ParseMpaLayer2IntensityStereo+1889>: sub %esi,%ecx
        <ParseMpaLayer2IntensityStereo+1891>: mov -0x948(%ebp),%edx
        <ParseMpaLayer2IntensityStereo+1897>: shr %cl,%edx
        <ParseMpaLayer2IntensityStereo+1899>: mov %esi,%ecx
        <ParseMpaLayer2IntensityStereo+1901>: shll %cl,-0x948(%ebp)
        <ParseMpaLayer2IntensityStereo+1907>: lea (%edx,%edx,1),%eax
        <ParseMpaLayer2IntensityStereo+1910>: add %edx,%eax
        <ParseMpaLayer2IntensityStereo+1912>: mov -0x928(%ebp),%edx
        <ParseMpaLayer2IntensityStereo+1918>: lea (%edx,%eax,4),%eax
        <ParseMpaLayer2IntensityStereo+1921>: movss (%eax),%xmm2                    Read Issue
        <ParseMpaLayer2IntensityStereo+1925>: movss 0x4(%eax),%xmm1
        <ParseMpaLayer2IntensityStereo+1930>: movss 0x8(%eax),%xmm0
        <ParseMpaLayer2IntensityStereo+1935>: mulss %xmm3,%xmm2
        <ParseMpaLayer2IntensityStereo+1939>: mov -0xa50(%ebp),%edx
        <ParseMpaLayer2IntensityStereo+1945>: movss %xmm2,-0x4(%edx,%edi,1)
        <ParseMpaLayer2IntensityStereo+1951>: mulss %xmm3,%xmm1
        <ParseMpaLayer2IntensityStereo+1955>: mov -0xa54(%ebp),%ecx
 •      (gdb) x $edx
 •      0x295110:          0x0081000d
 •      (gdb) x $eax
 •      0x714a70e8:        Cannot access memory at address 0x714a70e8
Is it just me or are these bugs a

• Non trivial to track down
• In this case, we don‘t see a direct correlation
  between input value and resultant problem
        – Clear that a bad pointer is being constructed
        – Backing up in current thread doesn‘t reveal where this
          value comes from
                 • Must come from thread that started this thread

    Phun with Threads

•   Thread 0:
•   0 libSystem.B.dylib           0x9082c20e semaphore_wait_signal_trap + 10
•   1 libSystem.B.dylib           0x9085e206 _pthread_cond_wait + 1267
•   2 libSystem.B.dylib           0x908a3539 pthread_cond_wait + 48
•   3 ...ple.QuickTimeMPEG.component     0x00632e51 QTYieldToThread + 470
•   4 ...ple.QuickTimeMPEG.component     0x006437bb MPEGSystemIdle + 635
•   5 ...ple.QuickTimeMPEG.component     0x00645257 MPEGSystemDispatcher +
•   6 ...ple.CoreServices.CarbonCore     0x95027a95 CallComponentDispatch + 29


Repeating pattern

• Interestingly, if you scramble that byte in an earlier
  same-pattern, in the file it crashes but quicker
        – Conversely, if one of the later patterns is scrambled
          it‘s well in the movie before it crashes
        – Thus, I‘m lead to believe this pattern is a repeated
          section header of some type, obviously in the
        – Where can I get more info??

My New Favoritest Tool: 010

Another Bad (crashed with)


Kibbles and bits!

    • 01 1.              1   0       ..   So:
                                          68, 69, 6a, 6b
                     M                    78, 79, 7a, 7b
                 C   o                    Yes.
                 h   d
                 a   e           O    E   Others 7C …Yes.
                 n               r    m   Probably just bits
                 n   E           i    p   5 and 6. Yes.
                 e   x           g    h
                 l   t           i    a   So:
                     e           n    s   6x or 7x will cause
                 M   n           a    i   crash.
                 o   s           l    s   e.g.
                 d   i                    ChannelMode 1
                 e   o                    ModeExtension 2|3

   Conclusions from IDA pro

• Did some more reversing and
  two things lead me to want to
  let this one go
   – The exception happens on a
     ―read‖ not a ―write‖ operation
          • I don‘t see where a write
            happens soon after either
   – We can‘t directly/easily control
     the address at which we read
   – But more reversing is
     probably in order
   – not fixed
          • ―0day crash‖
Example 6: .avi

• 0 ???                       0x15512a4c 0 + 357640780
• 1 com.apple.CoreFoundation         0x90c58768 _CFRelease +
• 2 com.apple.CoreFoundation         0x90bef530
  __CFAllocatorDeallocate + 48
• 3 com.apple.CoreFoundation         0x90c58aea _CFRelease +
• 4 com.apple.CoreFoundation         0x90c1d436
  __CFDataDeallocate + 118
• 5 com.apple.CoreFoundation         0x90c58768 _CFRelease +
• 6 com.apple.AppKit                 0x966f73e0 -
  [NSBitmapImageRep _freeData] + 250
• 7 com.apple.AppKit                 0x966f72b1 -
  [NSBitmapImageRep _freeImage] + 39
• 8 com.apple.AppKit                 0x966f7261 -
  [NSBitmapImageRep dealloc] + 60


• This happen once before as well actually
• Try as I might I was unable to repeat the crash
        – Even by using GuardMalloc
        – And by replaying the whole sequence again
        – The issue didn‘t show back up … hrm….
                 • Oh well, not really sure what to make of that, could have
                   been some other unrelated system issues that made it

Example 7: A different .mov

    • Exception Type: EXC_BAD_ACCESS (SIGSEGV)
    • Exception Codes: KERN_INVALID_ADDRESS at
      0x00000000e276cc60         Always here
             – Thread 8 Crashed:
             – 0 ...ickTimeComponents.component 0x92ced553
               Decompress_c::DecodeChromaDC(int*) + 39
             – 1 ...ickTimeComponents.component 0x92ced7b4
               Decompress_c::DecodeChromaBlock(long, int, int) + 38
             – 2 ...ickTimeComponents.component 0x92cfb22d
               Decompress_c::DecodeInterFrame(int, int*) + 2311
             – 3 ...ickTimeComponents.component 0x92cf0eb1
               Decompress_c::DecompressFrame(unsigned char*, int,
               FrameBuffer_c*, DecompressParams_t*) + 1091

Hrm, again no obvious „text‟

                 Other bytes like 00, 11, 80, and FF caused the exception as well

                 And bummer, there‘s no .mov template freely available for 010

                 I suppose I‘ll need to figure out what that byte represents. 

We could get “arbitrary” value into eax

                                 If we control
                                 contents in
                                 eax or ebx

Strange to see NOPs in eax

gdb) i r
                                   Odd, and in my file as well
eax                 0x90909090
ecx                0x19a9cb48
edx                 0x9f5600     Interesting, looks like exec addr,
ebx                 0x92ced53a          since similar to EIP
esp                 0xb04cb900
ebp                 0xb04cb948
esi                0x9f5600
edi                0x1c727fff
eip                0x92ced553

mov              eax,DWORD PTR [ebx+eax*4+0xb90f4e6]
Has Potential

• No write, but we do control a pointer that gets
• If it writes to that pointer later we could be in
• So, well, go ahead you have homework now
        – Not fixed
        – ―0day‖ crash

Example 8: .avi file

• Breakpoint 1, 0x900e8c50 in ptrace ()QuickTime
  Player(39147,0xa004b720) malloc: ***
  mmap(size=1778397184) failed (error code=12)***
  error: can't allocate region*** set a breakpoint in
  malloc_error_break to debug

Blah, doesn‟t look good

•     (gdb) bt
•     #0 0x9018f4a9 in malloc_error_break ()
•     #1 0x9018a497 in szone_error ()
•     #2 0x900b78d6 in allocate_pages ()
•     #3 0x900b80c2 in large_and_huge_malloc ()
•     #4 0x900af228 in szone_malloc ()
•     #5 0x900af018 in malloc_zone_malloc ()
•     #6 0x900aefac in malloc ()
•     #7 0x91aec76e in v2m_allocateFakeCodecMemory ()
•     #8 0x91af0494 in loadTheChunk ()
•     #9 0x91af4bf3 in addNewSchedule ()
•     #10 0x91af5610 in LoadAFrame ()
•     #11 0x91afa76b in v2m_doWhatTheMentorTellsUs ()
•     #12 0x91afc375 in Video2MoviesTask ()
•     #13 0x95e7509f in CallComponentFunctionCommon ()
•     #14 0x91aeb505 in Video2ComponentDispatch ()

Example 9: 3rd .mov

Thread 8 Crashed:
0 QuickTimeH264.scalar        0x1562212e JVTCompEncodeFrame + 2662083
1 QuickTimeH264.scalar        0x156e967b JVTLibDecoDispose + 131805
2 QuickTimeH264.scalar        0x156a618c JVTCompEncodeFrame + 3202849
3 QuickTimeH264.scalar        0x156a40db JVTCompEncodeFrame + 3194480
4 QuickTimeH264.scalar        0x15671565 JVTCompEncodeFrame + 2986746
5 libSystem.B.dylib        0x9085d095 _pthread_start + 321
6 libSystem.B.dylib        0x9085cf52 thread_start + 34

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000044
[Switching to process 12516 thread 0x9b03]
0x1564312e in JVTCompEncodeFrame ()

Classic Null Ptr Exception

  (gdb) bt
  #0 0x1564312e in JVTCompEncodeFrame ()
  #1 0x1570a67b in JVTLibDecoDispose ()
  #2 0x156c718c in JVTCompEncodeFrame ()
  #3 0x156c50db in JVTCompEncodeFrame ()

  (gdb) disass $eip-40 $eip+16
  0x1564312e <JVTCompEncodeFrame+2662083>: mov   0x44(%edx),%edi

  (gdb) i r
  edx            0x0   0

Example 10: Mac Hackers

• Charlie is a big tease. He let on that if I could land
  the bug from his soon to be out book at the time, I
  could get my own pwn2own prize
        – Couldn‘t resist a quick look, but of course the
          CanSec/ZDI folks ruled that this bug couldn‘t win
                 • Lame since there was no exploit out for it
                   – The note in the book isn‘t even close to a working sploit
                 • Also, during my look at this bug I noticed another related
                   bug in similar area

The JPEG 2000 (.jp2) file

                 Used as a short len

Example10: Mac Hacker
• Verify with gmalloc that it dies at
        – mov          ecx, [ebp+var_B0]                Yah! An exploitable
                                                        write bug!!
        – mov          [ecx+0Eh], edx ; dies here

        – inside JP2DecoPreflight
        – Pg 133 of their book shows how use gmalloc
                 • In GDB:
                   – set env DYLD_INSERT_LIBRARY=/usr/lib/libgmalloc.dylib
                   – set env MALLOC_ALLOW_READS = 1

What‟s happening?

• byte swapping, endieness?
• runs off the end of the buffer in X cases
• heap fung shui
        –        spray ptrs on heap
        –        free every other one toward the end
        –        get our buff allocated in one of those holes
        –        clobber a func ptr
        –        trigger the ptr with member func before clean up
        –        but … the devil‘s always in the details
                 • FIXED NOW

The related bug

                  If size greater then
                  read beyond error


• I hope you now have a better appreciation for how
  the bug  sploit process could work
• As was shown, the process is non-exact and non-
  trivial for a host of reasons
        – but write crashes are the key!
• Next generation of fuzzers should include analysis
  such as provided by the !exploitable plug-in for
• Keep on fuzzing
        – It should be part of most every software development


To top