Thursday, January 9, 2020

Remote iPhone Exploitation Part 1: Poking Memory via iMessage and CVE-2019-8641

Posted by Samuel Groß, Project Zero

Introduction

This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first blog post in a three-part series that will detail how a vulnerability in iMessage can be exploited remotely without any user interaction on iOS 12.4 (fixed in iOS 12.4.1 in August 2019). It is essentially a more detailed version of my 36C3 talk from December 2019.

The first part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 series provides an in-depth discussion of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second part presents a technique to remotely break ASLR, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 third part explains how to gain remote code execution afterwards.

The attack presented in this series allows an attacker, who is only in possession of a user’s Apple ID (mobile phone number or email address), to remotely gain control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user’s iOS device within a few minutes. Afterwards, an attacker could exfiltrate files, passwords, 2FA codes, SMS and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r messages, emails and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r user and app data. They could also remotely activate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 microphone and camera. All of this is possible without any user interaction (e.g. opening a URL sent by an attacker) or visual indicator (e.g. notifications) being displayed to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user. The attack exploits a single vulnerability, CVE-2019-8641 to first bypass ASLR, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n execute code on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target device outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sandbox.

This research was mainly motivated by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following question: given only a remote memory corruption vulnerability, is it possible to achieve remote code execution on an iPhone without furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r vulnerabilities and without any form of user interaction? This blog post series shows that this is in fact possible.

The vulnerability was found as part of a joint vulnerability research project with Natalie Silvanovich and reported to Apple on July 29 2019, followed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proof-of-concept exploit on August 9, 2019. The vulnerability was first mitigated in iOS 12.4.1, released on August 26, by making cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerable code unreachable over iMessage, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n fully fixed in iOS 13.2, released on October 28 2019. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hardening measures were suggested based on insights gained during exploit development, which, if implemented, should make similar exploits significantly harder in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 future. As some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se hardening measures are also relevant to ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r messenger services and (mobile) operating systems, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y will be mentioned throughout this series and summarized at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of it.

For security researchers, a proof-of-concept exploit targeting iOS 12.4 on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone XS is available here. In order to hinder abuse, it deliberately alerts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim of an ongoing attack by displaying multiple notifications throughout cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploitation process. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, it does not achieve native code execution (i.e. shellcode execution), thus making it more difficult to combine it with an existing privilege escalation exploit. However, none of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se restrictions require furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r vulnerabilities to remedy and only require re-engineering of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit by a capable attacker. The in-built restrictions and notifications are merely designed to stop abuse by unskilled attackers simply running cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code. It should be noted that skilled attackers likely already have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 capability offered by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 released exploit code, eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r from finding vulnerabilities cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves, from reverse engineering patches as has been observed before, or, as 1-day exploit, by for example combining CVE-2019-8646, a remote infoleak bug, with any of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r memory corruption bugs that were found

As usual, my hope is that this research will assist fellow security researchers and software developers by showing how well-intentioned mitigations can be bypassed, how modern exploitation techniques work and sharing some ideas that I have for ensuring that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 weak spots that I've highlighted can be subsequently mitigated.

iMessage Architecture


Incoming iMessages pass through multiple services and frameworks before a notification is finally displayed to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message is written to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages database. The main services handling iMessages on iOS 12.4 without requiring user interaction are depicted below. A red border indicates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existence of a sandbox for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process.



The remotely reachable attack surface, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 notoriously complex NSKeyedUnarchiver API, as well as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iMessage data format, have been described extensively by Natalie Silvanovich in a previous blog post. For cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 purpose of this blog post series, it is important to realize that a vulnerability in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSKeyedUnarchiver API can generally be triggered in two different contexts: in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sandboxed imagent and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unsandboxed SpringBoard process (which manages cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main iOS UI, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 homescreen). Both contexts have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir advantages and disadvantages with regards to exploitation. For example, while SpringBoard already runs outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sandbox and thus appears to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 better target at first, it is also a somewhat critical system process and crashing it will cause a noticeable “respring” of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device, with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 screen suddenly turning black and a loading icon appearing for a few seconds before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lock screen appears. Imagent on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand can safely crash without causing any system behaviour that might be observable to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user and will afterwards simply be restarted.

As of iOS 13, it appears that decoding of NSKeyedUnarchiver data no longer happens inside of SpringBoard but instead in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sandboxed IMDPersistenceAgent, thus significantly reducing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unsandboxed attack surface of iMessage.

iMessage Delivery


