Tuesday, 10 December 2013

Android to Arduino: the code

In a follow up to the Android to Arduino post, here's the code used. The code currently takes a command from an Android app (a button press), and sends a value to the Arduino over serial. In the mean time the arduino is sending a "nop" string back to the app every second. Not much, but enough to prove input & output over serial.
Video of it working here
Arduino code:

 #include  String inData;
Servo myservo;
int pos=0;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
  myservo.attach(14);
}

// the loop routine runs over and over again forever:
void loop() {
      while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is recieved
        if (recieved == '\n')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);
           
            Serial.print("\n");
            
            inData.trim();
            int dataAsInt=inData.toInt();
            if(dataAsInt>0 && dataAsInt<360 buffer="" clear="" dataasint="" delay="" indata="" myservo.write="" nop="" pre="" recieved="" serial.println="">
The Java app is based on the example from https://github.com/mik3y/usb-serial-for-android/tree/master/UsbSerialExamples but has a button with an onClick function with mSerialIoManager.writeAsync("10\n".getBytes());

Monday, 2 December 2013

Linking Android to Arduino

I've started our latest project (to be unveiled soon). It requires Arduino to receive commands from an Android device. It needs to be as light as possible, so ideally needs to be powered from the USB connection.

I've seen a number of solutions using Android ADK and special Arduinos, but this seems rather unnecessary. The problem seems to be the USB communication on either side, requiring USB sheilds (http://www.freetronics.com/products/usbdroid#.Upz8jx8hG1E). Alternatively there's Bluetooth (http://blog.arduino.cc/2013/07/18/how-to-control-arduino-board-using-an-android-phone/), but that would mean an external power source.

So instead, just use a Serial interface. There are Java libraries that can be used on Android. Everything including examples can be found here: https://github.com/mik3y/usb-serial-for-android

 I've hooked up my arduino Uno to an SIII using an A to B USB cable and OTG cable. It all works nicely. Stay tuned for what we're going to use it for ;-)

Thursday, 14 November 2013

How Many Apps are on my phone?

I've seen several people posting about how they have "over a hundred apps" on their phone. I don't think this is accurate. There are a lot of apps installed by default that the user doesn't see (and can't uninstall). Interestingly, I couldn't find a good way to display the total number of packages (apps), installed on a device using the GUI. You can list apps using Settings->Apps but this is incomplete.

Instead using a USB cable and ADB it's possible to get a clearer picture.
So the total number is more like over 300

Thursday, 19 September 2013

automated odex to dex script

When grabbing a new Android device, most applications' dex files have been optimised for the device. A few people have written a guide to using smali and baksmali in this situation (http://forum.xda-developers.com/showthread.php?t=1208320), but here's a handy script to do it all. You'll need smali.jar and baksmali.jar in the local directory when you run it.


echo "+------------------------------+"
echo "+                              +"
echo "+       mass de-odexer         +"
echo "+         TROTMASTER           +"
echo "+                              +"
echo "+------------------------------+"

