CyberTruck Challenge 2019 — Android CTF
CyberTruck Challenge 2019 is a premier event to bring together a community of interest related to heavy vehicle cybersecurity issued and develop talent to address those challenges. This is a write up for their CTF. Their website can be found here and the Github profile for the challenge can found here.
Note: I was not present during the event. All I wanted to do was practice Android CTFs and that’s when I came across their Github page.
Tools used
Challenge description
A new mobile remote keyless system “CyberTruck” has been implemented by one of the most well-known car security companies “NowSecure Mobile Vehicles”. The car security company has ensured that the system is entirely uncrackable and therefore attackers will not be able to recover secrets within the mobile application.
If you are an experienced Android reverser, then enable the tamperproof
button to harden the application before unlocking your cars. Your goal will consist on recovering up to 6 secrets in the application.
Preparing for the CTF
Installing the app
Using adb to install the app on the phone.
adb install cybertruck19.apk
Decoding the app using ApkTool
Decode the APK using Apktool and output it into cybertruck-smali
folder.
apktool d cybertruck19.apk -o cybertruck-smali
Converting the apk in .jar format using dex2jar
I converted the .apk to jar because then I can use JD-GUI to see Java source code.
Using JD-GUI, we open the cybertruck.jar
created by the dex2jar (previous command).
Launching the app
As soon as we launch the app, we get this image.
So we try to understand what the unlock button and toggle buttons do.
Challenge #1
Challenge1 to unlock car1. “DES key: Completely Keyless. Completely safe”
To figure out what activity is being launched, let’s take a look at AndroidManifest.xml
So, using JD-GUI
to take a look at the source code of MainActivity.class
Looking at the onCreate
function, we find the Unlock button. On clicking the unlock button, it calls this.b.k()
. So we further investigate.
The function creates an instance of class Challenge1
. So we take a look at Challenge1.class
Static Flag for challenge1 is s3cr3t$_n3veR_mUst_bE_h4rdc0d3d_m4t3!
For dynamic flag, we will have to find a way to get the value returned by generateDynamicKey
function in the runtime. These are exactly the scenario where Frida comes in handy. You can learn more about Frida from their official documentation.
generateDynamicKey
returns a byte array. The byte array is stored in variable result
which we forward it python function on_message
. Here we convert byte array to string.
Capturing Dynamic flag
The dynamic flag is 046e04ff67535d25dfea022033fcaaf23606b95a5c07a8c6
Challenge #2
Challenge2 to unlock car2: “AES key: Your Cell Mobile Is Your Key”
Going through the this.b.k()
function in MainActivity.class
Instance of class a
is called. Let’s investigate further.
So we have class a
with constructor a
and two functions with name a
.
While declaring constructors, you do not have specify the return value. So public a(Context paramContext) is the constructor and the rest are functions.
So this file contains:
Anyways, coming back to constructor a, it calls a(Context paramContext)
and then its returned value is then passed as one of the arguments in a(byte[] paramArrayOfbyte1, byte[] paramArrayOfbyte2)
So we take a look at function a(Context paramContext)
File ch2.key is opened. So we take a look at its contents.
The value of static flag for Challenge2 is d474_47_r357_mu57_pR073C73D700!!
Now let’s take look at function a(byte[] paramArrayOfbyte1, byte[] paramArrayOfbyte2)
For dynamic flag, we will need to use Frida again to capture the returned value of this function
The dynamic flag for Challenge2 is 512100f7cc50c76906d23181aff63f0d642b3d947f75d360b6b15447540e4f16
Challenge #3
Challenge3 to unlock car3. “Mr Truck: Unlock me Baby!”
Challenge3 description: There is an interesting string in the native code. Can you catch it?
Inside MainActivity.class
, this native-lib.so
is loaded.
The static flag for this challenge is Native_c0d3_1s_h4rd3r_To_r3vers3
For dynamic flag, it depends upon on your device’s instruction set. In my case, it was arm64-v8a
which requires you to be able to understand assembly language instructions for the same. Which seems to be out of my league (..yet!).
How to bypass Tamperproof check?
This function returns true if there is frida server is present and false otherwise. So we use Frida to overwrite this function’s return value
So that’s my solution for this CTF. I am still new to CTFs and have a lot to learn yet. Still this CTF was a good learning opportunity. Hope you also learned something.