iPhone: Fuzzing and iPhone: Fuzzing and Payloads Payloads Charlie Miller Charlie Miller Independent Security Evaluators Independent Security Evaluators [email protected][email protected]Follow me on twitter: 0xcharlie Follow me on twitter: 0xcharlie
iPhone: Fuzzing and Payloads. Charlie Miller Independent Security Evaluators [email protected] Follow me on twitter: 0xcharlie. Who am I?. Principal Analyst, Independent Security Evaluators First to hack the iPhone, G1 Android Phone - PowerPoint PPT Presentation
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
iPhone: Fuzzing and iPhone: Fuzzing and PayloadsPayloadsCharlie MillerCharlie MillerIndependent Security EvaluatorsIndependent Security Evaluators
History of iPhone History of iPhone researchresearch
iPhone 1.0 - June 2007iPhone 1.0 - June 2007
Everything ran as rootEverything ran as root
No sandboxingNo sandboxing
No ASLR/DEPNo ASLR/DEP
No code signingNo code signing
Hacked within a couple of weeksHacked within a couple of weeks
At least 3 public remote code exploitsAt least 3 public remote code exploits
iPhone 2.0iPhone 2.0
Released July 2008Released July 2008
Includes App Store, SDKIncludes App Store, SDK
App sandboxingApp sandboxing
DEP but no ASLRDEP but no ASLR
Code signingCode signing
Most apps run as user mobileMost apps run as user mobile
Major upgrade of security!Major upgrade of security!
Can circumvent DEPCan circumvent DEP
Most significantlyMost significantly
No public, remote code exploit for iPhone 2.0 or No public, remote code exploit for iPhone 2.0 or laterlater
Even survived Pwn2OwnEven survived Pwn2Own
iPhone 3.0iPhone 3.0
Added MMSAdded MMS
Fixed DEP circumvention (more on this later)Fixed DEP circumvention (more on this later)
Still no ASLRStill no ASLR
Device is way more secure than typical Snow Device is way more secure than typical Snow Leopard computerLeopard computer
SMSSMS
SMSSMS
Uses extra bandwidth in control channel (used for Uses extra bandwidth in control channel (used for establishing calls, status, etc)establishing calls, status, etc)
Message data limited to 140 bytes (160 7-bit characters)Message data limited to 140 bytes (160 7-bit characters)
Commonly used for for “text messages”Commonly used for for “text messages”
Can also deliver binary dataCan also deliver binary data
OTA programmingOTA programming
ringtones ringtones
Building block for essential services on the mobile phoneBuilding block for essential services on the mobile phone
Why pick on SMS? Why pick on SMS?
SMS is received by and processed by almost all phonesSMS is received by and processed by almost all phones
No way to firewall it (and still receive calls/texts)No way to firewall it (and still receive calls/texts)
SMS is processed with no user interactionSMS is processed with no user interaction
Server side attack surface with no firewall, I’m having Server side attack surface with no firewall, I’m having a 1990’s flashback!a 1990’s flashback!
Can be targeted with only a phone numberCan be targeted with only a phone number
SMS firewalls/filter exist on network but those on the SMS firewalls/filter exist on network but those on the phones are too high in the stack to protect against phones are too high in the stack to protect against these attacksthese attacks
On the deviceOn the device
Phone has 2 processors, application processor and Phone has 2 processors, application processor and modemmodem
Modem runs a specialized real time operating system Modem runs a specialized real time operating system that handles all communication with cellular network that handles all communication with cellular network
Communication between CPUs is via logical serial linesCommunication between CPUs is via logical serial lines
Text based GSM AT command set usedText based GSM AT command set used
Continued life of SMSContinued life of SMS
When an SMS arrives at the modem, the modem When an SMS arrives at the modem, the modem uses an unsolicited AT command result codeuses an unsolicited AT command result code
This consists of 2 lines of textThis consists of 2 lines of text
The result code and the number of bytes of the The result code and the number of bytes of the next linenext line
The actual SMS message (in PDU mode)The actual SMS message (in PDU mode)
A PDUA PDU0707919194710600403494710600403404040D0D9191947196466656F8947196466656F80000000090108211421540901082114215400A0AE8329BFD4697D9EC377DE8329BFD4697D9EC377D
The previous PDU was the simplest message The previous PDU was the simplest message possible, 7-bit immediate alert (i.e. a text possible, 7-bit immediate alert (i.e. a text message)message)
Can also send binary data in the UD fieldCan also send binary data in the UD field
This is prefaced with the User Data Header (UDH)This is prefaced with the User Data Header (UDH)
UDH exampleUDH example
050500000303000301000301
FieldField SizeSize BytesBytes
UDHLUDHL 1 byte1 byte 0505
IEIIEI 1 byte1 byte 0000
IEDLIEDL 1 byte1 byte 0303
IEDIED VariableVariable 000301000301
UDH example 1UDH example 1
Concatenated messagesConcatenated messages
Can send more than 160 bytesCan send more than 160 bytes
IEI = 00 -> concatenated with 8 bit reference IEI = 00 -> concatenated with 8 bit reference numbernumber
IEDL = 03 -> 3 bytes of dataIEDL = 03 -> 3 bytes of data
Reference number = 00Reference number = 00
Total number of messages = 03Total number of messages = 03
This message number = 01This message number = 01
050500000303000003030101
Other common UDH IEI’sOther common UDH IEI’s
IEI 01 = voice mail availableIEI 01 = voice mail available
IEI 05 = port numbers (application can register)IEI 05 = port numbers (application can register)
Port 5499 = visual voicemailPort 5499 = visual voicemail
A fuzzing framework implemented in Python by A fuzzing framework implemented in Python by Pedram Amini and Aaron PortnoyPedram Amini and Aaron Portnoy
Provides test case generation, test case sending, Provides test case generation, test case sending, target monitoring, post mortem analysistarget monitoring, post mortem analysis
We only use it for test case generationWe only use it for test case generation
Block based approach to dig deep into the protocolBlock based approach to dig deep into the protocol
Contains library of effective fuzzing strings and Contains library of effective fuzzing strings and integersintegers
Super SPIKE or underdeveloped PEACHSuper SPIKE or underdeveloped PEACH
if s_block_start("eight_bit", dep="tp_dcs", dep_values=["04"]): if s_block_start("eight_bit", dep="tp_dcs", dep_values=["04"]): s_size("message_eight", format="oct", length=1, math=lambda x: x / 2) if s_size("message_eight", format="oct", length=1, math=lambda x: x / 2) if s_block_start("message_eight"): s_size("udh_eight", format="oct", length=1, s_block_start("message_eight"): s_size("udh_eight", format="oct", length=1, math=lambda x: x / 2) if s_block_start("udh_eight"): math=lambda x: x / 2) if s_block_start("udh_eight"): s_byte(0x00, format="oct", fuzzable=True) s_size("ied_eight", s_byte(0x00, format="oct", fuzzable=True) s_size("ied_eight", format="oct", length=1, math=lambda x: x / 2) if format="oct", length=1, math=lambda x: x / 2) if s_block_start("ied_eight", encoder=eight_bit_encoder): s_block_start("ied_eight", encoder=eight_bit_encoder): s_string("\x00\x03\x01", max_len = 256) s_block_end() s_string("\x00\x03\x01", max_len = 256) s_block_end() s_block_end() if s_block_start("text_eight", encoder=eight_bit_encoder): s_block_end() if s_block_start("text_eight", encoder=eight_bit_encoder): s_string(" Test12345BlaBlubber231...Collin", max_len = 256) s_string(" Test12345BlaBlubber231...Collin", max_len = 256) s_block_end() s_block_end()s_block_end() s_block_end() s_block_end()s_block_end()
FieldField SizeSize BytesBytes
UDHLUDHL 1 byte1 byte 0505
IEIIEI 1 byte1 byte 0000
IEDLIEDL 1 byte1 byte 0303
IEDIED VariableVariable 000301000301
SMS injectionSMS injection
Sending the test casesSending the test cases
Could send over the airCould send over the air
Costs $$$$Costs $$$$
Telco’s get to watch you fuzzTelco’s get to watch you fuzz
You might (make that WILL) crash Telco’s equipmentYou might (make that WILL) crash Telco’s equipment
Could build your own transmitterCould build your own transmitter
That sounds hard!That sounds hard!
Could inject into the process which parsesCould inject into the process which parses
Would be very device/firmware dependentWould be very device/firmware dependent
SMS injectionSMS injectionWe MITM the channel between the application processor and the We MITM the channel between the application processor and the modemmodem
Can send messages quicklyCan send messages quickly
Its freeIts free
Requires no special equipmentRequires no special equipment
The receiving process doesn’t know the messages weren’t legitThe receiving process doesn’t know the messages weren’t legit
Telco (mostly) doesn’t know its happeningTelco (mostly) doesn’t know its happening
Warning: results need to be verified over the carrier networkWarning: results need to be verified over the carrier network
Man in the MiddleMan in the Middle
Use Library Pre-loading to hook basic APIUse Library Pre-loading to hook basic API
““Listen, and understand. That exploit is out Listen, and understand. That exploit is out there. It can't be bargained with. It can't be there. It can't be bargained with. It can't be
reasoned with. It doesn't feel pity, or reasoned with. It doesn't feel pity, or remorse, or fear. And it absolutely will not remorse, or fear. And it absolutely will not
stop, ever, until you are pwned”... Kyle Reesestop, ever, until you are pwned”... Kyle ReeseThe TerminatorThe Terminator040003X
XXX
040003XXXX
Let’s take a closer lookLet’s take a closer look
The issueThe issue
Read_next_byte returns the next (decoded) Read_next_byte returns the next (decoded) byte or -1 if there is no more databyte or -1 if there is no more data
Since enough data is not explicitly checked, Since enough data is not explicitly checked, you can arrange to have you can arrange to have
This message number be -1This message number be -1
Total message and This message to be -1Total message and This message to be -1
An array of C++ strings is allocated, of size Total numberAn array of C++ strings is allocated, of size Total number
When a new concatenated msg arrives, it indexes into When a new concatenated msg arrives, it indexes into this array by (This number - 1) this array by (This number - 1)
Explicitly checks its not too big or 0Explicitly checks its not too big or 0
If This number is -1, it underflows the arrayIf This number is -1, it underflows the array
It compares this string to a NULL stringIt compares this string to a NULL string
If it is not equal, we know we already received a If it is not equal, we know we already received a message with This number, so ignore this msgmessage with This number, so ignore this msg
If not assign the data from the msg to the string in the If not assign the data from the msg to the string in the arrayarray
CompareCompare
Comparing Null StringComparing Null String
The only way to pass this test is to have a The only way to pass this test is to have a “length” of 0“length” of 0
This length is stored in the first dword of the This length is stored in the first dword of the bufferbuffer
(at location -0xc from the pointer)(at location -0xc from the pointer)
To pass the test, need 00000000 at ptr - 0xcTo pass the test, need 00000000 at ptr - 0xc
AssignAssign
AssignAssign
Replaces old string data with new string dataReplaces old string data with new string data
Step 1: control the dword (pointer) before the array of Step 1: control the dword (pointer) before the array of strings (actually we want array[-2])strings (actually we want array[-2])
Step 2: Point it at memory that begins with 00000000Step 2: Point it at memory that begins with 00000000
Then we can decrement the dword at pointer+8Then we can decrement the dword at pointer+8
We can free(pointer)We can free(pointer)
Either of these two things are enough for exploitationEither of these two things are enough for exploitation
But can you manipulate the heap with only SMS???But can you manipulate the heap with only SMS???
Again with the Again with the concatenated messagesconcatenated messages
Each time a new reference number appears, an array of strings Each time a new reference number appears, an array of strings is allocated (size Total * 4)is allocated (size Total * 4)
Each time a new message for that ref number appears, a Each time a new message for that ref number appears, a string is allocated to store the datastring is allocated to store the data
Buffer of size 0x2d, 0x4d, 0x8d, 0x10dBuffer of size 0x2d, 0x4d, 0x8d, 0x10d
When the concatenated message is completeWhen the concatenated message is complete
These pointers are all freed when all the messages have These pointers are all freed when all the messages have arrived (but not before)arrived (but not before)
All strings are appended into one big stringAll strings are appended into one big string
Which is then free’d shortly thereafterWhich is then free’d shortly thereafter
Our heap weaponsOur heap weapons
Can allocate data in buffers up to size 144 Can allocate data in buffers up to size 144 (data of SMS message)(data of SMS message)
Can control when (or if) these guys are free’dCan control when (or if) these guys are free’d
Can allocate different sized buffers of pointers Can allocate different sized buffers of pointers to C++ strings (up to size 1024 bytes)to C++ strings (up to size 1024 bytes)
Can control when (or if) these guys are free’dCan control when (or if) these guys are free’d
Can create long strings of data up to size 36k, Can create long strings of data up to size 36k, free’d immediatelyfree’d immediately
That’s it! But that’s enoughThat’s it! But that’s enough
2 others not applicable to SMS...2 others not applicable to SMS...
Each region maintains a list of free’d pointersEach region maintains a list of free’d pointers
Malloc tries to return the first free’d pointer that is big Malloc tries to return the first free’d pointer that is big enough to hold the new bufferenough to hold the new buffer
If that buffer is bigger than needed, the rest is put on the If that buffer is bigger than needed, the rest is put on the free’d list again in a smaller slotfree’d list again in a smaller slot
Heap spray, 140 bytes at a Heap spray, 140 bytes at a timetime
Send a bunch of SMS’s with different This numbers for Send a bunch of SMS’s with different This numbers for large Total number and different reference numberslarge Total number and different reference numbers
You can get 140 = 0x8c bytes allocated which contain You can get 140 = 0x8c bytes allocated which contain arbitrary binary data (in a 0x90 byte buffer)arbitrary binary data (in a 0x90 byte buffer)
No indication on the phone these messages are No indication on the phone these messages are arriving since they are never complete!arriving since they are never complete!
Can do stuff like mini-heap feng shei if you alternate Can do stuff like mini-heap feng shei if you alternate sending in messages with two different reference sending in messages with two different reference numbersnumbers
Ref1, This 1Ref1, This 1
Ref2, This 1Ref2, This 1
Ref1, This 2Ref1, This 2
......
Then “complete” one of them to get the buffers free’dThen “complete” one of them to get the buffers free’d
This gives you “holes” in the heapThis gives you “holes” in the heap
Gotta be something with a zero dword before itGotta be something with a zero dword before it
Must be at a consistent, guessable, addressMust be at a consistent, guessable, address
Decrementing it should help usDecrementing it should help us
Pointer in the free’d list!Pointer in the free’d list!
If we decrement it so it points to our data then If we decrement it so it points to our data then when it gets re-used for a malloc an unlinking when it gets re-used for a malloc an unlinking will occurwill occur
This gives us a write-4 primitiveThis gives us a write-4 primitive
The dreamThe dreamOur data is right before an array of C++ strings which we can Our data is right before an array of C++ strings which we can underflow (so it reads our user controlled pointer)underflow (so it reads our user controlled pointer)
We have data before a pointer in the free’d listWe have data before a pointer in the free’d list
(and this pointer stays at the beginning of the free list when (and this pointer stays at the beginning of the free list when we do all this stuff)we do all this stuff)
We decrement the pointer so the free’d list pointer points to We decrement the pointer so the free’d list pointer points to our dataour data
We cause an allocation to occur which uses this free’d pointerWe cause an allocation to occur which uses this free’d pointer
This buffer is unlinked from the free list which gives us a write-This buffer is unlinked from the free list which gives us a write-4 (we control metadata)4 (we control metadata)
We write-4 to the global offset tableWe write-4 to the global offset table
Get that function pointer calledGet that function pointer called
ExploitExploit
Msg 1: Allocate 2/3 of small concatenated message (so it will end Msg 1: Allocate 2/3 of small concatenated message (so it will end up in tiny region)up in tiny region)
Msg 2, 3: Allocate n/(n+1) of a concat msg for some nMsg 2, 3: Allocate n/(n+1) of a concat msg for some n
Msg 3: Allocate n/n of a concat msgMsg 3: Allocate n/n of a concat msg
Gives holes in memory Gives holes in memory andand clears out free list clears out free list
Send last bit of Msg1 to put it on the free list (with lots of other Send last bit of Msg1 to put it on the free list (with lots of other smaller guys on the free list ready to get used) smaller guys on the free list ready to get used)
This is the guy we want to decrementThis is the guy we want to decrement
Create 16 new messages with This msg = -1Create 16 new messages with This msg = -1
Each does 1 decrement to the free list pointerEach does 1 decrement to the free list pointer
Send in array request of size 0x7bSend in array request of size 0x7b
Our dataOur dataFor demo of write-4:For demo of write-4:
Did I mention this requires no user-Did I mention this requires no user-interaction, and it runs as unsandboxed interaction, and it runs as unsandboxed
root?root?
In allIn all
519 SMS’s (@ 1/sec)519 SMS’s (@ 1/sec)
Only one shows up to userOnly one shows up to user
Can cause CommCenter to restart at will (for Can cause CommCenter to restart at will (for clean slate)clean slate)
Keep trying - you can throw the exploit as Keep trying - you can throw the exploit as many times as you like, there’s nothing the many times as you like, there’s nothing the victim can do to stop you!victim can do to stop you!
iPhone MeterpreteriPhone Meterpreter
iPhone 2.0 memory funiPhone 2.0 memory fun
Security architecture: No writeable page may Security architecture: No writeable page may become executablebecome executable
How do debuggers work?!?!How do debuggers work?!?!
Can make existing library writable (using Can make existing library writable (using VM_PROT_COPY flag), overwrite code, make it VM_PROT_COPY flag), overwrite code, make it executable againexecutable again
Can do this using return oriented programming Can do this using return oriented programming payload (remember there is no ASLR)payload (remember there is no ASLR)
So what?So what?
App store code may “update” itselfApp store code may “update” itself
Generic shellcode can be runGeneric shellcode can be run
dyld can be modifieddyld can be modified
dyld makes sure only signed libraries are dyld makes sure only signed libraries are loaded, so...loaded, so...
Can load unsigned librariesCan load unsigned libraries
MeterpreterMeterpreter
Originally an advanced Metasploit payload for Originally an advanced Metasploit payload for WindowsWindows
Better than a shellBetter than a shell
Upload, download, and edit files on the flyUpload, download, and edit files on the fly
Redirect traffic to other hosts (pivoting)Redirect traffic to other hosts (pivoting)
On iPhone, provides a shell on a system without On iPhone, provides a shell on a system without /bin/sh!/bin/sh!
Not a Development phoneNot a Development phoneUsing Ad-Hoc distribution on provisioned phoneUsing Ad-Hoc distribution on provisioned phone
iPhone version 3iPhone version 3
They fixed this bugThey fixed this bug
Debugging only works on Development phones (or Debugging only works on Development phones (or processes with special ‘provisions’)processes with special ‘provisions’)
Open question whether generic shellcode can be Open question whether generic shellcode can be run on iPhone 3run on iPhone 3
No ASLR means that return oriented programming No ASLR means that return oriented programming is still possible on iPhone 3.0is still possible on iPhone 3.0
ConclusionsConclusions
SMS bugs are very badSMS bugs are very bad
Heap manipulation over SMS is hard but possibleHeap manipulation over SMS is hard but possible
SMS fuzzing can be done over a local networkSMS fuzzing can be done over a local network
Against 2.2.1 you could get a root owned Against 2.2.1 you could get a root owned Meterpreter shell via SMSMeterpreter shell via SMS
iPhone continues to get more secure but still lacks iPhone continues to get more secure but still lacks ASLRASLR
Questions?Questions?
Contact me at Contact me at [email protected]@securityevaluators.com