Modifying Android Apps: A SEC575 Hands-on Exercise, Part 1

By Joshua Wright

Blog1

 Introduction

As a security professional, I’m called on to evaluate the security of Android applications on a regular basis. This evaluation process usually takes on one of two forms:

  • Evaluate app security from an end-user perspective
  • Evaluate app security from a publisher perspective

While there is a lot of overlap between the two processes, the difference effectively boils down to this: whose risk perspective does my customer care about the most?

When an app publisher wants me to evaluate the security of their Android app, I need to determine if the app employs sufficient controls to protect the required app functionality and publisher brand. Often, this requires me to identify critical app components (critical for my customer, such as how they make revenue from the app, or the integrity of the data transmitted by the app), and determine if I can manipulate them in interesting ways.

As a guide, I developed an Application Report Card system to steer an analyst through the application evaluation process. One of these tasks is to manipulate the Android application by modifying the low-level Smali bytecode, removing the intended publisher functionality.

Blog 1a

In my SEC575: Mobile Device Security and Ethical Hacking course, we use a custom application, IsItDown as our evaluation target. In the exercise, participants have to install and run the application to identify the app functionality and constraints, then decompile, modify, reassemble, and re-sign the application so the app can be used without restrictions.

In this 2-part article, we’ll take a peek at the SEC575 hands-on lab exercise for modifying Android apps. In the first part, we’ll take a look at how we can leverage the Apktool utility to decompile an Android app, followed by a quick primer on reading Smali code. In the second part, we’ll generate custom keys to sign the modified application so that it can be used on a virtual or physical Android device, and look at defense techniques.

Feel free to download the IsItDown application and follow along. You’ll also need the following tools for your system:

Evaluate the App

Blog2

After starting a virtual Android device (or connecting your physical Android device over USB), use the adb utility to install the IsItDown.apk application as shown above. Next, run the app and experiment.

IsItDown is a basic IsItDownForJustMeOrForEveryoneElseToo app… except it’s only testing from your mobile device. Frankly, it’s not that useful, but it serves our needs fine.

If you are working from a virtual device, you’ll quickly be disappointed. Not only does IsItDown have an obnoxious banner ad on the bottom of the page, it only teases you with the promise of functionality before it tells you to go away.

Blog3

Our goal here is modify the Android application to allow us to run in the Android Emulator, and to remove that annoying banner ad.

Decompile the App

First, we’ll use Apktool written by Ryszard Wisniewski and Connor Tumbleson to convert the IsItDown.apk file into Smali code. Smali code is a representation of the app code using the Android Dalvik opcodes – essentially an intermediate representation of the code between the original Java source and the processor-specific assembly instructions. Apktool allows us to take the Android APK file, convert it into a Smali source representation that can be modified, and then recompile it back into a new APK file.

Note: The pedantic reader will no doubt be questioning my use of “decompile” as a verb here. Converting an Android APK file to Smali code is not quite decompilation, but it’s not quite disassembly either. It’s somewhere in the middle. I’ll keep using decompilation, since you are getting a high-level representation of the app code in the Smali file, but if you are more comfortable with the decompilation verb, feel free to search+replace this article.

Apktool isn’t so much a hacking tool as it is a mechanism to evaluate Android applications. Sure, people with ill intent can manipulate an application for evil purposes, but it can also be used for Android application troubleshooting, and for the localization (adding local language support) for applications as well. Don’t use it to do evil things, OK? (Ed.: I second that.)

Blog 2a

Make sure you have apktool.jar (renamed from apktool-2.0.0.jar), apktool.bat and IsItDown.apk all in the same directory (or put apktool.jar and apktool.bat in your system PATH somewhere). Next, use apktool.bat to decompile the APK file, as shown here:

Blog 4

Apktool will generate a new directory IsItDown that holds the application resources, AndroidManifest.xml declarations, the original signature information from the developer, and the Smali code itself.

apktool-d-explorer

Modify the App

Browsing to the smali directory, we’ll see a directory structure created for the application package names (e.g. com/willhackforushi/isitdown/). For our simple application, only a handful of Smali files are generated, as shown here:

Blog 3a

