The Mossad 2019 Challenge - Part 1
The 4th Mossad’s challenge for Israel’s independence day begun in 8th of May, 2019. Like the previous challenges, it requires some research and some “out of the box” thinking. In the following article(s), I will go through all 3 challenges and explain my solutions.
The challenge begins in this URL: https://r-u-ready-4.it/
This picture is basically a binary pattern with the Mossad’s logo. If we convert them to decimal, we’ll get the 4 octets of presumably, an IP address.
After visiting 35.246.158.51, we’ll be redirected to the first challenge:
The webpage provides us with an .APK file. .APK (Android Package File) is the file extension for Android apps, and it’s in standard zip format. It’s important to not just extract the file like a zip, because it contains Android Binary XML files, which you would just need to decode manually. In this case we’ll use apktool to disassemble the APK.
After extracting the files, we’ll look at AndroidManifset.xml
. This xml contains valuable information, such as the package name, permissions, and more.
We can see a few important hints here:
- The app uses the internet permissions. This is a strong hint that the app is contacting some remote server.
- The “look for us on github.com” hint.
- The app is a Flutter application. Flutter is Google’s mobile app SDK.
- The app is debuggable. That’s a strong hint this APK was built in debug mode, and we can extract code or important symbols from it.
A quick overview on Flutter.
Flutter is used to develop native apps. Flutter apps are developed in the Dart programming language - also developed by Google.
When you build a Flutter app, the Dart kernel (“an intermediate language for Dart programs”) takes your Dart code and creates kernel bytecode.
That bytecode is usually saved in the kernel_blob.bin
file, which we’ll look at now.
In the assets/flutter_assets/
folder, we can find the kernel_blob file. By running strings
on it, we can view the source code directly.
Here’s an interesting portion of the code:
Looking at this code, we can infer that a request is being sent to http://35.246.158.51:8070/auth/getUrl
to retrieve the authentication URL,
and then an additional POST request is sent with a JSON containing a seed and a password.
Let’s try that:
Interesting. So what we know so far is that in order to authenticate, we need to give a valid seed and password. The server returns Time
which is probably the time taken to process the request.
The time hints that this server is vulnerable to a timing attack.
Timing attacks?
To put simply, these are attacks where the attacker analyzes the time taken to process something based on the input given. Let’s assume the server compares each character in the password, byte by byte in a loop, and breaks when a character is incorrect. This will mean that the more correct characters you have in the input, the longer the server takes to process your request. Then, you can bruteforce all characters and measure the time, and see which characters take longer - and you can assume they are correct.
So, after playing with the /auth/v2
endpoint for a while, I could see the returned time is pretty much inconsistent, and a timing attack wouldn’t work on this endpoint.
Let’s go back a bit, remember the “look for us on github” from the manifest? By searching for “iwalk” on github, we can find an interesting user: iwalk-locksmithers-app
The user has a “server” repo which contains the source code for the server.
By looking at the code, we can see that there’s an /auth/v1_1
endpoint available, only if we set our User-Agent
header to ed9ae2c0-9b15-4556-a393-23d500675d4b
!
Let’s see if it’s working in the remote server:
Let’s look at the password check code for the /auth/v1_1
endpoint:
So it seems like the code sleeps for 30ms for every correct character we hit. Also, it checks the string up to the length of the password, so even if the password is “1234”, the password “123456” would work as well. We now know that we can perform a timing attack on this endpoint. However we still need the seed. Remember the beginning of the challenge where we were given a ‘client id’? We’ll use this as the seed.
In this example script, you bruteforce the password with the character set of lowercase letters and digits (originally I used all letters and special characters too, but I changed it after observing the pattern of the password). We convert the Time
from nanoseconds to milliseconds, and add the character to the current_password
if there’s a 25ms or more difference between the two.
Visiting the URL completes the challenge: