Exception or exploit?
Download
Report
Transcript Exception or exploit?
Hacking QuickTime:
Exception or Exploit?
Jared DeMott
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
them”
• 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 40%
– 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&from=r
ss
• 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 create
– 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 semiintelligent 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 exceptions?
8 Main Steps for Bit
Flipper Fuzzing
•
•
•
•
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)
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:
http://documents.iss.net/whitepapers/IBM_XForce_WP_final.pdf
• “The vulnerability in question is an exploitable NULLpointer dereference of …”
• So really, it’s tough to say “this isn’t
exploitable” if an exploit cannot be developed.
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.
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 AD/HD
• 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
example:
int main() {
int x = 42/0;
return 0; /* Never reached */
Why?
• 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
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
What exceptions are the most
interesting?
• 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
monitoring?
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,
Simple Reversing the File Format
Go and get http://developer.apple.com/DOCUMENTATION/QuickTime/QTFF/qtff.pdf
.mov
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 follows.
STSZ Data
• 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
hmmmm…
70707070 is the number that gets used as a bad malloc size
.gdbinit file to get QT in GDB
break ptrace
commands 1
return
continue
end
The BackTrace in GDB
Breakpoint 2, 0x91eec4a9 in malloc_error_break ()
(gdb) bt
#0 0x91eec4a9 in malloc_error_break ()
#1 0x91ee7497 in szone_error ()
#2 0x91e148d6 in allocate_pages ()
#3 0x91e150c2 in large_and_huge_malloc ()
#4 0x91e0c228 in szone_malloc ()
#5 0x91e0c018 in malloc_zone_malloc ()
#6 0x91e0bfac in malloc ()
#7 0x128b4621 in loadTheChunk ()
#8 0x128b8bf3 in addNewSchedule ()
#9 0x128b9610 in LoadAFrame ()
#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 ()
#18 0x12984770 in internalDoAction ()
#19 0x12975732 in _MCIdle ()
#20 0x1297097d in _MCComponentDispatch ()
#21 0x96060a95 in CallComponentDispatch ()
#22 0x00517db3 in MCIdle ()
#23 0x00516196 in QTOMovieObject::SendCommand ()
#24 0x004169ae in DispatchQTMsg ()
#25 0x004166d5 in
QTObjectTokenPriv::SendMessageToObject ()
#26 0x00415ca6 in QTObjectTokenPriv::DispatchMessage ()
#27 0x0051601a in QTSendToObject ()
…
Register Dump
gdb) up
#1 0x91ee7497 in szone_error ()
(gdb)
#2 0x91e148d6 in allocate_pages ()
(gdb)
#3 0x91e150c2 in large_and_huge_malloc ()
(gdb)
#4 0x91e0c228 in szone_malloc ()
(gdb)
#5 0x91e0c018 in malloc_zone_malloc ()
(gdb)
#6 0x91e0bfac in malloc ()
(gdb) i r
DEMO
edx
0x91e0b1c6
1847545402
ebx
0x91e0bfd5
1847541803
esp
0xbfffd8c0 0xbfffd8c0
ebp
0xbfffd8d80xbfffd8d8
esi
0x0 0
edi
0x70707084
1886417028
eip
0x91e0bfac0x91e0bfac
<malloc+55>
eflags
0x246
582
cs
0x1723
ss
0x1f 31
ds
0x1f 31
es
0x1f 31
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
esds
• 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 'esds'
• 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
Elementary Stream Descriptor
• Trouble finding a solid file format
• ‘QLCMfmt’ and ‘Qcelp 13K’ turn up
– http://www.potaroo.net/ietf/idref/draftgarudadri-qcp/
– Explains bytes from QLCMfmt on, but our issues is
before that
• Found this
– http://red5.googlecode.com/svn/java/server/bran
ches/paulg_mp4/refs/mp4-layout.txt
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
Back Trace
(gdb) bt
#0 0x9710a4a9 in malloc_error_break ()
#1 0x97105497 in szone_error ()
#2 0x9702f523 in szone_free ()
#3 0x9702f38d in free ()
#4 0x901ab755 in CSMemDisposePtr ()
#5 0x901ab716 in CSMemDisposeHandle ()
#6 0x901ab6c1 in DisposeHandle ()
#7 0x95c8319e in
QCelpUtilsMapMP4AudioEntryToSoundDescription ()
#8 0x95c7ac0c in
threegpp2moov_ProcessSampleDescriptionsAtom ()
#9 0x95c785cf in threegpp2moov_ProcessAtomContainer ()
#10 0x95c789d9 in threegpp2moov_ProcessGenericAtomList
()
#11 0x95c78e1c in
threegpp2moov_ProcessSampleTableAtom ()
#12 0x95c785cf in threegpp2moov_ProcessAtomContainer ()
#13 0x95c789d9 in threegpp2moov_ProcessGenericAtomList
()
#14 0x95c78d8d in threegpp2moov_ProcessMediaInfoAtom
()
#15 0x95c785cf in threegpp2moov_ProcessAtomContainer ()
#16 0x95c789d9 in threegpp2moov_ProcessGenericAtomList
()
#17 0x95c78bdc in threegpp2moov_ProcessMediaAtom ()
#18 0x95c785cf in threegpp2moov_ProcessAtomContainer ()
#19 0x95c789d9 in threegpp2moov_ProcessGenericAtomList
()
#20 0x95c78afa in threegpp2moov_ProcessTrackAtom ()
#21 0x95c785cf in threegpp2moov_ProcessAtomContainer ()
#22 0x95c789d9 in threegpp2moov_ProcessGenericAtomList
()
Tried to free Null Pointer
0x9702f381 <free+94>:
mov %esi,(%esp)
0x9702f384 <free+97>:
mov
%eax,0x4(%esp)
0x9702f388 <free+101>: call 0xa0a9d547
<dyld_stub_malloc_zone_free>
0x9702f38d <free+106>: add $0x2c,%esp
(gdb) i r
eax
0x0
0
Example 4: Crash from a .mov
• Exception Type: EXC_BAD_ACCESS (SIGSEGV)
• Exception Codes: KERN_INVALID_ADDRESS at
0x00000000003da000
• Thread 0 Crashed:
DEMO
• 0 ...ickTimeComponents.component
0x927188cb marker_detect + 273
• 1 ...ickTimeComponents.component
0x92721702 jpegpredecompress + 280
• 2 ...ickTimeComponents.component
This part of the file format is
simpler get Meaning for
Movie Data Atom Type
“mdat”
JPEG Start Of Image marker
FF D8
Motion-JPEG APP1 marker
FF E0
Marker Content Length
00 10
(Other markers, for example
JFIF )
“JFIF”
Hrm…
• 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
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
(Hash=0x14012070.0x1849147b)
• UPDATE: Fixed
Example 5: From a .mpg
• Exception Type: EXC_BAD_ACCESS (SIGSEGV)
• Exception Codes: KERN_INVALID_ADDRESS at
0x000000007520741e
• 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
Darn, no 4 byte string tags nearby
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
(gdb) i r
eax
0x714a70e8 ecx
0x13
edx
0x295110ebx
0x45f9d7
esp
0xb06203b0 ebp
0xb0620e78
esi
0x0
0edi
0x28
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) Read Issue
<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
<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
Is it just me or are these bugs a pain?
• 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
+ 733
• 6 ...ple.CoreServices.CarbonCore
0x95027a95 CallComponentDispatch
+ 29
Hrm,
couldn’t
find value
there
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
“ParseMpaLayer2IntensityStereo”
– Where can I get more info??
My New Favoritest Tool: 010
Another Bad (crashed with)
Good
Kibbles and bits!
• 01 1.
C
h
a
n
n
e
l
M
o
d
e
M
o
d
e
E
x
t
e
n
s
i
o
n
1 0
C
o
p
y
r
i
g
h
t
O
r
i
g
i
n
a
l
..
E
m
p
h
a
s
i
s
So:
68, 69, 6a, 6b
78, 79, 7a, 7b
Yes.
Others 7C …Yes.
Probably just bits 5
and 6. Yes.
So:
6x or 7x will cause
crash.
e.g.
ChannelMode 1
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
Example 6: .avi
• 0 ???
0x15512a4c 0 + 357640780
• 1 com.apple.CoreFoundation
0x90c58768
_CFRelease + 216
• 2 com.apple.CoreFoundation
0x90bef530
__CFAllocatorDeallocate + 48
• 3 com.apple.CoreFoundation
0x90c58aea
_CFRelease + 1114
• 4 com.apple.CoreFoundation
0x90c1d436
__CFDataDeallocate + 118
• 5 com.apple.CoreFoundation
0x90c58768
_CFRelease + 216
• 6 com.apple.AppKit
0x966f73e0 [NSBitmapImageRep _freeData] + 250
• 7 com.apple.AppKit
0x966f72b1 [NSBitmapImageRep _freeImage] + 39
Unrepeatable
• 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 crash??
Example 7: A different .mov file
• Exception Type: EXC_BAD_ACCESS (SIGSEGV)
• Exception Codes: KERN_INVALID_ADDRESS at
Always here
0x00000000e276cc60
– 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’
nearby
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
Odd, and in my file as well
gdb) i r
eax
0x90909090
ecx
0x19a9cb48
edx
0x9f5600
ebx
0x92ced53a
esp
0xb04cb900
ebp
0xb04cb948
esi
0x9f5600
edi
0x1c727fff
eip
0x92ced553
Interesting, looks like exec addr, since
similar to EIP
Has Potential
• No write, but we do control a pointer that gets
constructed
• If it writes to that pointer later we could be in
business
• 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 ()
Example 9: 3rd .mov
Thread 8 Crashed:
0 QuickTimeH264.scalar
1 QuickTimeH264.scalar
2 QuickTimeH264.scalar
3 QuickTimeH264.scalar
4 QuickTimeH264.scalar
5 libSystem.B.dylib
6 libSystem.B.dylib
0x1562212e JVTCompEncodeFrame + 2662083
0x156e967b JVTLibDecoDispose + 131805
0x156a618c JVTCompEncodeFrame + 3202849
0x156a40db JVTCompEncodeFrame + 3194480
0x15671565 JVTCompEncodeFrame + 2986746
0x9085d095 _pthread_start + 321
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>:
(gdb) i r
edx
0x0
0
mov 0x44(%edx),%edi
Example 10: Mac Hackers Handbook
• 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 Book
An exploitable
• Verify with gmalloc that it dies at Yah!
write bug!!
– mov
– mov
ecx, [ebp+var_B0]
[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
filesize,
read beyond error
Conclusion
• 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 windbg
• Keep on fuzzing
– It should be part of most every software
development project