In order to deliver an exploit over iMessage, one needs to be able to send custom iMessages to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target. This requires interacting with Apple’s servers and dealing with iMessage’s end2end encryption. An easy way to do this, which was used for this research, is to reuse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existing code by hooking into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iMessage handling code inside imagent with a tool like frida. With that, sending a custom iMessage from a script running on macOS can be done by:

  1. Building cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desired payload (e.g. to trigger an NSKeyedUnarchiver bug) and storing it to disk
  2. Calling a small apple script that instructs Messages.app to send a message with a placeholder content (e.g. “REPLACEME”) to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target
  3. Hooking imagent with frida and replacing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of outgoing iMessages containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 placeholder with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 content of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 payload file

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same way it is also possible to receive incoming messages by using frida to hook cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiver functions in imagent.

As an example, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following iMessage (encoded as a binary plist), will be sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiver when sending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message “REPLACEME” from Messages.app:

{
    gid = "008412B9-A4F7-4B96-96C3-70C4276CB2BE";
    gv = 8;
    p =     (
        "mailto:sender@foo.bar",
        "mailto:receiver@foo.bar"
    );
    pv = 0;
    r = "6401430E-CDD3-4BC7-A377-7611706B431F";
    t = "REPLACEME";
    v = 1;
    x = "REPLACEME";
}

The frida hook will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message before it is serialized, encrypted, and sent to Apple’s servers:

{
    gid = "008412B9-A4F7-4B96-96C3-70C4276CB2BE";
    gv = 8;
    p =     (
        "mailto:sender@foo.bar",
        "mailto:receiver@foo.bar”
    );
    pv = 0;
    r = "6401430E-CDD3-4BC7-A377-7611706B431F";
    t = "REPLACEME";
    v = 1;
    x = "REPLACEME";
    ati = ;
}

This will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cause imagent on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiver’s device to decode cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ati field using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSKeyedUnarchiver API. Example code that allows sending custom messages and dumping incoming ones can be found here.

CVE-2019-8641


The bug that was used for this research is CVE-2019-8641, corresponding to Project Zero issue 1917. It is anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r bug in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSKeyedUnarchiver component which has been discussed in depth by Natalie. While it is likely that ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r memory corruption bugs found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSKeyedUnarchiver components during this research can be exploited in a similar way, this one seemed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most convenient to exploit.

The bug in question occurs during unarchiving of an NSSharedKeyDictionary, a special kind of NSDictionary in which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 keys are declared up front in an NSSharedKeySet to allow for faster element access. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, an NSSharedKeySet can itself have a subSharedKeySet, essentially building a linked list of KeySets. 

To understand cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability, it is first necessary to take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSKeyedUnarchiver serialization format. Below is a simple archive containing a serialized NSSharedKeyDictionary as printed by plutil(1) (NSKeyedArchiver encodes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object graph as a plist) and with some comments added to it:

{
  "$archiver" => "NSKeyedArchiver"
  # The objects contained in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 archive are stored in this array
  # and can be referenced during decoding using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir index
  "$objects" => [
    # Index 0 always contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 nil value
    0 => "$null"
    # The serialized NSSharedKeyDictionary
    1 => {
      "$class" => {value = 7}
      "NS.count" => 0
      "NS.sideDic" => {value = 0}
      "NS.skkeyset" => {value = 2}
    }
    # The NSSharedKeySet associated with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dictionary    
    2 => {
      "$class" => {value = 6}
      "NS.algorithmType" => 1
      "NS.factor" => 3
      "NS.g" => <00>
      "NS.keys" => {value = 3}
      "NS.M" => 6
      "NS.numKey" => 1
      "NS.rankTable" => <00000000 0001>
      "NS.seed0" => 361949685
      "NS.seed1" => 2328087422
      "NS.select" => 0
      "NS.subskset" => {value = 0}
    }
    # The keys of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSSharedKeySet 
    3 => {
      "$class" => {value = 5}
      "NS.objects" => [
        0 => {value = 4}
      ]
    }
    # The value of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first (and only) key
    4 => "cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365_key"
    # ObjC classes are stored in this format
    5 => {
      "$classes" => [
        0 => "NSArray"
        1 => "NSObject"
      ]
      "$classname" => "NSArray"
    }
    6 => {
      "$classes" => [
        0 => "NSSharedKeySet"
        1 => "NSObject"
      ]
      "$classname" => "NSSharedKeySet"
    }
    7 => {
      "$classes" => [
        0 => "NSSharedKeyDictionary"
        1 => "NSMutableDictionary"
        2 => "NSDictionary"
        3 => "NSObject"
      ]
      "$classname" => "NSSharedKeyDictionary"
    }
  ]
  # A reference to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root object in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 archive
  "$top" => {
    "root" => {value = 1}
  }
  "$version" => 100000
}