mkdir BOOTCLASSPATH 2>/dev/null
mkdir tobedeodexed 2>/dev/null
mkdir deodexed  2>/dev/null
#clear out the previous contents COMMENT THIS OUT IF YOU ARE USING THE SAME BOOTCLASSPATH etc.
rm BOOTCLASSPATH/* 2>/dev/null
rm tobedeodexed/*  2>/dev/null
rm deodexed/* 2>/dev/null

#get bootclasspath files TODO:get only .jar files
echo "pulling boot class path files..."
adb pull /system/framework/ BOOTCLASSPATH/ > /dev/null 2>&1

#get odexes
echo "pulling .odex files..."
for i in $(adb shell ls /system/app/*.odex | sed -e 's/odex./odex/'); do adb pull $i tobedeodexed/$(echo $i|cut -d"/" -f 4)>/dev/null 2>&1;done

#Now run smali then baksmali to change odex to dex. may need -a to change api level
for i in $(ls tobedeodexed/*.odex);do rm -R out/ 2>/dev/null; echo baksmali-ing $(echo $i|cut -d"/" -f 2);java -Xmx1024m -jar baksmali.jar  -x $i -d BOOTCLASSPATH/; echo smali-ing $(echo $i|cut -d"/" -f 2);java -Xmx1024m -jar smali.jar -o deodexed/$(echo $i| cut -d "/" -f 2).dex out;done

Sunday, 8 September 2013

Settting the phone number in an android emulator

So this is another short post to help answer a question that the Internet seems to faff around with:
  "How do I set the phone number in an Android emulator?"

This was important for me as I have been producing a proof of concept app that relies on using the phone number as a way of identifying you. Rather hard if all the emulators are on the same number.

So as a result it appears that the following information can be used:
 - The number of the phone ends in the four digits relating to the port number that the emulator is listening on. So for instance when it's run on port 5554:


To change, you can run ./emulator -avd -port
There doesn't seem to be a way to set the port when using Eclipse's AVD manager, but they will at least start on incrementing ports from 5554 onwards so no chance of a collision.

Thursday, 5 September 2013

android adb - daemon still not runningerror: cannot connect to daemon

For people getting:

 
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
** daemon still not runningerror: cannot connect to daemon
 
 
Check your iptables!
if you are whitelisting INPUT on local interface, you'll get this error. You need to allow at least port 5037 through on lo.
 
Or if you're happy with allowing all input on lo:
sudo iptables -I INPUT -i lo -j ACCEPT


hope that saves you the hour I just wasted :-)

Friday, 19 July 2013

Android webview security loadDataWithBaseURL

A quick lesson in web views in Android. Normally they are a big risky area, be it adding JavaScript interfaces (http://labs.mwrinfosecurity.com/blog/2012/04/30/building-android-javajavascript-bridges/), or just generally enabling javascript and opening yourself up to webkit exploits (which given how little the OEMs update their firmware, is not hard to do).

So another interesting bit to concern yourself with is found on the following page's code:
http://www.androidsnippets.com/webview-with-custom-html-and-local-images

The code is as follows:

/**
 * This code loads a custom HTML from a string which references a local image
 * - for this to work, simply place the image in the directory /assets/
 */
 
public void loadHTML() {
    final String mimeType = "text/html";
    final String encoding = "utf-8";
    final String html = "

Header

Custom HTML "; WebView wv = (WebView) findViewById(R.id.wv1); wv.loadDataWithBaseURL("fake://not/needed", html, mimeType, encoding, "");

The problem is with the loadDataWithBaseURL's first argument. This defines how relative links on the page should be dealt with. Normally setting it to null or "" is enough, although this obviously produces invalid links. A better way is to use "file://android_asset". The problem with "fake:" is that if any other app registers for this custom url scheme, they will receive the link and start one of their activities.

Not a bad issue, unless the url has sensitive data in it right? Well as a malware writer, this is could still be useful. Imagine if this screen is part of the Facebook app and has a relative link on it, or has JavaScript that changes the window.location to a relative page. All the malware needs to do is dress the pop up screen in nice Facebook attire and ask the user to re-enter their creds. It doesn't even require the malware app to request any permissions from the user.

To fix it, just set the baseurl to null, or include a custom webview client (setWebViewClient)

Saturday, 20 April 2013

Beer fridge on the go




It's been a little while since my last post about the beer fridge so let's get you up to date. Since my last post:
1. My company has sponsored the fridge (so they'll pay for all the parts :-) )
2. We spent a Saturday getting to work on it.
3. It's not finished yet
4. I'm having issues with the MOSFEST/solenoid part


The basic design is as follows:
 A fridge will be locked from the inside by a set of solenoids acting as bar locks. The solenoids and the corresponding LEDs are controlled by an Arduino. The Arduino takes commands from a Raspberry Pi over serial and the Pi will have network connectivity.

 If you want to open the fridge, complete the fiendish hacking challenges on the Pi. Each challenge will control 1 or more solenoid. Unlocking the solenoid will only keep it unlocked for 30 seconds.

On the front of the fridge is a little black box. This has a set of red and green LEDs that will change whenever a lock is opened. There will also be (very importantly), a key lock that will bypass all challenges and power all the solenoids. This is because if (when) the pi or Adruino crashes, I still have a way to open the fridge. Otherwise it would be a matter of crowbar and damage.

fridge with the override lock
The next steps will be getting it in a working state. Currently there is only 1 solenoid (they are an absolute pain to mount correctly given the fridge's build and the small range of motion of the solenoid).

 I was thinking of having a Python script that sent the command over serial. The problems are that the exact serial port can change and also that writing to the serial port requires root permissions. I need to create a user to do this then Suid the python file (possible?).

 Finally it will be a matter of mounting it on the door. I'm a little worried that the condensation inside the fridge will screw with the electronics. Time will tell

Saturday, 23 March 2013

SQLite injection - beyond SELECT

I work a lot with mobile and that means whenever I see SQLinjection vulns, chances are that they're in SQLite. This is a massive pain because:
a) no-one really writes guides/tools for SQLite injection
b) It's really limited (as we'll see)

