For the past week, I have been slowly and steadily enjoying a new CTF website, TargetPractice. I finally completed their Android crypto/reverse-engineering challenge, Dead Drop, and wanted to share my workflow and experience with this fun exercise.

Warning: This is a complete write-up and will contain spoilers and solutions.

To start, I did a dry run of the application to see what its all about.

It is a simple 6-digit pin code blocking entry to whatever the next component of the application is. Its likely that we can just circumvent this and see whats next, so lets decompile the apk file and start poking around.

The first thing I like to do with decompiled Android code is pull all of the strings out and search for interesting tidbits. I found a URL when searching for http connections.

I decided to monitor the applications network traffic and see if that connection gets made before or after entering a pin.

> emulator @Pixel_2_XL_API_28 -tcpdump C:/dev/TargetPractice/emulator_capture.cap

Sure enough, there's an exchange. The application sends an RSA public key and the server responds with an encrypted PIN and encrypted flag.

Okay, lets take a look at where this public key is being generated. To do this, I want to see the flow of code when the application is launched, and also when a pin is attempted. I used my personally developed live debugger to monitor which java methods were being called while the application was being run. The Dead Drop app appears to have been coded in kotlin, but both java and kotlin are converted to the same dalvik instructions. The application launch looks like this:

and the PIN attempt looks like this:

There's a lot going on here... but one thing that immediately caught my eye was the repeated writePrivateFile() method. I took a look at the code for it and it takes two strings as parameters. One can assume that they'd be file name and data. I used my debugger to output the arguments and restarted the app.

Sure enough, it writes a public key and a private key that it must have generated as well as the encrypted pin and the encrypted flag that it received from the server. At this point, it might be possible to just decrypt the pin or flag and be done with it but I tried for a long time and was unsuccessful. I decided to return to my original goal of just bypassing the pin screen. When further examining the method trace of entering a pin, I noticed that something was being decrypted via AsymmetricEncryption.decrypt(). Lets log the result of that function every time it is run:

Well what do you know.... There's the pin! And using it brings you straight to a screen with the unencrypted flag! Success!

Big thanks to TargetPractice for this challenge. It was definitely a fun CTF and I look forwarding to completing their others!

In this quickstart guide, we will be learning about the role of object deserialization in security. Deserialization is featured in most major languages and when implemented improperly, either by the language itself or by the application being written, can be a fruitful attack surface. CVE-2017-5941 is an example of flawed implementation of deserialization in the node.js JavaScript framework.

What is Object Deserialization?

Understanding deserialization requires a basic understanding of object-oriented programming. Most modern programming languages allow for improved efficiency by using the concept of an object. The basic structure of an object is programmed, including its functionality and any details that can vary, just once (into what is called a class). This code can then be re-used when multiple versions of this object are needed, ultimately improving efficiency. There are many more benefits to using objects that don't need to be covered for exploring deserialization. If object-oriented programming is a new concept to you, it can help for this guide to think of an object as a filled out form. The software application can print off as many forms as it wants, and fill them out differently.

Deserialization is the act of reversing serialization. Serialization is a complex type of encoding. Much like we base64 encode URL parameters and cookie data, programming languages serialize objects so that they can be transported under constraint. When receiving a serialized object, a programming language or application will process it and convert it back into an object in memory. This is where things can go awry.


CVE-2017-5941 is a deserialization exploit in the node.js JavaScript framework. Node.js is used very widely across the web in modern web applications, and any version that has not been patched and utilizes deserialization is susceptible to attack.

CVE-2017-5941 takes advantage of the conversion moment in deserialization, where the serialized object has been processed and is being put into memory. It does this by serilaizing an "immediately invoked function" into the object.

Immediately Invoked Functions

JavaScipt syntax includes a way to call a function at the same moment it is defined. The syntax is simply appending two parenthesis, "()", after the definition. Example:

alert("I am an example function!");

Now lets draft a function that we might want to execute on a target:

require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });

Exploiting CVE-2017-5941

So we know that code can be executed when a function is defined, but its not ever supposed to be the user's role to define functions. Javascript, however, allows functions to be placed inside regular variables. If a web application is serializing user input as a variable (this could be as simple as a variable called first_name that takes a value from a form field), we can modify the data transmission to send an immediately invoked function with our payload instead of the expected value type for the variable.

However, it is important to realize the role of deserialization at this point. Simply sending an immediately invoked function to a server won't accomplish anything. If the payload isnt deserialized, it never gets treated with the respect of "real code". Much like cross-site scripting, or injection attacks, deserialization exploitation is the result of unintentionally running user input as functional code. However, unlike cross-site scripting or injection attacks, this capacity is a necessity. The entire purpose of deserialization is to transport code and data that is intended to be re-entered into the application as functional code.


This truly unique ability to leave and enter your programming language's interpretation layer is what makes serialization/deserialization in all languages worthy of investigation as an attack surface. Many major languages have had deserialization exploits and there are likely to be new and creative ways to break this system in the future.


For this project, I have compared the effectiveness of various feature sets from League of Legends (LoL) game data in classification tasks. Data for individual LoL matches were scraped from the North American match history servers. A decision tree, k-nearest-neighbors model, and multi-layer perceptron neural network were each configured and tested on their ability to identify player ranks when presented with game data. I used 13 different feature sets with each classifier and compared the results. The neural network always outperformed the other two models and the best feature set was the creep score intervals, gold earned intervals, and vision ward placement/destruction. The worst feature set was the losing team’s KDA by itself.

Read Paper

In this guide, we will take a look at a few exploits that target remote keyless entry (RKE) systems in modern vehicles. We will learn the theory behind the generic rolljam attack and also implement a specific attack on Subaru vehicles. Read Guide

"What's the wifi password?" is today's "Where is the bathroom?": the first question asked by guests of an unfamiliar location. I myself have asked this of many friends and this past week had noticed a security weakness in their routers. For those using NETGEAR brand routers, there is a simple pattern within the default WPA2 passwords that increases viability of WPA2 hash cracking. Read Guide

ReDroid started as an apktool wrapper and became a simple workspace tool for Android disassembly projects. It automates disassembly and reassembly of apps via Smali, allows for branching, and automates the signing and installing of recompiled apk files There's still a lot of work to do, and I will continue to update occasionally while I continue my DHS assignment. ...continue reading "ReDroid v0.7 Release"

In this guide we will observe one of Java's most dangerous vulnerabilities, CVE-2012-1723. We will analyze the conditions of the vulnerability and work through an example of practical exploitation through a drive-by attack. Read Guide