In the Spring 2018 semester, I took a Computer Security course here at Tufts University. In labs for the course I got to build network sniffers, compete in CTF tournaments, and even use Tufts' High Performance Computing Cluster to crack password hashes (at one point I was allocated a VM with 32 GPUs, oh boy!).
However, by far the best experience in this class was my research, disclosure, and follow-up assessments of a private vendor's enterprise software.
Below you’ll find two reports I sent to the Tufts InfoSec team, who swiftly investigated the claims and worked with the service vendor to mitigate the issues. Additionally, you can find a presentation I gave to my Computer Security class about this process here.
Vulnerability research of third-party software was unfortunately not part of the syllabus for this course. Time spent doing this research actually made me miss a lecture on SQL injection and cross-site scripting. Thankfully, the professor for the course approved of my "hands-on learning".
Thank you to Ming Chow, who helped me get in contact with the Tufts Information Security team and guided me through the disclosure process, Lorna Koppel and Eric Barnes at Tufts Information Security, and the rest of the Tufts Information Security and Tufts Technology Services team for quickly jumping into action and kicking off the remediation process for the reported vulnerabilities.
Note: Certain data has been redacted from the original reports.
The purpose of this report is to demonstrate the open vulnerabilities in Tufts’ implementation of the software vendor’s ticketing system. As it stands, the implementation is vulnerable to the following exploits: database injection (SQLi), cross-site scripting, information exposure, and XML injection.
Going to the “My Open Items” tab and inspecting the source code (most browsers have built-in developer tools, here I am using Chrome’s Dev Tools), each incident on the list makes reference to an incident XML table, which led me to try some different URL parameters to be able to access the table I theorized existed. This also gave me an idea of how the URL is parsed in order to request information from the table.
home.do gave me my homepage and
incident.do gave me the incident reporting page,
incident_list.do could return a list of all incidents. And it did. So, making a request to
incident_list instead of
home allowed me to access all incidents reported on TechConnect, a total of 491,298 reports (I found some tickets dated back to 2011).
Now I can look through every ticket, including the full name of the client, their Tufts UTLN, the short and extended description of their issue, and, if they provided the information, their phone number and address. I also have access to any attachments made to the report and information about who at Tufts Technology Services opened the ticket, who it was assigned to, and who closed it, including first/last name and their Tufts UTLN.
With specific requests, I can list incidents that have phone numbers, or attachments, or certain names. Any actor has the ability to look up specific people and find their phone number and office address/location of incident. This includes information on users deemed to be “VIPs”. An icon appears next to the client’s name, giving a potential attacker visual cues for valuable information.
Additionally, I also have access to who gets updated for each request, allowing me to add and delete people from the watch list.
They confirmed the vulnerabilities five days later and patched the issues within 7 days.
The profile page is where more valuable information is displayed (full name, phone, address, email), and is displayed after querying to a database. I could not use my previous XSS method to return a list of users or incidents, so I will try to find another way to access this info.
In my previous email, I mentioned the vendor did not fix the access control issue, still allowing me to access other profiles if I have the URL for their profile. But how can I do this if I don’t have the correct URL?
I analyzed the URL for two profiles I had access to (Lionel [REDACTED] and Deborah [REDACTED]), and found the only change in the URL was for a field sys_id. sys_id seems to tell the database who’s information to retrieve. So if we can find this value for other users, we’ll have access to their profile.
Lionel [REDACTED]’s sys_id
Deborah [REDACTED]’s sys_id
Reconstructed URL for Lionel’s account:
Reconstructed URL for Deborah’s account:
Whenever an incident request is made, multiple pieces of information is stored, but what we’re concerned with is the fact that it connects the profile of who opened, closed, is assigned to, and is on the watch list for an incident. So, by looking through incidents I do have access to (either by watchlist or as owner), I could perhaps find some information about the users linked to each incident.
Sure enough, the page’s source code stored each user’s sys_id in plain text as a hidden variable. This gave me the sys_id for the people involved with the ticket. This meant with this old ticket, I can access not only mine, but Delilah’s and Shawn’s profiles as well. Delilah [REDACTED]’s (Resolved by, Assigned to) sys_id
Shawn [REDACTED]’s (On watchlist) sys_id
Reconstructed URL to query for Delilah [REDACTED]’s account
Reconstructed URL to query for Shawn [REDACTED]’s account
This vulnerability can be exploited to gain a lot more information than the support person servicing tickets the malicious actor has access to. In the watch list field, the user can add and remove any user they wish. This allows them to have a handy tool for finding ANY USER’S sys_id value, and it even includes a user autofill feature that can be leveraged to find users whose username the attacker is unaware of. This allows an attacker to access any user profile they want. This information leak needs to be fixed before it can be leveraged against someone.