ADB WI-FI

Architecture of ADB Wifi

ADB has always had the capability to communicate with a device over TCP. However the process involved is convoluted and results in an insecure channel. The steps are as follows.

  1. Connect device via USB cable.
  2. Accept host’s public key in the device UI dialog (pairing).
  3. Request adbd to open a TCP server socket
$ adb tcpip 5555
  1. Retrieve device’s Wi-Fi IP address
IP=`adb shell ip route | awk '{print $9}'`
  1. Finally, connect over TCP
$ adb connect $IP:5555

After all these steps, adb server is communicating with adbd over TCP unencrypted. This means all traffic can be eavesdropped and open to MITM attacks.

The two problems ADB Wifi solves

ADB Wifi allows a user to pair a device and a host in a single step, without requiring prior USB connection.

Moreover, ADB Wifi uses TLS which allows for secure authentication and a secure connection after authentication.

How ADB Wifi works

ADB Wifi revolves around four capabilities.

  • Pair without the user having to click β€œAllow debugging”.
  • Encrypt ADB traffic.
  • Advertise services over the network.
  • Auto-connect to paired devices.

Pairing

A host and a device are considered paired if the hostβ€˜s public key is in the device’s /data/misc/adb/adb_keys or /adb_keys files (keystore). After pairing, the host can be trusted by the device because the host can use its private key to answer the challenges from the device (and the device can verify answer using keys from the keystore until a matching public key is found).

To pair, ADB Wifi uses a Pairing Server running on the device. The Pairing Server communicates using RSA 2048-bit encryption (in a x509 certificate). Trust is bootstrapped using a shared secret, seeded either by a six-digit number (pairing code) or a 10-digit number (QR code pairing).

Encrypted traffic

After pairing, and if the user has enabled β€œWireless debugging”, adbd listens on a TCP server socket (port picked at random). This is not the same as the legacy tcpip socket. The legacy socket greets all communication attempts with an A_AUTH packet whereas this socket opens communication with A_STLS which means all traffic will be TLS encrypted (and authentication is different as well).

All this traffic is handled by the TLSServer which is forwarded to adbd’s fdevent. When users toggle β€œWireless Debugging”, they start and stop the TLSServer.

Network Advertising (mDNS)

All of the elements previously mentioned advertise their presence on the network via mDNS. Three service types are used.

  • _adb._tcp: This is the legacy TCP service started via adb tcpip <PORT>.
  • _adb-tls-pairing._tcp: The service advertised when the device pairing server is active.
  • _adb-tls-connect._tcp: The service advertised when the device TLSServer is active.

Note that all services’ instances are published by the device (adb server is merely a consumer of mDNS packets). Both _adb._tcp and _adb-tls-connect._tcp are published directly by adbd while _adb-tls-pairing._tcp is published via NsdServiceInfo.

mDNS Service Instance names

An instance name prefix is usually adb- followed by the value of the property ro.serialno plus a random suffix added by the mdns backend.

The Pairing Server is special. Its service instance name changes whether it is intended to be used with a pairing code or a QR code.

  • Pairing code: adb-<prop(persist.adb.wifi.guid)>-< mDNS backend suffix > (e.g.: adb-43081FDAS000VS-QXjCrW)
  • QR code: studio-< RANDOM-10> (e.g: studio-58m*7E2fq4)

Auto-connect

When the host starts, it also starts mDNS service discovery for all three service types. Any service instance of type _adb-tls-connect being published by the device results in a connection attempt by the host. If the device was previously paired, TLS authentication will automatically succeed and the device is made available to the host.

CLI tools

ADB Wifi can be set up and monitored with the command line.

mdns check

$ adb mdns check tells the user the name of adb’s mDNS stack and its version.

$ adb mdns check
mdns daemon version [Openscreen discovery 0.0.0]

mdns services

$ adb mdns services lists all supported mdns services’ instances discovered and still active, followed by their service type and their resolved IPv4 address/port.

$ adb mdns services
List of discovered mdns services
adb-14141FDF600081         _adb._tcp	          192.168.86.38:5555
adb-14141FDF600081-QXjCrW  _adb-tls-pairing._tcp  192.168.86.38:33861
adb-14141FDF600081-TnSdi9  _adb-tls-connect._tcp  192.168.86.38:33015
studio-g@<xeYnap/          _adb-tls-pairing._tcp  192.168.86.39:55861

Note: At the moment, IPv6 addresses are resolved but not output by the command.

pair

If a user starts a Pairing Server on the device (via Settings > System > Developer options > Wireless debugging > Pair device with pairing code), they are presented with both a pairing code and the IPv4:port of the Wi-fi interface. In this case the vector to exchange the TLS secret is the user who reads it on the device then types the pairing code on the host.

With the Pairing Server active, ADB Wifi is entirely configurable from the command-line, as follows.

$ adb pair 192.168.86.38:43811
Enter pairing code: 515109
$ adb connect 192.168.86.34:44643
$ adb devices
List of devices attached
adb-43081FDAS000VS-QXjCrW._adb-tls-connect._tcp	device

Android Studio

Pair with code

Android Studio automates pairing with a pairing code thanks to its GUI. The advantage compared to the CLI method is that it relies on mDNS to detect devices with an active Pairing Server. To this effect, Studio polls adb server for service instances of type _adb-tls-pairing.

Pair with QR code

Studio also introduces a QR code system which is just an easy way to share the pairing code between the host and the device.

When a user clicks on β€œPair device Using Wi-Fi”, they are shown a QR code.

In the example code above Studio generated a QR code containing the string WIFI:T:ADB;S:studio-g@<xeYnap/;P:(Aq+v9>Cx>!/;;. The QR code piggyback on WPA3 Specification which specifies the format as follows.

β€œWIFI:” [type β€œ;”] [trdisable β€œ;”] ssid β€œ;” [hidden β€œ;”] [id β€œ;”] [password β€œ;”] [publickey β€œ;”] β€œ;”

Tokens are ; separated. The QR Code contains three tokens

  1. Type (marked by T: prefix) indicates this is an ADB special string.
  2. The ssid field (marked by S: prefix) is repurposed to request a specific service instance name for _adb-tls-pairing._tcp. The device has a special Camera QR code handler which when it sees type T:ADB starts a Pairing Server with the requested instance name. Note that the part after studio- is randomized. This is done so Studio can tell which phone just scanned the QR code (here the instance name requested is studio-g@<xeYnap/).
  3. The password (marked by P: prefix) to use with the Pairing Server (here: (Aq+v9>Cx>!/). This is the second shared secret vector we mentioned earlier. Here the code is generated by Studio and read by the device’s camera.

Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.