Whoami
Source
https://cybertalents.com/challenges/mobile-security/whoami
whoami
This challenge has 2 distinct solutions actually,
the first one is by using
Frida
to bypass root detection, then swapping the two activitiesthe second is by extracting the
JNI
libraries and using them in our own app (this solution is kinda sneaky and I don't think this is how the challenge was intended to be solved)
So let's begin.
Gathering information
By using Jadx
to reverse-engineer the APK after downloading it, we get its source code.
Reading AndroidManifest.xml
<activity android:name="com.cybertalents.ohmyroot.FLAGbox"/>
<activity android:name="com.cybertalents.ohmyroot.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
It appears that we only have 2 activities with only one activity being exported as the MAIN
activity, and the second one isn't exported at all, meaning that we cannot reach it from outside normally.
Reading the MainActivity
, we are introduced to this code.
super.onCreate(bundle);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.sample_text);
if (Boolean.valueOf(new IsRooted().IsDeviceRooted()).booleanValue()) {
textView.setText("Try Harder");
} else {
textView.setText(stringFromJNI());
}
}
Reading the code we conclude that the activity is calling some class named IsRooted()
and calling a method IsDeviceRooted()
. By their names, it looks like a root-detection mechanism.
Reading the class content and focusing on the IsDeviceRooted()
method, we notice that it returns a boolean
public class IsRooted {
// --- snip --- //
public boolean IsDeviceRooted() {
return detectTestKeys() || checkForSuBinary() || checkSuExists() || checkForBusyBoxBinary();
}
// --- snip --- //
}
This looks like an easy mechanism to bypass, so the first thing we do is fire up our trustworthy rooted emulator, then inject a frida
agent inside our target application using objection patchapk -s whoami.apk
, install it via adb
, open the application, then start the frida
client using frida -U oHmyRoot
.
In my emulator the root detection didn't work properly, so the application thought my device wasn't rooted and blessed me with the result of the else
branch. But worry not, my friend — I'll write the root detection bypass using frida
in case the root detection is working in your case.
Java.perform(() => {
let isRooted = Java.use("com.cybertalents.ohmyroot.IsRooted");
isRooted.IsDeviceRooted.implementation = function() {
return false;
}
})
We load this code using frida -U oHmyRoot -l <filename.js>
. In this code we import the IsRooted
class and re-implement the IsDeviceRooted
function to always return false
so our device isn't considered rooted.

But as we know from the code review, the flag isn't here. So let's review the second activity FLAGbox
; obviously from its name it is the one containing our flag XD.
private native String DoSomeMagic();
static {
System.loadLibrary("native-lib");
}
@Override // androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_flagbox);
TextView textView = (TextView) findViewById(R.id.textView);
if (!Boolean.valueOf(new IsRooted().IsDeviceRooted()).booleanValue()) {
textView.setText(DoSomeMagic());
} else {
textView.setText("Sorry You Are you should get off your Rooted Device");
}
}
Viewing it we deduce the same thing: it checks if our device is rooted or not, then executes DoSomeMagic()
, so we need to find some way to start this activity.
Using the next frida
script,
Java.perform(() => {
const MainActivity = Java.use("com.cybertalents.ohmyroot.MainActivity");
const FlagActivity = Java.use("com.cybertalents.ohmyroot.FLAGbox")
MainActivity.onResume.implementation = function () {
console.log("onresume");
let Intent = Java.use("android.content.Intent");
var myIntent = Intent.$new(this.getApplicationContext(), FlagActivity.class);
this.startActivity(myIntent);
}
})
This code would start the flag activity when the main activity resumes. So we hook this code using frida
after starting our application. You might notice that nothing happens immediately, but after going to the home screen and then entering the app again, the flag will appear.

Last updated