BlackBerry Spyware Dissected

Yesterday it was reported by variousmedia outlets that a recent BlackBerry software update from Etisalat (a UAE-based carrier) contained spyware that would intercept emails and text messages and send copies to a central Etisalat server. We decided to take a look to find out more. We're not sure why the software was delivered in both .jar and .cod form. The .cod file is a RIM proprietary format that contains the compiled Java classes along with a signature. Therefore it's not even necessary to send the .jar, but they did, completely unobfuscated. Arrogance or incompetence? Here's what's inside:

The Recv class implements net.rim.blackberry.api.mail.event.FolderListener and net.rim.blackberry.api.mail.event.StoreListener, allowing it to hook folder and message store updates. It's installed using addFolderListener().

The Send class implements net.rim.blackberry.api.mail.event.FolderListener and net.rim.blackberry.api.mail.SendListener, allowing it to hook folder updates and outbound messages. It's not installed as a listener via addSendListener(), though it's used explicitly to forward messages later on.

The StatusChange class implements net.rim.device.api.system.RadioStatusListener and net.rim.device.api.system.GlobalEventListener, allowing it to hook radio events such as a change of network. It's installed using addRadioListener() and addGlobalEventListener(), and all it really does is remove and re-register the Recv listener when certain network events occur.

Whenever a message is received on the device, the Recv class first inspects it to determine if it contains an embedded command -- more on this later. If not, it UTF-8 encodes the message, GZIPs it, AES encrypts it using a static key ("EtisalatIsAProviderForBlackBerry"), and Base64 encodes the result. It then adds this bundle to a transmit queue. The main app polls this queue every five seconds using a Timer, and when there are items in the queue to transmit, it calls this function to forward the message to a hardcoded server via HTTP (see below). The call to http.sendData() simply constructs the POST request and sends it over the wire with the proper headers.

Let's get back to that part about embedded commands. The first thing that the Recv class does is check to see if there's an embedded command in the received message. The first check is actually inactive due to a conditional that will always evaluate to false. If I had to guess I would say that conditional was originally used to check the origin of the message against two BlackBerry device PINs -- that's a guess based on the fact that the strings look similar to the device PIN format. If this code path were enabled, any message with a subject containing "cmd_mail" would be passed off to a command handling routine. If the subject also contained "XXX", it meant the body was encrypted.

Since that section will never run, we move on to the else clause. Here, we see that if the sender name and address match "Customer Service" and the message was PIN-based (as opposed to email based) the body of the message will be treated as an encrypted command packet and the message will be instantly discarded. It's unclear if it will momentarily appear in the user's Inbox, but even if it does, it won't be there for long.

The encryptedCmd() function parses the body of the command packet by extracting anything that looks like a PGP signature block, that is, the chunk of text delimited by the strings "-----BEGIN PGP SIGNATURE-----" and "-----END PGP SIGNATURE-----". It then Base64 decodes the body and AES decrypts it using an AES key based on the device PIN. It then parses the command packet, which is an XML-like structure. It doesn't seem to execute arbitrary commands, just packages up device information such as IMEI, IMSI, phone number, etc. and sends it back to the central server, the same way it does for received messages. It also provides a way to remotely enable/disable the spyware itself using the commands "start" and "stop". Just for fun, here's the key generation routine used to encrypt these command packets to a specific device. The keyString variable is the hex-encoded form of whatever is returned by the RIM API call DeviceInfo.getDeviceId():

The most alarming part about this whole situation is that people only noticed the malware because it was draining their batteries. The server receiving the initial registration packets (i.e. "Here I am, software is installed!") got overloaded. Devices kept trying to connect every five seconds to empty the outbound message queue, thereby causing a battery drain. Some people were reporting on official BlackBerry forums that their batteries were being depleted from full charge in as little as half an hour. The final thing to mention is that the spyware does appear to be installed in a non-running state by default, where it's not actually exfiltrating data once the initial registration packet has gone out. However, using the command and control mechanism we described earlier, the carrier can remotely start/stop the service at will on a per-device basis.

CA Veracode Security Threat Guides

Related Content

Chris Eng, vice president of research, is responsible for integrating security expertise into CA Veracode’s technology. In addition to helping define and prioritize the security feature set of the CA Veracode service, he consults frequently with customers to discuss and advance their application security initiatives. With over 15 years of experience in application security, Chris brings a wealth of practical expertise to CA Veracode.

Get all the latest news, tips and articles delivered right to your inbox.

Cookie Use

We use cookies to collect information to help us personalise your experience and improve the functionality and performance of our site. By continuing to use our site [without first changing your browser setting], you consent to our use of cookies. For more information see our cookies policy.