nOBEX allows emulating the PBAP, MAP, and HFP profiles to test vehicle infotainment systems and similar devices using these profiles. nOBEX provides PBAP and MAP clients to clone the genuine virtual filesystems for these profiles from a real phones. This means downloading the entire phone book and all text messages. Raw vcards, XML listings, and MAP BMSG structures are stored, and can be modified as desired for negative testing. nOBEX can then act as a PBAP and MAP server, allowing vehicles and other devices to connect to it and retrieve phone book and message information. Vcards, BMSGs, and XML listings are sent exactly as saved, allowing malformed user modified data to go through. Since most vehicle head units require HFP support before they attempt using PBAP and MAP, nOBEX also provides rudimentary support for HFP. It will send back user customizable preset responses to AT commands coming from the vehicle's head unit. This allows mimicking a real cell phone.
nOBEX is built on top of the PyOBEX project by David Boddie. This tool would not have been possible without David's great efforts in making OBEX approachable and easy to work with. nOBEX extends PyOBEX by adding support for large multi-part OBEX messages, HFP emulation, PBAP and MAP servers, a MAP client, and an improved PBAP client.
nOBEX (and PyOBEX) use the BlueZ Bluetooth stack to advertise over the Service Discovery Protocol (SDP) and establish RFCOMM connections. nOBEX/PyOBEX contain standalone implementations of the OBEX specification for client and server roles. Both Python 2 and 3 are supported.
In client mode, nOBEX uses BlueZ to query services offered by the server. If it detects that the requested service is available, it connect to the server over RFCOMM on the port specified over SDP. OBEX requests are constructed and sent to the server in accordance with the profile in use. Responses are interpreted and saved to disk. Client modes for PBAP and MAP can be used to clone a real phone.
In server mode, nOBEX advertises the available services over SDP. When a client makes an RFCOMM connection on the advertised port, the server will accept and handle OBEX requests. OBEX responses to requests will be sent using the data on disk. The PBAP and MAP servers serve file/folder structures matching those generated by the respective clients.
The following setup instructions were tested on Fedora 24, 27, and 29. Other recent distributions may also work, but experiences may vary. You may need to install legacy bluez tools (including sdptool) if your distribution does not bundle sdptool. Also be aware that OBEX servers tend to not work inside virtual machines with shared Bluetooth adapters. Either run Linux natively, or have a dedicated USB Bluetooth adapter used only by the VM.
Try probing advertised local services on SDP:
sudo sdptool browse local
If you are running a recent distribution, it will probably fail due to some breaking API changes in BlueZ 5. You can fix it by running bluetoothd in compat mode. Do this by editing the systemd service for bluetoothd.
sudo vi /usr/lib/systemd/system/bluetooth.service
Add --compat to the ExecStart line:
ExecStart=/usr/libexec/bluetooth/bluetoothd --compat
Now restart bluetoothd:
sudo service bluetooth stop
sudo systemctl daemon-reload
sudo service bluetooth start
sudo hciconfig -a hci0 reset
Test browsing local SDP services again (it should work this time):
sudo sdptool browse local
Get nOBEX and install it:
git clone https://github.com/nccgroup/nOBEX.git
cd nOBEX
sudo python3 setup.py install
Find the MAC address of a phone whose phone book you wish to clone:
hcitool scan
Clone the PBAP contents of an existing phone (use your correct MAC and a preferably empty or nonexistent destination directory of your choice):
python3 examples/pbapclient.py 5C:51:88:8A:EC:5B ~/pbap_root/
Alternatively, use the PBAP sample data tree located in the examples/pbap_root
folder.
Modify the vcards and listing XMLs in the your PBAP dump directory as desired. Now run a PBAP server using the cloned phone book:
sudo python3 examples/multiserver.py --pbap ~/pbap_root/
You'll also need to pair your PBAP client with the computer (PBAP server).
Pull the message data off your phone to establish a test MAP tree:
python3 examples/mapclient.py 5C:51:88:8A:EC:5B ~/map_root/
Alternatively, if your phone doesn't support MAP properly, use the MAP sample data tree
located in the examples/map_root
folder.
Modify the sample data as desired. Then run the server, indicating where it should look for the root of the MAP tree.
sudo python3 examples/multiserver.py --map ~/map_root/
The HFP client (hands free, car kit emulator) provides an AT command CLI to talk to your HFAG (phone/modem). I call it the "HFP client" despite it being an RFCOMM server because it is a "client" for the HFAG (phone/modem). You use the HF emulator ("client") to send AT commands to the HFAG, despite the fact that the "server" (HFAG) is the one that initiates the RFCOMM connection.
To run the HF emulator:
sudo python3 examples/hfpclient.py
You may need to start the HF emulator to advertise that you are an HF over SDP before you pair your phone. When the HF emulator is running, your phone will initiate an AT command RFCOMM connection with the emulator script. To expedite this process, you can click on your paired computer in your phone's Bluetooth settings to trigger a connection/reconnection.
Once the HFAG (phone/modem) initiates a connection, you usually have a limited window (30 seconds to a minute) to configure the HFP session. Before you can send useful AT commands (like initiating phone calls), you have to send a sequence of AT commands within the limited window, else the HFAG might disconnect from you. The following initial AT command sequence should work for most phones:
AT+BRSF=39
AT+CIND=?
AT+CIND?
AT+CMER=3,0,0,1
AT+CHLD=?
AT+CCWA=1
AT+CLIP=1
AT+NREC=0
The HFP server (audio gateway) is fairly basic, sending back preconfigured replies to select commands. The server is set up to support common HFP commands out of the box, but every vehicle will likely require a few additional commands and/or changes to responses. Custom responses can be configured through a text file with a format of command and response pairs on each line, command and response being separated by a tab. Sample config files can be found in the examples/bbeast folder.
Unlike the other servers, the nOBEX HFP AG implementation doesn't actually accept RFCOMM connections. The HFP standard is ambiguous on how connections should be established, and thus both the HF and AG are allowed to both accept and initiate connections. Different head units behave differently when it comes to connection establishment practices. However, most HF devices tend to accept being connected to by the AG if the AG does not accept connections on its own port. Thus, the nOBEX HFP AG "server" just searches through paired devices for ones that support the HF service, and nOBEX then connects to the HF device.
Be aware that the HFP AG code will try connecting to any device listed under
/var/lib/bluetooth/*/*
that claims to support the HFP HF role. Thus, you should
delete any erroneous pairings in that directory before trying to use the HFP server.
To run a standalone HFP AG (config file is optional):
sudo python3 examples/multiserver.py --hfp [config_file]
The HFP server (HFAG) also supports interactive operation where you can edit auto-responses at runtime or manually send AT responses. The HFP server listens on port 7137 of localhost for commands. You can connect to it using netcat as shown below:
nc localhost 7137
There are only two simple commands for this interface:
send <atresp>
- sendatresp
as an AT responseursp <atcmd> <atresp>
- update/set the auto-response foratcmd
toatresp
The following example commands will simulate an incoming phone call:
ursp AT+CLCC +CLCC: 1,1,4,0,0,"1234567890",129
send RING
The FTP (File Transfer Profile) client allows you to browse files on an OBEX FTP server, such as another computer running nOBEX, or an Android phone running the Bluetooth File Transfer app. There is an FTP client sample program located in the examples directory.
python3 examples/ftpclient.py SERVER_MAC_ADDRESS [save_directory]
Running the example FTP client with only a Bluetooth MAC address as the argument will print
out a recursive directory listing of all files accessible over OBEX FTP on the server. If the
optional save_directory
argument is provided, the script will download every file that is
accessible on the server and save it to the specified save directory on your computer.
The FTP server allows a client to browse files on your computer (server) inside a specified folder.
sudo python3 examples/multiserver.py --ftp PATH_TO_FTP_FOLDER
The OPP (Object Push Profile) client allows pushing a file on your computer to an OBEX OPP server.
python3 examples/pushclient.py SERVER_MAC_ADDRESS FILE_TO_PUSH
The OPP server allows a client to push files to your computer (server) inside a specified folder.
sudo python3 examples/multiserver.py --opp PATH_TO_OPP_FOLDER
The multiserver.py scripts allows running any combination of HFP, MAP, PBAP, FTP, and OPP servers simultaneously. Just combine the arguments from the examples shown above. To run HFP, MAP, and PBAP simultaneously:
python3 examples/multiserver.py --map ~/map_root/ --pbap ~/pbap_root/ --hfp [config_file]
The combination of HFP and PBAP has been tested successfully on a 2012 Ford Focus.
The primary purpose of nOBEX is to perform negative testing and fuzzing of PBAP and MAP clients on automotive head units. The HFP support and PBAP/MAP client support are intended to facilitate this goal. Manual fuzzing can be performed by running a server with hand-modified XML listings, vcards, and BMSGs. OBEX is a rich fuzzing target with many nested TLV structures that can span multi-part messages. PBAP and MAP greatly increase the attack surface with vcard, BMSG, and XML parsers.
nOBEX does not have integrated support for automated fuzzing, but since it is written in Python, it is easy to extend. More powerful fuzzing capabilities can be built by pairing it with a mutation engine and instrumenting the target device.
Beyond fuzzing MAP and PBAP on automotive head units, nOBEX can also be used for normal positive testing of PBAP, MAP, and other OBEX profiles (such as FTP) for both client and server roles. The PBAP and MAP servers were tested with the OBEX Commander app for Android, in which many crashes could be triggered by faulty OBEX communication and malformed profile specific data. Furthermore, the HFP support can be used to manually fuzz AT commands.