Most of these Smali files include auto-generated code, so we don’t have to look through all of them. First, let’s search for a reference to the string “No emulator use permitted.” using the Windows findstr.exe utility:

Blog 4a

Here we see the string is in the MainActivity.smali file. This is unusual; typically, string values will be defined in the res/values/strings.xml file, making it easier to localize the application. Here, the developer just got lazy, and embedded the string directly in the Java source. This makes it a little easier for us to evaluate the Smali code though: simply open the MainActivity.smali file with your favorite editor and skip to the line where the string is defined.

Blog 6

At this point, if you’re not a developer, or have never seen Smali code before, you might be like “WTW? I’m supposed to read this?”. Have no fear! You just need to know a few things about Smali:

  • Smali uses declared registers as placeholders for objects, variables. v0 is a local register, p0 is a parameter register (e.g. something passed to the function/method)
  • Syntax in Smali is always destination, then source
  • Object types are specified with a capital letter at the end of the object or method:
    • V – Void
    • Z – Boolean
    • B – Byte
    • S – Short
    • C – Char
    • I – Int
    • J – Long (64-bits)
    • F – Float
    • D – Double (64-bits)
    • L – Object

A cheat sheet is a useful thing to have as well, that explains common Smali opcodes and their functionality. Here’s one from my SEC575 course!

Blog 8

Finally, the reference maintained by Gabor Paller at http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html is awesome, and frankly, is how I learned to read Smali code. You should bookmark that link!

Looking at that Smali code, there is a lot of stuff we don’t care about. We know that the application shows us an error “Go away” and refuses to run. Logically, before that message is displayed, we should see some code that determines whether or not to display that error. Sure enough, check out line 350:

Blog 9

Line 350 invokes a method calls isEmulator() which returns a Boolean value (see the big “Z” at the end?). The Boolean result is moved to the v13 register, and then the if-eqz opcode  determines if the value is 0 (or “False”). If v13 is equal to 0, then the code jumps to the code_0 block. Otherwise, we get the nasty “No emulator use permitted.” message.

Not so hard, right? Knowing this, we can make a simple change to this code. Consider this small “fix”:

Blog 11See what I did on line 354? I changed if-eqz to if-nez, effectively inverting the test. Now, even though isEmulator() still returns True on emulated devices, the code behaves as if it the device were not an emulator, jumping to the cond_0 block.

This is not completely desirable, since this change would invert the test, and break the functionality for legitimate devices that install the modified IsItDown.apk file. You could modify the isEmulator() method to always return False as another option, but this is what I ended up doing:

Blog 12

On line 354 is the original if-eqz test, and then I added the inverted test immediately afterward. This way, regardless of what the isEmulator() method returns, the code always skips the “No emulator use permitted” message. It’s a little hackish, but it gets the job done. (Ed.: Did Tom Liston teach you that, Josh?)

Next up: removing that banner ad. Banner ads are usually displayed in a WebView object, which is effectively a little tiny web browser in the app. Searching for the string “http:” reveals two references that look like the source of our advertising:

Blog 13

Searching for that same string in the MainActivity.smali and MainActivity$1.smali files reveals code like this:

Blog 14

In this example, line 268 loads the reference to the WebView in the v2 parameter, while line 270 loads the ad URL in the v3 parameter. Line 272 loads the URL content into the WebView. Easy enough to change that behavior:

Blog 15

Simply commenting-out the invoke-virtual opcode that fills the WebView is enough to cause the banner ad to stop loading. Repeat this step for both MainActivity.smali, and MainActivity$1.smali and you’re done!

Concluding Part One

In this first part of our article, we saw how Apktool can be used to decompile an Android application, and looked at the Smali code with a focus on changing the code to overcome Android emulator restrictions and to disable an annoying banner ad. In Part Two we’ll pick up where we left off and re-build the application and sign it with the Java Development Kit utilities so we can run the modified app on an emulated or real Android device. Finally, we’ll address defensive techniques that you can use in your next Android pen test report with suggestions to pass on to Android developers, and briefly discuss how Android testing can also be useful when evaluating iOS targets.

Until next time,

