Indirect Direct Object Reference Vulnerability in UC Berkeley's bHive

4 minute read 2015-12-10 Ashkan Kiani -

Discovery

A friend of mine was describing the appointment process for L&S and how it was quite different from the EECS appointment system in that a person must make an appointment for 2 weeks from then on the day of. This leads to a rush to get appointments in the first few minutes of the appointment being available.

I actually am not sure if this is actually the case as I didn't set an appointment, but it got me curious about finding the API to perhaps give my friend an edge in scheduling an appointment.

In the process, I found that the API uses websockets to facilitate this, and in inspector, the frames being sent back and forth are easily read. I set about using phantomjs to scrape the websocket url which I handed off to a websocket client to start playing around with sending my own data. However, there was one websocket frame which got me very curious:

["{\"msg\":\"sub\",\"id\":\"B5HAPFkcbTvYd3Awt\",\"name\":\"studentAppointments\",\"params\":[\"22589623\"]}"]

I saw how my student id was being sent as a parameter, so I asked my friend for his student id to test out my hunch, and sure enough, I was able to send a sub request for his student id. Now I was curious about how bad this vulnerability could be, i.e. if there was rate-limiting in place. So I set about making a more robust script.

The problems discovered

  • The direct object reference to student appointment information outside of the currently logged in students. There needs to be validation here. The appointment data leaked information like emails, student names, and personal details.
  • A single url like the one here: "wss://bhive.berkeley.edu/cluster-ddp/f524202f9045cf1a0facecd3c7f4a3ff3a4b6f60/bhive/556/sq69kmb2/websocket" was able to be used for a period of 3 days!! The expiration of the url should be tied to the session at the least.
  • There is no rate limiting: I was able to use the same url to run 6 workers constantly hitting the endpoint with more than 100 requests per second. This is a DDoS vulnerability, especially if the attacker is not considerate enough to unsub after subbing, leading to the server potentially with thousands of un-collected references (as I'm assuming the server is garbage collected node.js).

The Exploitation

After writing a script that would subscribe, then subsequently unsubscribe for a studentAppointments channel for a particular SID, I ran parallel workers on the same script that were able to test on averge 21 student ids per second per worker in a linear scan of the student id space. Upon getting a hit, I maintained a counter and a simple list to the effect of seeing how many student ids were able to be scanned overnight. In a period of 14 hours, I was able to identify 14818 student ids that yielded non-negligible personal details. A sample from the appointments collection:

{
  "name": "appointments",
  "fields": {
    "studentId": "20000000",
    "method": "visit",
    "staffId": "123456",
    "email": "... THEIR EMAIL ...",
    "skype": "... USUALLY BLANK BECAUSE NO ONE USES SKYPE ...",
    "duration": 30,
    "status": "concluded",
    "created": 1400000000000,
    "createdBy": "0000000",
    "lastModified": 1400000000000,
    "lastModifiedBy": "0000000",
    "reasonId": "0000000000000aaaaaaaaaaa",
    "reason": "... A PERSONAL APPOINTMENT REASON ...",
    "startTime": 1400000000000,
    "isDayReminderSent": true,
    "isPast": true,
    "isFifteenMinuteReminderSent": true,
    "studentArrivalTime": 1400000000000,
    "studentCheckInTime": 1400000000000,
    "historyItemId": "1234567890ABcDeFG",
    "appointmentConcludedTime": 1400000000000
  },
  "id": "ABCdef12345678pYz"
}

We can see the status of the appointment, the time of the appointment, their reason for visiting, their email, and their student id associated with their name (typically). And if not from there, then from the messages sent from the singular sub call:

{
  "name": "messages",
  "fields": {
    "appointmentId": "ZYXzyx11111111111",
    "type": "adviserConfirmation",
    "to": "STUDENT@berkeley.edu",
    "from": "appointments@bhive.berkeley.edu",
    "subject": "Office visit with FIRSTNAME LASTNAME Thu Nov 32 @ 9:99 PM",
    "html": "... A WHOLE LOT OF HTML ...",
    "sent": 1400000000000
  },
  "id": "abcZYX123eeeeeeee"
}

The Results

14818 distinct student IDs with information leaked. I have since deleted the records of the student IDs after running the workers.

Recommendation

VALIDATE THE STUDENT ID ACCORDING TO THE LOGGED IN STUDENT. THIS IS A VERY COMMON BUG IN A HASTILY WRITTEN APPLICATION.


published in security and tagged security , netsec and web