the path to EL1 in iOS 11
@i41nbeer
Please expand the speaker notes if you’re reading this deck!
I find bugs, and sometimes exploit them
15 years ago...
http://cseweb.ucsd.edu/~savage/papers/IEEESP03.pdf
char db_name[16];
...
strcpy(db_name, &udp_packet[1])
poor software development practices used to lead to CLEARLY VISIBLE harm
"Our new design approaches need to dramatically reduce the number of such issues that come up in the software that Microsoft, its partners and its customers create"
https://www.wired.com/2002/01/bill-gates-trustworthy-computing/
"At the same time, we're in the process of training all our developers in the latest secure coding techniques."
https://www.wired.com/2002/01/bill-gates-trustworthy-computing/
"So now, when we face a choice between adding features and resolving security issues, we need to choose security."
https://www.wired.com/2002/01/bill-gates-trustworthy-computing/
15 years later
https://assets.documentcloud.org/documents/4599753/NSO-Pegasus.pdf
15 years later:
now, poor software development practices lead to HIDDEN harm
in Android and iOS
quite widespread and damaging,
but easy to ignore
security systems design is making promises which poor software development practises cannot keep
https://www.apple.com/business/docs/iOS_Security_Guide.pdf
given sufficient bug density, security design is irrelevant
"feedback that we've heard pretty consistently, both from my red team at Apple and also from researchers directly, is that it's getting increasingly more difficult to find those most critical types of security vulnerabilities."
mach_voucher_extract_attr_recipe_trap(
struct mach_voucher_extract_attr_recipe_args *args) {� ipc_voucher_t voucher = IV_NULL;� kern_return_t kr = KERN_SUCCESS;� mach_msg_type_number_t sz = 0;�� if (copyin(args->recipe_size, (void *)&sz, sizeof(sz)))� return KERN_MEMORY_ERROR;
.....
uint8_t *krecipe = kalloc((vm_size_t)sz);
if (!krecipe) {
kr = KERN_RESOURCE_SHORTAGE;
goto done;
}
if (copyin(args->recipe, (void *)krecipe, args->recipe_size)) {
if (dst->sa_family == AF_INET &&
dst->sa_len != sizeof(mpte->__mpte_dst_v4)) {
error = EINVAL;
goto out;
}
if (dst->sa_family == AF_INET6 &&
dst->sa_len != sizeof(mpte->__mpte_dst_v6)) {
error = EINVAL;
goto out;
}
if ((mp_so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) {
memcpy(&mpte->mpte_dst, dst, dst->sa_len);
}
legacy & esoteric
mitigations
weak mitigations can be trivially defeated with more bugs; if you don't care about bugs there's no point shipping weak mitigations
randomization
zone_map
384 MB reserved kernel vm region (across all iOS 11 devices)
kalloc.64 zcram
X
X
X
X
X
X
X
X
X
X
X
small number of hardware pages
individual allocations
zone_map
384 MB reserved kernel vm region (across all iOS 11 devices)
kalloc.64 zcram
X
X
X
X
X
X
X
X
X
X
X
small number of hardware pages
individual allocations
zone_map
384 MB reserved kernel vm region (across all iOS 11 devices)
kalloc.64 zcram
X
X
X
X
X
X
X
X
X
X
X
small number of hardware pages
individual allocations
unsigned int random_bool_gen_bits(
struct bool_gen *bg, unsigned int *buffer, unsigned int count, unsigned int numbits)
{
unsigned int index = 0;
unsigned int rbits = 0;
for (unsigned int bitct = 0; bitct < numbits; bitct++) {
// Find a portion of the buffer that hasn't been emptied.
// We might have emptied our last index in the previous iteration.
while (index < count && buffer[index] == 0)
index++;
// If we've exhausted the pool, refill it.
if (index == count) {
random_bool_gen_entropy(bg, buffer, count);
index = 0;
}
// Collect-a-bit
unsigned int bit = buffer[index] & 1;
buffer[index] = buffer[index] >> 1;
rbits = bit | (rbits << 1);
}
return rbits;
}
zone_map
384 MB reserved kernel vm region (across all iOS 11 devices)
kalloc.64 zcram
X
X
X
X
X
X
X
X
X
X
X
small number of hardware pages
individual allocations
1) there's still a pattern
2) larger objects are less randomized
3) can we just sort the freelist?
please stop just spot-fixing bugs;
learn from them, and act on that
...one more thing
https://www.amnesty.org/en/latest/research/2018/08/amnesty-international-among-targets-of-nso-powered-campaign/
apple bug bounty
"it's not meant to be any kind of exclusive club. So, if someone who is not in the program, brings to us a vulnerability that would be covered under the program, we welcome that, we're going to take a look, and if the work merits it we'll invite them in to the program and we'll reward the vulnerability that they found."
"In addition to these exact amounts we will let researchers donate the reward to a charity of their choosing, we will at our option match that 1 to 1, doubling the donation."
CVE-2016-7612 $100'000
CVE-2016-7621 $100'000
CVE-2016-7644 $100'000
CVE-2017-2353 $100'000
CVE-2017-2370 $100'000
CVE-2017-2360 $100'000
CVE-2017-2473 $100'000
CVE-2017-2474 $100'000
CVE-2017-2478 $100'000
CVE-2017-2501 $100'000
CVE-2017-2482 $100'000
CVE-2017-2490 $100'000
CVE-2017-13867 $100'000
CVE-2017-13847 $100'000
CVE-2017-13861 $100'000
CVE-2018-4241 $100'000
CVE-2018-4243 $100'000
694799600 $100'000
696255847 $100'000
CVE-2016-7637 $50'000
CVE-2016-7661 $50'000
bug with charity match
bug with charity match
CVE-2016-7660 $50'000
CVE-2017-2522 $50'000
CVE-2017-2523 $50'000
CVE-2017-2524 $50'000
CVE-2017-7047 $50'000
CVE-2018-4206 $50'000
695930632 $50'000
695992129 $50'000
696619631 $50'000
$2'450'000