One thing to note here is that this serialization format supports references to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 objects contained in it through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CFKeyedArchiverUID values. During unarchiving, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSKeyedUnarchiver will keep a mapping of UIDs to objects, so that a single object can be referenced from multiple ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r objects in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same archive. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference is added to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 map before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object’s initWithCoder method (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 constructor used during unarchiving) is invoked. As such, it becomes possible to decode cyclic object graphs, in which case an object can be referenced while it is currently being unarchived furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r up in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 callstack. Interestingly, in that case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first object may not yet be fully initialized when it is referenced. This creates potential for bugs and is exactly what happens for CVE-2019-8641.

Below is Objective-C (ObjC) pseudocode for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initWithCoder implementations of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSSharedKeyDictionary and NSSharedKeySet classes. Readers unfamiliar with ObjC can think of code constructs such as

    [obj doXWith:y and:z];

as a method call on an object, similar to
   
    obj->doX(y, z);

in C++.

  1.   self->_keyMap = [coder decodeObjectOfClass:[NSSharedKeySet class]
  2.                          forKey:"NS.skkeyset"];
  3.   // ... decode values etc.
  4. }

  1.   self->_numKey = [coder decodeInt64ForKey:@"NS.numKey"];
  2.   self->_rankTable = [coder decodeBytesForKey:@"NS.rankTable"];
  3.   // ... copy more fields from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 archive

  4.   self->_subSharedKeySet = [coder 
  5.                             decodeObjectOfClass:[NSSharedKeySet class]
  6.                             forKey:@"NS.subskset"]];

  7.   NSArray* keys = [coder decodeObjectOfClasses:[...] 
  8.                          forKey:@"NS.keys"]];
  9.   if (self->_numKey != [keys count]) {
  10.     return fail(“Inconsistent archive);
  11.   }
  12.   self->_keys = calloc(self->_numKey, 8);
  13.   // copy keys into _keys

  14.   // Verify that all keys can be looked up
  15.   for (id key in keys) {
  16.     if ([self indexForKey:key] == -1) {
  17.       NSMutableArray* allKeys = [NSMutableArray arrayWithArray:keys];
  18.       [allKeys addObjectsFromArray:[self->_subSharedKeySet allKeys]];
  19.       return [NSSharedKeySet keySetWithKeys:allKeys];
  20.     }
  21.   }
  22. }

The implementation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indexForKey routine, which is invoked at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of initWithCoder (line 20), is given below. It uses a hash of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key to index into _rankTable and uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result as an index into _keys. It recursively searches for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 subSharedKeySet until it finds it or no more subSharedKeySets are available:

  1.   NSSharedKeySet* current = self;
  2.   uint32_t prevLength = 0;
  3.   while (current) {
  4.     // Compute a hash from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r internal values of    
  5.     // cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KeySet. Convert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hash to an index and ensure that it 
  6.     // is within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds of rankTable
  7.     uint32_t rankTableIndex = ...;
  8.     uint32_t index = self->_rankTable[rankTableIndex];
  9.     if (index < self->_numKey) {
  10.       id candidate = self->_keys[index];
  11.       if (candidate != nil) {
  12.         if ([key isEqual:candidate]) {
  13.           return prevLength + index;
  14.         }
  15.       }
  16.     prevLength += self->_numKey;
  17.     current = self->_subSharedKeySet;
  18.   }
  19.   return -1;
  20. }
        

Given cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above logic, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following object graph will lead to memory corruption when deserialized:



Here is what happens during unarchiving:
  1. The NSSharedKeyDictionary is unarchived, in turn unarchiving its SharedKeySet
  2. SharedKeySet1’s initWithCoder runs up to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 point where it unarchives its subSharedKeySet (line 6). At this point
  • _numKey is fully controlled by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker as no check has been performed on it yet (that will only happen after _keys has been unarchived)
  • _rankTable is also fully controlled
  • _keys is still nullptr (as ObjC objects are allocated via calloc)
  1. SharedKeySet2 is completely unarchived. Its subSharedKeySet is now a reference to SharedKeySet1 (which is still being unarchived). At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end, it invokes indexForKey: for all keys in its _keys array (line 20)
  2. As SharedKeySet2’s rankTable is all zeros, only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first key can be looked up on itself (see lines 8 through 15 in indexForKey:). The second key will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n be looked up on SharedKeySet1. Here, as _numKey and _rankTable’s content are fully controlled, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code will, in line 10, index into _keys (which is nullptr) with a controlled index, causing a crash.

