User Tools

Site Tools


public:wikiblog:26-05-2025-en-reverse-engineering-blackberry-q5-setup-wifi-calls

Reverse engineering Blackberry Q5 setup "calls to home"

Blackberry disabled it's servers on January 4 2022 (Business Insider), making their phones basically bricks, if they were not “activated” before that date. I just bought a used BB Q5 with BBOS 10, that would not allow to use “autoloader” (to flash new OS), or really any other exploit method I could find online. So I took it's fate into my own hands and started investigation.

The setup

My setup for this investigation looks like this:

  1. Dell Latitude 5290 with Ubuntu 24.04
  2. Blackberry Q5 with BBOS 10.2.1.3247

…and that's it.

Steps

Getting my feet wet

First I created a WiFi hotspot on my Ubuntu machine, and with Wireshark in background I connected my Q5 on “Network setup” screen to said hotspot. It showed me that after connecting to WiFi, Q5 asks DNS for such domains (in correct order):

  1. cse.doc.blackberry.com
  2. xtra.gpsonextra.com
  3. inet.registration.blackberry.com
  4. pki.services.blackberry.com
  5. clients3.google.com
  6. cs.sl.blackberry.com (only after DNS response for inet.registration.blackberry.com)
  7. time.blackberry.com (only after answer to PKIOperation request)

Setting up local DNS server

For my WiFi hotspot, I used builtin thingy in Ubuntu settings that allows me to create a hotspot in two clicks. Turns out, it also runs dnsmasq as a DHCP server and DNS-cache. Good thing, that after looking in htop, it uses a flag that loads config from /etc/NetworkManager/dnsmasq-shared.d/. So I created a new file in that directory, and added such configuration:

address=/www.blackberry.com/10.42.0.1
address=/pki.services.blackberry.com/10.42.0.1
address=/inet.registration.blackberry.com/10.42.0.1
address=/cse.doc.blackberry.com/10.42.0.1

Restart the hotspot device, and Blackberry now thinks my laptop is blackberry.com.

Setting up local HTTP server

Just quick and simple Nginx configuration, to check what URL's are being requested:

server {
  listen 80;
  root /var/www/html;
  server_name inet.registration.blackberry.com;
  access_log /var/log/nginx/inet.registration.blackberry.com.access.log;
  error_log /var/log/nginx/inet.registration.blackberry.com.error.log;
  location / {
    try_files $uri $uri/ =404;
  }
}

First requests

For now I've only setup the inet.registration.blackberry.com domain in Nginx, but after looking in access log, we can see some interesting stuff:

10.42.0.61 - - [26/May/2025:23:10:57 +0200] "GET /select/wifiloginsuccess/EN/ HTTP/1.1" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:10:59 +0200] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:11:00 +0200] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:11:01 +0200] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:11:03 +0200] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:11:04 +0200] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:11:17 +0200] "GET /select/wifiloginsuccess/EN/ HTTP/1.1" 404 162 "-" "-"
10.42.0.61 - - [26/May/2025:23:11:18 +0200] "GET /select/wifiloginsuccess/ HTTP/1.1" 404 134 "-" "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.2.1.3247 Mobile Safari/537.35+"
10.42.0.61 - - [26/May/2025:23:11:57 +0200] "GET /select/wifiloginsuccess/EN/ HTTP/1.1" 404 162 "-" "-"

What we can see here, is that:

  1. Blackberry first checks if there is internet by GET'ting inet.registration.blackberry.com/select/wifiloginsuccess/EN/
  2. Then it wants to do a PKIOperation which I would believe to be a Public key request
  3. And after pressing the “Hotspot login” button on BB, it asks about wifiloginsuccess again

What we can do with this information:

  1. Crash the browser using some webkit exploit in hopes it exits to home screen?
  2. Check what this PKI Operation sends to server and try to make our own?

Checking out PKI Operation request

Let's check that PKI Operation request. Quick fix in nginx configuration to forward requests to port 5000 which we will use later:

location /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1 {
	proxy_pass http://localhost:5000;
	proxy_set_header Host $host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto $scheme;
}

Restart nginx, run netcat to listen at port 5000, tee output to some file (nc -l -p 5000 | tee test.bin), and we get…

POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0
Host: pki.services.blackberry.com
X-Real-IP: 10.42.0.61
X-Forwarded-For: 10.42.0.61
X-Forwarded-Proto: http
Connection: close
Content-Length: 2013
Accept: */*

0�0�1	*�H��
��0�1�0�`�He0�	*�H��
[...]

After removing the header from file, let's check what we're working with…

mdukat@mdukat-Latitude-5290:~$ file Downloads/test.bin 
Downloads/test.bin: DER Encoded PKCS#7 Signed Data
mdukat@mdukat-Latitude-5290:~$ openssl pkcs7 -inform der -in Downloads/test.bin -print_certs -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 9020257421968243025 (0x7d2e64557aff7951)
        Signature Algorithm: ecdsa-with-SHA512
        Issuer: C=CA, O=Research In Motion Limited, OU=BlackBerry, CN=2BD06E17
        Validity
            Not Before: May 26 23:06:27 2025 GMT
            Not After : May 26 23:06:27 2026 GMT
        Subject: C=CA, O=Research In Motion Limited, OU=BlackBerry, CN=2BD06E17
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:36:d2:a1:09:92:39:e2:3d:22:3a:f7:26:61:6d:
                    b8:2a:da:d9:d5:ac:16:61:34:59:c1:41:22:c7:40:
                    ae:48:9b:8d:87:cc:6c:df:a5:7c:6e:93:83:9d:4f:
                    90:3b:cb:16:b2:a0:3c:4e:4d:d4:ba:3a:4b:d0:9d:
                    2d:14:b3:e7:c8
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: critical
                TLS Web Server Authentication, TLS Web Client Authentication
    Signature Algorithm: ecdsa-with-SHA512
    Signature Value:
        30:46:02:21:00:be:df:fe:bf:46:a6:ff:5e:79:2c:39:d3:f6:
        d0:8b:f2:01:e0:3b:6c:40:22:ae:3f:d8:28:40:cf:9c:3f:af:
        a4:02:21:00:e8:31:5b:b9:ae:24:5e:b7:7e:54:88:d1:cf:3e:
        c1:55:84:43:aa:00:fb:e1:ee:19:b4:db:a3:60:da:1d:b7:48
-----BEGIN CERTIFICATE-----
MIIB3zCCAYSgAwIBAgIIfS5kVXr/eVEwCgYIKoZIzj0EAwQwWjELMAkGA1UEBhMC
Q0ExIzAhBgNVBAoMGlJlc2VhcmNoIEluIE1vdGlvbiBMaW1pdGVkMRMwEQYDVQQL
DApCbGFja0JlcnJ5MREwDwYDVQQDDAgyQkQwNkUxNzAeFw0yNTA1MjYyMzA2Mjda
Fw0yNjA1MjYyMzA2MjdaMFoxCzAJBgNVBAYTAkNBMSMwIQYDVQQKDBpSZXNlYXJj
aCBJbiBNb3Rpb24gTGltaXRlZDETMBEGA1UECwwKQmxhY2tCZXJyeTERMA8GA1UE
AwwIMkJEMDZFMTcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ20qEJkjniPSI6
9yZhbbgq2tnVrBZhNFnBQSLHQK5Im42HzGzfpXxuk4OdT5A7yxayoDxOTdS6OkvQ
nS0Us+fIozQwMjAOBgNVHQ8BAf8EBAMCBaAwIAYDVR0lAQH/BBYwFAYIKwYBBQUH
AwEGCCsGAQUFBwMCMAoGCCqGSM49BAMEA0kAMEYCIQC+3/6/Rqb/XnksOdP20Ivy
AeA7bEAirj/YKEDPnD+vpAIhAOgxW7muJF63flSI0c8+wVWEQ6oA++HuGbTbo2Da
HbdI
-----END CERTIFICATE-----

Let's make a simple Flask app and try answering an “OK” message. We'll also save the requests for later.

from flask import Flask, request
import os
import uuid
 
app = Flask(__name__)
 
@app.route('/ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1', methods=['POST'])
def handle_post():
    filename = f"/tmp/request_{uuid.uuid4().hex}.dat"
 
    with open(filename, 'wb') as f:
        f.write(request.data)
 
    return "OK", 200
 
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Run, and… Nothing, Blackberry still says that there's no internet connection, even tho both wifiloginsuccess and PKIOperation return 200 OK. What's interesting, is that BB tries this PKIOperation request every second, five times. Kinda fast for a simple retry, I think?

(venv) mdukat@mdukat-Latitude-5290:~/Documents$ python3 app.py 
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.0.129:5000
Press CTRL+C to quit
127.0.0.1 - - [27/May/2025 01:55:48] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 200 -
127.0.0.1 - - [27/May/2025 01:55:49] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 200 -
127.0.0.1 - - [27/May/2025 01:55:51] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 200 -
127.0.0.1 - - [27/May/2025 01:55:52] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 200 -
127.0.0.1 - - [27/May/2025 01:55:53] "POST /ra/scep/rimbbcp-ica-1/rimbbcp-ira-1/rimbbcp-dev-p1?operation=PKIOperation HTTP/1.0" 200 -

After some more research, I learned that it is a base of SCEP protocol for device enrollment, and that I would probably need a CA cert that's on the device itself, to sign it from “my” server.

Files generated in this analysis

public/wikiblog/26-05-2025-en-reverse-engineering-blackberry-q5-setup-wifi-calls.txt · Last modified: 2025/05/27 00:25 by mdukat