-Josh

 

Upcoming SANS Special Event – 2018 Holiday Hack Challenge

KringleCon

SANS Holiday Hack Challenge – KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • “On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team.” – @mikehodges
  • “#SANSHolidayHack Confession – I have never used python or scapy before. I got started with both today because of this game! Yay!” – @tww2b
  • “Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa” – @dnlongen
kringle_02

Traffic Lights and Modbus/TCP – A SEC562 CyberCity Hacking Adventure

By Joshua Wright

Blog1

When the Counter Hack team started building the SEC562: CyberCity Hands-on Kinetic Cyber Range class, I knew I wanted to develop a mission that involved the Industrial Control protocol Modbus/TCP and traffic lights. Because CyberCity is 1:87 scale, I needed to build my own traffic light controller using Modbus/TCP with model-sized traffic lights, and connect them to a Modbus/TCP powered controller.

Traffic light

Part of our goals in writing the SEC562 course is to provide hands-on experience understanding the security of ICS protocols such as Modbus/TCP, CIP, PROFINET, DNP3 and others. This is done through the completion of several missions, where the team of analysts has a defined goal, and has to use offensive or defensive skills to achieve the stated goal. In the case of the traffic light mission, the team has to hack their way into the CyberCity Department of Transportation (DoT) network, pivot from publicly accessible systems to restricted access systems, and use the compromised host to deliver custom a Modbus/TCP exploit that manipulates the traffic light patterns.

I’m biased, but I think these missions are SUPER FUN. Challenging, for sure, but a great opportunity to learn about a whole new realm of interesting protocols (ICS and related technology) that allow you to use hacking to interact with the kinetic world, manipulating systems that move or control things that move (like… traffic lights!). The class itself is 80% hands-on, 20% lecture, so you spend much more time DOING than listening… and falling asleep after eating too much lunch (been there).

In this article, we’ll take a peek at the Traffic Control CyberCity mission. I’m not going to give away everything, but we’ll take a look at how we can combine useful reconnaissance and information gathering, web attacks, privilege escalation, pivoting, and Modbus/TCP exploits effectively.

CyberCity Scoring Server

cybercity-night-wide

In the SEC562 class, we don’t just give you a target, shrug, and say “figure it out”. It’s not a good use of your time. Instead, we provide a well-tested environment using the NetWars Scoring Server, that identifies the mission and asks questions in a sequential order that guide you through the mission steps. If you get stuck on a question the automated hint system brings you a little bit closer to the answer with each hint. This way, you can work at your own pace: figure out small portions of the mission on your own, or use hints to get extra assistance where desired. When you answer a question correctly, you get all the hints automatically, just to validate your technique with what we planned for the mission.

Blog2

Let’s jump in and start answering some questions.

Reconnaissance

Blog3

Like any penetration test, you’ll conduct reconnaissance analysis and information gathering before evaluating the target systems for vulnerabilities. For example:

Leverage the FaceSpace site (facespace.co.nw) to identify three employees working for the CyberCity Department of Transportation. Enter the last name of the DoT employee whose name ends in “be”.”

FaceSpace is our social networking site within CyberCity, complete with thousands of accounts and posts from various CyberCity citizens. FaceSpace is built on the Elgg open-source social networking software, acting both like Twitter and Facebook. Like other social networking sites, FaceSpace is a wealth of sensitive data that is useful for reconnaissance analysis including the disclosure of username information, “friend” associations to identify co-workers, and other sensitive data. Searching for various on “department of transportation” and “DoT” turns up some interesting results.

Blog4

Blog5

Looks like Jermaine Strobbe is a new hire for the DoT, and the answer for our question. Let’s move on to some scanning and information gathering.

Scanning

Blog6

Later in the mission, we start getting questions like this one:

“Additional informational resources about the structure of systems and traffic light control protocols are stored in non-guest accounts on the filebox.dot.city.nw site. Access these protected resources and identify the model number for the traffic light controller used by the Cyber City DoT. Enter the numeric portion of the traffic light controller model number.”