The following picture shows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 slightly simplified callstack at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 crash: 


As a result of this, a mostly arbitrary address (in this case 0x41414140, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 index is multiplied by 8, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 element size) is now dereferenced and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result used as an ObjC object pointer (an “id”). There are, however, two restrictions on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 addresses that can be accessed with this bug:

  1. The address must be cleanly divisible by 8 (as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 _keys array stores pointer sized values) and
  2. it must be less than 32G as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 index is a 4 byte unsigned integer

Luckily, at least on iOS, most (all?) interesting things in memory are located below 0x800000000 (32G) and thus become accessible using this primitive.

As it turns out, even a seemingly uninteresting null pointer dereference can become a pretty powerful exploit primitive under cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right circumstances... :)

At this point no information about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target process’ address space is available. As such, some kind of information leak must first be constructed. This will be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 topic of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next blog post.

Tuesday, January 7, 2020

Policy and Disclosure: 2020 Edition

Posted by Tim Willis, Project Zero

At Project Zero, we spend a lot of time discussing and evaluating vulnerability disclosure policies and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir consequences for users, vendors, fellow security researchers, and software security norms of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 larger industry. We're very happy with how well our disclosure policy has worked over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 past five years. We've seen some big improvements to how quickly vendors patch serious vulnerabilities, and now 97.7% of our vulnerability reports are fixed within our 90 day disclosure policy.

In saying that, it's a complex and often controversial topic that is frequently discussed both inside and outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 team.  We often receive feedback from vendors that Project Zero works closely with regarding our current policies: sometimes it's things cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y want us to change, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r times it's how our work has positively impacted cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir work and users. Conversations like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se have helped develop our policies over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 years. For example, we introduced our 14-day grace-period in 2015 after helpful discussions with various vendors.

We recently reviewed our policies and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 goals we hope to accomplish with our disclosure policy. As a result of that review, we have decided to make some changes to our vulnerability disclosure policy in 2020. We will start by describing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 changes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 policy, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n discuss cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rationale behind cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se changes.

Summary of changes for 2020

For vulnerabilities reported starting January 1, 2020, we are changing our Disclosure Policy: Full 90 days by default, regardless of when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug is fixed.  

Fix a bug in 20 days? We will release all details on Day 90.
Fix a bug in 90 days? We will release all details on Day 90.

If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is mutual agreement between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vendor and Project Zero, bug reports can be opened to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public before 90 days elapse. For example, a vendor wants to synchronize cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 opening of our tracker report with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir release notes to minimize user confusion and questions. 

We will try this policy for 12 months, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n consider whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r to change it long term.

The current list of changes for 2020:

2019
2020 Trial
  1. 90 days or when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug is fixed (decided by researcher discretion), whichever is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 earliest.
  1. Full 90 days, regardless of when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug is fixed. Earlier disclosure with mutual agreement.
  1. Policy goal:
    • Faster patch development
  1. Policy goals:
    • Faster patch development
    • Thorough patch development
    • Improved patch adoption
  1. Inconsistent handling of incomplete fixes. Such issues are eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r filed as separate vulnerabilities or added to existing reports at researcher discretion.
  1. Details of incomplete fixes will be reported to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vendor and added to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existing report (which may already be public) and will not receive a new deadline.
  1. Bugs fixed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 grace period* would be opened to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public sometime after a patch was released.
  1. Project Zero tracker reports are immediately opened when patched during cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 grace period*.
  1. Project Zero tracker reports are opened at researcher discretion after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 deadline expires.
  1. Project Zero tracker reports are opened automatically on Day 90 (or earlier under mutual agreement).
* The grace period is an additional 14 days that a vendor can request if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y do not expect that a reported vulnerability will be fixed within 90 days, but do expect it to be fixed within 104 days. If a grace period is requested, and a bug is fixed between 90 and 104 days after it was reported, bug details will be released on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 day it is fixed. Grace periods will not be granted for vulnerabilities that are expected to take longer than 104 days to fix. Note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 seven day deadline for vulnerabilities that are being actively exploited "in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wild" will remain unchanged.

