SyScanTaipei2011 StefanEsser iOS Kernel Exploitation IOKit Edition
SyScanTaipei2011 StefanEsser iOS Kernel Exploitation IOKit Edition
SyScanTaipei2011 StefanEsser iOS Kernel Exploitation IOKit Edition
de
•Stefan Esser
•from Cologne / Germany
•in information security since 1998
•PHP core developer since 2001
•Month of PHP Bugs and Suhosin
•recently focused on iPhone security (ASLR, jailbreak)
•founder of SektionEins GmbH
•currently also working as independent contractor
• Introduction
• Kernel Debugging
• Auditing IOKit Drivers
• Kernel Exploitation
• Stack Buffer Overflows
• Heap Buffer Overflows
• Kernel patches from Jailbreaks
OS X iOS
user-land dereference bugs are not user-land dereference bugs are partially
exploitable exploitable
kernel exploits only trigger-able as root kernel exploits only trigger-able as root
are not interesting interesting for untethering exploits
• untethering exploits
• kernel exploit as “root“ user during boot sequence
• patch kernel to disable all security features in order to jailbreak
• from iOS 4.3.0 also needs to be implemented in 100% ROP
PIN Desc
1,2 GND
3 Line Out - R+
4 Line Out - L+
5 Line In - R+
8
Line In - L+
Video Out
• iPhone Dock Connector has PINs for
- Line Out / In
9 S-Video CHR Output
11 GND
- Video Out
12 Serial TxD
13 Serial RxD
14 NC
15,16
17
GND
NC - USB
18 3.3V Power
19,20
12V Firewire Power
- FireWire
21 Accessory Indicator/Serial Enable
- Serial
22 FireWire Data TPA-
25 USB Data -
27 USB Data +
29,30 GND
470kΩ resistor
Breakout Board
FT232RL USB to Serial
PodGizmo Connector
• 470 kΩ resistor
• used to bridge pin 1 and 21
• activates the UART
• costs a few cents
• PodBreakout
• easy access to dock connector
pins
• some revisions have reversed
pins
• even I was able to solder this
• about 12 EUR
• USB cables
• type A -> mini type B
• provides us with wires and
connectors
• costs a few EUR
... ... Other values might work but might be complicated to use.
R1 = Object Name
R2 = Parent‘s MetaClass
R3 = Methods of MetaClass
• AppleBasebandUserClient::clientClose(void)
• Credits: pod2g
• triggers when a HFS image with overlong volume name is mounted
• stack based buffer overflow in a character conversion routine
• requires root permissions
• used to untether iOS 4.2.1 - 4.2.8
memset(&vn, 0, sizeof(vn));
ioctl(fd, VNIOCDETACH, &vn);
vn.vn_file = "/usr/lib/exploit.hfs";
vn.vn_control = vncontrol_readwrite_io_e;
ret = ioctl(fd, VNIOCATTACH, &vn);
close(fd);
if (ret < 0) {
puts("Can't attach vn0.");
exit(1);
}
memset(&args, 0, sizeof(args));
args.fspec = "/dev/vn0";
args.hfs_uid = args.hfs_gid = 99;
args.hfs_mask = 0x1c5;
ret = mount("hfs", "/mnt/", MNT_RDONLY, &args);
int
hfs_to_utf8(ExtendedVCB *vcb, const Str31 hfs_str, ...)
{
int error;
UniChar uniStr[MAX_HFS_UNICODE_CHARS];
ItemCount uniCount;
size_t utf8len;
hfs_to_unicode_func_t hfs_get_unicode = VCBTOHFS(vcb)->hfs_get_unicode;
error = hfs_get_unicode(hfs_str, uniStr, MAX_HFS_UNICODE_CHARS, &uniCount);
if (uniCount == 0)
error = EINVAL;
if (error == 0) {
error = utf8_encodestr(uniStr, uniCount * sizeof(UniChar), dstStr, &utf8len, maxDstLen , ':', 0);
...
Text
call to
mac_roman_to_unicode()
should be 0
to exit function
uniCount R4 R5 R6 R7 PC
THUMB mode
xxx r7
xxx r4
xxx r7
80067C60 copyin
400 length
src in
20000000 user space
• kernel level ROP very attractive because limited amount of different iOS kernel versions
this is iOS not Mac OS X => we can return to user space memory
if (error == 0)
{
/* At this point, we've at least got enough bytes to start looking around */
u_int32_t demuxOn = 0;
because of
proto_param.demux_count = ndrvSpec.demux_count; high demux_count
proto_param.input = ndrv_input; this loop loops
very often
proto_param.event = ndrv_event;
ifdemux->type = ndrv->type;
ifdemux->data = ndrv->data.other;
limited in what
ifdemux->datalen = ndrv->length;
can be written
• a zone consists of a number of /* boolean_t */ exhaustible :1, /* (F) merely return if empty? */
/* boolean_t */ collectable :1, /* (F) garbage collect empty pages */
memory pages /* boolean_t */ expandable :1, /* (T) expand zone (with message)? */
/* boolean_t */ allows_foreign :1,/* (F) allow non-zalloc space */
/* boolean_t */ doing_alloc :1, /* is zone expanding now? */
• each allocated block inside a /* boolean_t */ waiting :1, /* is thread waiting for expansion? */
zone is of the same size /* boolean_t */ async_pending :1, /* asynchronous allocation pending? */
/* boolean_t */ doing_gc :1, /* garbage collect in progress? */
/* boolean_t */ noencrypt :1;
• free elements are stored in struct zone * next_zone; /* Link for all-zones list */
call_entry_data_t call_async_alloc; /* callout for asynchronous alloc */
a linked list const char *zone_name; /* a name for the zone */
#if ZONE_DEBUG
queue_head_t active_zones; /* active elements */
#endif /* ZONE_DEBUG */
};
head of freelist
0
head of freelist
0
head of freelist
0
head of freelist
1
head of freelist
2
head of freelist
3
head of freelist
4
head of freelist
5
5
• it is split into the zone‘s element size 3
head of freelist
6
5
• it is split into the zone‘s element size 4
6
1 2
head of freelist
7
5
• it is split into the zone‘s element size 5
6
4
• elements in freelist are in reverse order
1 2 3
head of freelist
7
2
6
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 5
to the freelist 6
1 2 3
head of freelist
6
2
5
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 4
to the freelist 6
1 2
head of freelist
5
2
4
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 3
to the freelist 6
head of freelist
4
2
3
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 2
to the freelist 6
head of freelist
3
2
2
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 1
to the freelist 6
head of freelist
5
2
3
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 2
to the freelist 6
head of freelist
7
2
5
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 3
to the freelist 6
head of freelist
6
2
7
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 5
to the freelist 6
1 2
head of freelist
4
2
6
• when memory blocks are allocated they 3
are removed from the freelist 4
5
• when they are freed they are returned 7
to the freelist 6
1 2 3
i++) \
((uint32_t *)(element))[i] = 0xdeadbeef; \
current head of freelist
} \ is written to start of free block
*((vm_offset_t *)(element)) = (zone)->free_elements; \
if (check_freed_element) { \
if ((zone)->elem_size >= (2 * sizeof(vm_offset_t))) \
((vm_offset_t *)(element))[((zone)->elem_size/sizeof(vm_offset_t))-1] = \
(zone)->free_elements; \
free block is made
} \ the head of the freelist
(zone)->free_elements = (vm_offset_t) (element); \
(zone)->count--; \
MACRO_END
grey code is only activated by debugging boot-args
Apple seems to think about activating it by default
Sotirov ...
https://github.com/comex/datautils0/blob/master/make_kernel_patchfile.c
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 100
Restrictions and Code Signing
• proc_enforce
• sysctl variable controlling different process management enforcements
• disabled allows debugging and execution of wrongly signed binaries
• nowadays write protected from “root“
• cs_enforcement_disable
• boot-arg that disables codesigning enforcement
• enabled allows to get around codesigning
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 101
PE_i_can_has_debugger
variable
patched to 1
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 102
vm_map_enter
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 103
vm_map_protect
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 104
AMFI Binary Trust Cache Patch
replaced with
MOV R0, 1
BX LR
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 105
Patching the Sandbox
function is hooked
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 106
Questions
Checkout my github
https://github.com/stefanesser
Stefan Esser • iOS Kernel Exploitation - IOKit Edition • November 2011 • 107