The filebox.dot.city.nw site is used for sharing public resources – it’s the CyberCity version of ownCloud or other cloud storage providers and based on a private cloud system that I got to evaluate for a customer penetration test not long ago. When you visit the site, several files are accessible to guest users as shown here.

Blog7

When I mouse-over the link for any of the files, I see URLs that look like this:

http://filebox.dot.city.nw/Z3Vlc3QK/Event%20Permit.docx

This looks like a classically bad URL scheme, where the files are in a random-looking directory. Browsing to the directory itself, we get the following:

Blog8

So, we know we have a directory browsing issue, but we want to get access to other user’s files on this same system. We could mount a password guessing attack against the login screen, but that could take ages and might lock-out user accounts. If we focus on the unpredictable directory portion of the URL, we see the string Z3Vlc3QK. Browsing to small variations on this string only returns 404 errors from the server.

Pasting the value into Burp Suite, we can use the Decoder tool to evaluate how the string decodes in several ways. Most of the options don’t apply (e.g. “Z3Vlc3QK” is not URL, HTML, ASCII hex, Hex, Octal, Binary, or Gzip encoded), but the Base64 option looks interesting. Using Base64 as a decode option, and we see the encoded value returns the string “guest”.

However, we can try different decoding methods to further analyze this content. While the string could just be random lower/upper alphanumeric values, let’s try different decoding options.

Pasting the value into Burp Suite, we can use the Decoder tool to evaluate how the string decodes in several ways. Most of the options don’t apply (e.g. “Z3Vlc3QK” is not URL, HTML, ASCII hex, Hex, Octal, Binary, or Gzip encoded), but the Base64 option looks interesting. Using Base64 as a decode option, and we see the encoded value returns the string “guest”.

Pasting the value into Burp Suite, we can use the Decoder tool to evaluate how the string decodes in several ways. Most of the options don’t apply (e.g. “Z3Vlc3QK” is not URL, HTML, ASCII hex, Hex, Octal, Binary, or Gzip encoded), but the Base64 option looks interesting. Using Base64 as a decode option, and we see the encoded value returns the string “guest”.Blog10

Seeing this, we can use our earlier reconnaissance data of username information for directory path guessing attacks to bypass authentication to access other user cloud files. You can do this manually, or a little shell script can speed things up:

jwright@ccgateway2 ~ $ for username in jstobbe bstobbe jdesoto bdforge rgray ; do
> enc=`echo -n $username | openssl enc -base64` # -n very important here!
> curl -sL -w "%{http_code} %{url_effective}\\n" http://filebox.dot.city.nw/$enc -o /dev/null
> done
404 http://filebox.dot.city.nw/anN0b2JiZQ==
404 http://filebox.dot.city.nw/YnN0b2JiZQ==
200 http://filebox.dot.city.nw/amRlc290bw==/
404 http://filebox.dot.city.nw/YmRmb3JnZQ==
404 http://filebox.dot.city.nw/cmdyYXk=

Here, we see mostly 404’s, but one wonderful 200 indicates that we found another encoded directory that was previously hidden from us. Skipping to the pillaging phase, we retrieve all the files in the directory and evaluate them to learn more about the target system. Among other things, we learn that the traffic light system used by the CyberCity DoT is a product from Traffic Control Systems (TCS) that includes an extended Human-Machine Interface (HMI) that allows for online reporting of traffic data. We can further validate that by browsing to the www.dot.city.nw website, shown here.

 

Blog11

Looking at the page source, we find another interesting target to explore:

Blog12

Exploitation

Blog13

 

Jumping ahead a little bit, we can explore the hmi.dot.city.nw target. What we find is a straightforward login page, asking the user to enter credentials for the product management console. If we try to authenticate with a guessed password for a DoT employee, we get an error from the server.

Blog14

Blog15

When we fail authentication, we get a <div> on the page letting us know. However, the URL now has a new parameter: msg=loginfail.html.

NOTE: Anytime you see anything that looks like a filename in the URL, try to use the parameter to access other files on the system! Even though it’s 2015, it still happens all the time. Here too, we have a straightforward Local File Include (LFI) issue that allows us to read files outside of the web root:

Blog16