We're constantly considering whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r our policies are in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interest of user security, and we believe this change is a furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r step in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right direction. We also think it's simple, consistent and fair. 

Rationale on changes for 2020


For cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last five years, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 team has used its vulnerability disclosure policy to focus on one primary goal: Faster patch development

We want to make attacks using zero-day exploits more costly. We do this through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lens of offensive vulnerability research and evidence of how real attackers behave. This involves discovering and reporting a large number of security vulnerabilities, and through our experience with this work, we realised that faster patch development and patch deployment were very important and areas for industry improvement.

If patches take a long time to develop and deploy, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n we quickly fall behind cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 curve: more bugs are introduced than vendors can fix and a herculean effort is required to get things back on track.

We also regularly uncover cases of "bug collisions" with our research. This is where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability we discovered was previously found and exploited by a real attacker. Knowing that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerabilities that we find are often already being secretly exploited to harm users creates a sense of urgency, and so we ask vendors to fix issues as quickly as possible.

After five years of applying a 90-day disclosure deadline, we're proud of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results we've seen: vulnerabilities are being fixed faster than ever. For example, around cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time Project Zero started in 2014, some issues were taking upwards of six months to fix. Fast forward to 2019, and 97.7% of our issues are fixed under deadline. That said, we know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is still room for improvement, both in industry-wide patch development speed and over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire vulnerability management lifecycle.

Revisiting our underlying policy principles and goals


We recently spent some time articulating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 underlying principles of our policies:

  • Simple.  Simplicity is important because we want to be easily understood. We also want to operate at scale, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rwise it's even harder to aggressively push all of industry to do better. 
  • Consistent.  We want to be reliable and predictable. We want to apply our deadlines in a deterministic manner without fear or favour, demonstrating that we mean what we say. The bar for any exception/inconsistency needs to remain extremely high (note: we've only had two exceptions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 five year history of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 team).
  • Fair.  We want to be equitable, balanced and impartial. We don't want to be in a position where different vendors (including Google!) get a form of preferential treatment. The same rules should apply to everyone.

We also realised as part of our discussions that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are two ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r policy goals that we wanted to include. Based on those discussions, here are our policy goals for 2020:

  1. Faster patch development (existing): We want vendors to develop patches quickly and have processes in place to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hands of end users. We will continue to pursue this with urgency.

  1. Thorough patch development (new): Too many times, we've seen vendors patch reported vulnerabilities by "papering over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cracks" and not considering variants or addressing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root cause of a vulnerability. One concern here is that our policy goal of "faster patch development" may exacerbate this problem, making it far too easy for attackers to revive cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir exploits and carry on attacking users with little fuss. 

  1. Improved patch adoption (new): End user security doesn't improve when a bug is found, and it doesn't improve when a bug is fixed. It improves once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end user is aware of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug and typically patches cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir device. To this end, improving timely patch adoption is important to ensure that users are actually acquiring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 benefit from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug being fixed.

This new policy direction for 2020 gives clear incentives for vendors, especially those that have raised cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following issues with us in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 past. 

  • Since we founded Project Zero, some vendors hold cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 view that our disclosures prior to significant patch adoption are harmful. Though we disagree (since this information is already public and being used by attackers per our FAQ here), under this new policy, we expect that vendors with this view will be incentivised to patch faster, as faster patches will allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m "additional time" for patch adoption. 
  • The full 90 day window is available to perform root cause and variant analysis. We expect to see iterative and more thorough patching from vendors, removing opportunities that attackers currently have to make minor changes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir exploits and revive cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir zero-day exploits.
  • We're also being explicit on improving patch adoption, since we're incentivising that vendors should be able to offer updates and encourage installation to a large population within 90 days.  

We also really like that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new policy will improve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 consistency of our disclosure process, while also remaining simple and fair. For example, some vendors considered our determination of when a vulnerability was fixed as unpredictable, especially when working with more than one researcher on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 team at a given time. They saw it as a barrier to working with us on larger problems, so we're going to remove cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 barrier and see if things improve. We hope this experiment will encourage vendors to be transparent with us, to share more data, build trust and improve collaboration.

Disclosure policy is a complex topic with many trade-offs to be made. We don't expect this policy to please everyone, but we’re optimistic that it will improve on our current policy, encompasses a good balance of incentives and will be a positive step for user security. We plan to re-evaluate whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it is accomplishing our policy goals in late 2020.