Unfortunately this post is about what is not possible in SQLite injection. Hopefully it will give you a guide to where to focus attacks/defence.

SQL injection as my previous post mentioned is a subset of regular SQL. There's no command execution, file reading/writing or anything particularly cool. You can't even stack queries unless the developer is using less orthodox functions (like rawquery). In essence it normally boils down to information disclosure (i.e. reading from tables that you shouldn't).

Select Statements in Mobile SQLite

With Android you (as the attacker) will hopefully be able to inject on 'projection' variable, that is the part that goes in the "SELECT ____ FROM". This obviously allows you to redirect the statement to go to anywhere else. The ideal test is to try projection=" * FROM SQLITE_MASTER; -- ". If you can get to the master table, you can get anywhere else (unless the programmer has some custom code ready to black list you out of having fun).
Failing this you could try on the 'selection' variable and try a union statement. (see my previous post for more details

This week has been spent looking at the other commands (insert,update,delete). The goal for the attacker is to change values in other tables in the .db file. The big issue here is the table to be queried is selected before your variables get included.

Inject into INSERT statements


insert into TABLENAME(field1,field2) values (val1,val2)
 
Here you can maybe control field1 & 2 and val1 & 2. The problem is that you can't jump tables. SQLite doesn't permit UNIONs or JOINs in anything other than select statements. You can use CASE to hide SELECT statments in the middle of this but that doesn't get you much in the way of altering data powers. You also can't use table.field in the query. Essentially you are stuck altering the data within that table.

It is therefore possible for SQL injection through inference of values being changed with CASE statements to read data from a table, but it's not possible to jump to and attack other tables.

 Inject into UPDATE or DELETE statements

UPDATE table SET (val1 = val2) WHERE condition
DELETE FROM table WHERE condition

Similarly the update query permits field names (val1), updated values (val2) and where clauses (condition), but no changing of the table name. The delete function is similarly limited.

I'm scratching my head finding a more useful attack vector that somehow nests more useful things inside statements. All comments are welcome. In the meantime, this should make for some useful reading: http://www.sqlite.org/syntaxdiagrams.html

Monday, 4 March 2013

Hacking Android dynamic Broadcast Receivers

An interesting point was raised this week when the subject of attacking IPC endpoints in Android applications was being discussed.
Attacking Endpoints is a method by which a malicious application on an Android device can communicate with, and misuse functions of other applications installed on the device. This can lead to anything from information disclosure to code execution.

To find these end points it's normally a matter of checking the application's manifest file (which can be recovered from the apk)

adb shell "pm list packages"
adb shell "pm path com.example.apptotest"
adb pull /data/app/com.example.apptotest-1.apk
aapt d xmltree com.example.apptotest-1.apk AndroidManifest.xml


This process (which can be sped up with mercury), gives you a whole list of text which allows you to identify which of these end points are exported either on purpose or otherwise, and which have permissions.

This gives us a list of things to look at in code, but I believe we are missing a step here. This assumes that these are the only end points we can talk to. Obviously some require permissions that we as a malicious app might have ourselves by just asking the user for it, but for this instance the malware will have zero permissions.

It is possible to register a broadcast receiver dynamically, typically by doing the following:
registerReceiver(BroadcastReceiver myreceiver, new IntentFilter("android.some.THING"))

This is fine, and often required to listen out for an event on a device. There are 2 things that can go badly wrong here though. First if the broadcast filter is listening for an intent that isn't a restricted broadcast then the malicious app can start sending them without needing any permissions. Secondly if the receiver goes on to use the extras sent with the broadcast, or to start running other functions, then the malware has a whole new entry point to your application. Of course it would require the malware to send the broadcast at the right moment, but hell just have it send the broadcast every second and run all the time.

To protect your broadcast, you need to register permissions when you declare it (details here), secondly don't trust the data that is being sent with it. It's passing through a trust zone to arrive in your app, so validate it! Details on Android permissions can be found here.