However, the web user is limited to read files owned by www-data, or with “world” read permission. This limits our ability to get additional access on the target system (e.g. we can’t read the /etc/shadow file, and start password cracking). SEC562 participants have to leverage a second vulnerability to get files uploaded to the target system and then include those scripts in the LFI to gain a shell on the target.

Pivoting

Blog17

Once we get basic shell access to the hmi.dot.city.nw box, we can start to pillage the host for information, and use it as a pivot point to attack downstream systems including the individual Modbus/TCP traffic light controllers. Here’s what we find out through pillaging the host:

  • Target OS is Ubuntu 12.04.4 LTS
    • Host has a public interface on the 10.21.12.0/24 network at 10.21.12.11.
    • Host has a second private interface on the 10.21.22.0/24 network at 10.21.22.11.
  • PLCs for traffic light controllers exist at 10.21.22.21, 10.21.22.22, 10.21.22.23, and 10.21.22.24
    • All PLCs are listening on TCP/502 for Modbus/TCP connections
  • TCS traffic reporting software runs from /opt/b2b/lightstatus

Using the cameras that monitor CyberCity in real time, and packet capture data from the traffic light controller PLCs, we can gain some insight into how the Modbus protocol is configured to control the traffic light patterns.

Blog18

Here, the master device (the Ubuntu box at 10.12.22.10) is transmitting a “Write Multiple Coils” message to the target device at 10.21.22.23. In Modbus, a coil is a binary value (on or off), while a register is an analog reading (from Y to Z). Modbus lacks any kind of authentication, encryption, or integrity protection; clearly, this was a protocol that was not written to be used on the same network as a hostile adversary. (Ed. understatement of the year)

While some Modbus/TCP attack tools exist, I typically find it is easiest to build what I want with a quick Python script instead of adapting a different tool for a specific task. First, we can experiment with setting all the bits to the ON position with:

Joshuas-MacBook-Pro-2:~ jwright$ cat lightmanip.py
#!/usr/bin/python
from pymodbus.client.sync import ModbusTcpClient
from time import sleep
import sys
 
i=0
while(i < 30):
    client = ModbusTcpClient(sys.argv[1])
    client.write_coils(0, [True, True, True]*4) # Ref #, followed by coil settings in list form
    client.close()
    sleep(1)
    i+=1
print "Done"

Here, the list element [True, True, True] represents the Red/Yellow/Green lights, repeated 4 times for the North, South, East, and West directions. When we run the script with the IP address of one of the PLCs, it should change all the traffic lights to the on position.

python lightmanip.py 10.21.22.21 
Done

Viewed through the traffic light reporting page, we see something like this:

Blog19

This view only shows a single light on for the Quadrant 1 traffic lights (all red). This could be because the monitoring software doesn’t have the logic to keep testing for other lights to be set (since that shouldn’t happen in practice). Viewed through the CyberCity camera, we see a different picture:

Blog20

It’s a little hard to tell because the LEDs are so bright, but all 12 LEDs are shining strong because of our tool. Now, it’s a simple matter of correlating the traffic lights to the individual IP addresses, and updating the script to manipulate each traffic light per the mission directive.

Conclusion

Blog21

In this article we looked at some of the techniques used in the SEC562: CyberCity Hands-on Kinetic Cyber Range Exercise. For an attacker, the world of Industrial Control Systems opens up a lot of attack opportunity, both from the ease with which these protocols can be exploited, and the kinetic impact an attacker can produce. Learning about these attacks expands your skillset both as an attacker and as a defender (and, we get to have a lot of fun in the process).

-Joshua Wright

 

Upcoming SANS Special Event – 2018 Holiday Hack Challenge

KringleCon

SANS Holiday Hack Challenge – KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • “On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team.” – @mikehodges
  • “#SANSHolidayHack Confession – I have never used python or scapy before. I got started with both today because of this game! Yay!” – @tww2b
  • “Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa” – @dnlongen
kringle_02

The work “Main St Lights” is a derivative of “US Route 6 (2)” by Nicholas A. Tonelli, used under CC BY. “Main St Lights” is licensed under CC BY by Joshua Wright. All other images copyright Counter Hack, Inc., All Right Reserved.