React debug.keystore key was trusted by Meta(Facebook) which caused to Instagram account takeover by malicious apps.

 

App Signing

All Android applications should be signed with keys generated by app developers (https://source.android.com/security/apksigning). When application signed with specific key we can verify that this app was not modified by thirdparty. Also it is possible to communicate between apps (IPC) and verify app identity by it key signature. If caller app has verified signature than we can allow it to do some restricted actions, for example we can return some confidential information to it like user information. This keys should be confidential and not be exposed outside.


Bug Description

I played with Facebook Sdk for Android and noticed one thing. This api call is not validates package name when you authorize your client_id

```

https://m.facebook.com/dialog/oauth?android_key=Xo8WBi6jzSxKDVR4drqm84yr9iU&calling_package_key=com.vulnano.android.facebook.sdkat&client_id=124024574287414&display=touch&facebook_sdk_version=8.1.0&redirect_uri=fbconnect%3A%2F%2Fsuccess&response_type=token%2Csigned_request%2Cgraph_domain&scope=email&state=%7B%220_auth_logger_id%22%3A%2248b8ada7-fa9e-4136-a711-edc4778a8601%22%2C%223_method%22%3A%22katana_proxy_auth%22%7D&type=user_agent&_rdr

```

It validates only "android_key".

"android_key" is app signature value. And the funny thing is that some Facebook applications (https://developers.facebook.com/apps/), for example Instagram, is setup not only with release Facebook keystore, but also they setup with exposed keys, which we could find in internet:) 

For example this  https://github.com/facebook/react-native/tree/master/keystores keystore is used to sign examples for React apps.

I signed my malicious android application with that key and now I can authorize my app like Instagram.

How I found that signature? I found in Facebook sources lines like this

```

  public static final C016209j A01 = new C016209j("fbandroid_debug", "Xo8WBi6jzSxKDVR4drqm84yr9iU", "-sYXRdwJA3hvue3mKpYrOZ9zSPC7b4mbgzJmdZEDO5w");

```


Than I searched for Xo8WBi6jzSxKDVR4drqm84yr9iU and found original key (it is android debug key)

So, api call is not validates package name and we can sign our app with required key. Now our application is getting Instagram token through Facebook for Android app.


Steps to reproduce:

  1. Install Facebook for Android
  2. Login into Facebook with account which used also for Instagram auth (or install Instagram and authorize there with your Facebook account)
  3. Install Poc *
  4. Launch PoC
  5. If you see "Token is null, login", than press Login button
  6. You should see received token.
  7. Copy token and verify it:)

* if you compile PoC from provided sources than look inside "build.gradle" to set correct path on "debug.keystore" file.


Browser/OS

Rooted Android 10.0 Pixel 3 (should work at any other version), Facebook v. 302.0.0.45.119


Video of PoC (accessed by url)

https://youtube.com/shorts/gcQk0lMZEUE

(yeah, my test token is not blured fully in video, but it should be inactive )))

Attack Scenario

Malicious Android application can steal Instagram (and probably other apps) tokens without user interaction. This is possible through public keystore file which can be used for malicious apk sign. Probably this signature may allow us to bypass some signature checks in inter process communication with Facebook apps or on Facebook devices like Portal or Oculus.


PS

I don't publish the PoC because you don't need it. The PoC is app signed with debug.keystore key located in https://github.com/facebook/react-native/tree/master/keystores.

BTW Google Play prevents developers to upload .apks signed with that key. So you won't be able to publish your app signed with that key, however be carefull if you use this key in your React app as debug key and trust it via signature verifications by code.


Timeline

26.01.2021 Report sent

26.01.2021 Report reproduced by Meta team

27.01.2021 Report triaged

08.06.2021 Bounty 10000$ + 2000$ (Diamond league bonus)

25.06.2021 Fixed




Promo

By publishing this small research I want to raise one community problem which goes from HackereOne and affects Belarussian/Russian researchers.

I trusted to H1 and used it to get bounties from Meta(Facebook), I have MVH 2019 belt from Vancouver (https://hackerone.com/dzmitry) and some other awards from LHE organized by H1. 

HackerOne claims they don't send rewards to researchers located (https://twitter.com/vulnano/status/1533756892408856579/photo/1) in sanctioned areas like Belarus/Russia. This is their decision and risks, ok. But they don't send payments anywhere if you have belarussian/russian citizenship! They locked payments from my https://hackerone.com/dzmitry account and I can't send payments anywhere - in any other country, pay taxes there and spend money there. I had some good reputation in private programs, but I don't have any motivation to look bugs when I can't get rewards. And this is only because I have belarussian citizenship. How this is called? They think we support the war and use this money for this purposes? (just look back and see what happened in 2020 in Belarus).

Some my experience in BB: ~ TOP10 in Meta BB 2018-2022 (https://www.facebook.com/whitehat/thanks), ~TOP 15 in Google BB (https://bughunters.google.com/ ).

And another story from my belarussian colleague who can't get his money from H1. Money which he got before the war started and H1 anounced restrictions! 

https://twitter.com/xnwup/status/1545741277895049216 

Popular posts from this blog

Facebook Messenger server random memory exposure through corrupted GIF image

Facebook Messenger for MacOS contained valid hardcoded FB access token (employee's token?)