My first blog post will talk about a security vulnerability that I discovered in March 2017 for a private bug bounty program. I won’t disclose the name of the customer (let’s call it Customer01) but will say that the bounty is currently hosted by Bugcrowd.
The issue I found is a very simple username enumeration vulnerability with a lot of potential for damage. There wasn’t much to do except reading the available information and connecting the dots.
Java Network Launch Protocol
It all started with a “.jnlp” file. According to Oracle, the Java Network Launch Protocol (JNLP) “enables an application to be launched on a client desktop by using resources that are hosted on a remote web server. Java Plug-in software and Java Web Start software are considered JNLP clients because they can launch remotely hosted applets and applications on a client desktop.”
Customer01 developed some Java applications and released them for its users to download and run. This is achieved by using a .jnlp file per application. The JNLP is an XML file which tells JAVA what resources need to be downloaded from Customer01’s site and how to run the application.
The JNLP referenced several “.jar” files (about 30). This got my attention. As you probably know, jar files can be decompiled with available tools and that’s what I did. To be quick about it, I ran “Java 8 Web Start” (this is installed by default when installing Java’s jre/jdk) and made sure that every HTTP requests would be proxied through the well known web application security testing toolkit, Burp Suite.
I then ran the JNLP application and all the jar files started appearing into Burp’s HTTP History. I then grabbed all the URLs that resolved to a file and downloaded them with “wget”.
Decompiling the files
To decompile the “JAR” files I used JD-GUI for Linux (available at http://jd.benow.ca). If you are not familiar with the command line, this tool is perfect. You select a .jar file and there you are.
What to do next?
Finding the needle in the haystack
Now the boring part starts. You have got about 30 jar files and in each one of them you have got thousands of lines of code. You could read each one of them (I did this in part) or look for something specific by using the search function of JD-GUI. This is what I looked for:
- Any references to “Customer01” (the name of the client’s site)
- Any references to protocols: “http://”, “https://”, “ftp://”, “sftp://”, “smb://”, etc.
- Any references to keywords: “admin”, “adm” ,“user”, “password”, “pwd” ,“test”, “debug”, “host”, “ip”, “domain”,“key”
- Any references to files: “html”, “htm”, “php”, “shtml”, “jsp”, “txt”, “asp/aspx”, “xml”, etc.
This process brought some good information about internal IP addresses, subdomains I hadn’t seen before, hidden or authenticated-only endpoints and a .txt file:
When I saw the list of approximately 500 users I couldn’t believe it [note. the users in the picture are not the real users]. I went to check if these were valid users. One of the sites owned by Customer01 had a user enumeration vulnerability (not ever rewarded) which confirmed that most of the users were indeed valid (some of which looked like internal users).
What to do now?
Reporting user enumeration vulnerabilities is not a great thing. You don’t get to show the real impact of the vulnerability, you don’t get rewarded. On the other hand, Bug bounty programs generally prohibit bug hunters to brute force user accounts. What to do then? Since I reported 70 valid bugs to Customer01’s private program I decided to try my luck and ran a 1-password not-so-brute force attack (1 password because I couldn’t really understand if the apps had lockout policy in place). If this had failed, I would have tried to find a better way to use those users or report the security vulnerability as a simple user enumeration.
The target and the password
I decided to target the application which had the user enumeration vulnerability (the one that I used to confirm the list of users) because I was sure the users were valid for at least that site.
Furthermore the application disclosed information regarding the password policy in use: passwords should be minimum 8 characters long (weak password policy, another bug which is generally not rewarded). I decided to go for the dumbest password that a user could choose: according to several experts in the field (penetration testing and all the other fields!) it is “password”. Probably not the best choice but whenever you perform a brute force attack you can be sure there will be at least few users with extremely lazy passwords.
I was lucky enough that user #603 in my 612 user’s list chose “password” as his password
This gave me access to a chat application in use by internal users and customers. You can probably imagine the kind of damage these security vulnerabilities could have caused. I had access to hundreds of usernames (more than the ones in the list I already had) and could have started a targeted phishing attack to escalate privileges first within Customer01’s external perimeter (web applications) and then perhaps within the internal domain. Of course nothing like this was tried.
I decided to see whether the user had access to other subdomains and then stop to report the results of my vulnerability assessment
I found out that the credentials would work only on another site which allows users to read their chat history. This proved to be quite interesting since the user disclosed credentials for a couple of test users and a domain user (yes, domain credentials). The domain user and password worked on other sites in scope but I was stopped by 2 Factor Authentication which the user correctly enabled (or was forced to enable by Customer01’s security policy).
This is the end of the story.
Lessons learned and Considerations
- Decompile .jar files! They can disclose plentiful of information;
- Username enumeration and weak password policy are not really considered important by bug bounty programs and I believe they should be! They can be quite scary when linked together;
- Brute force attacks are prohibited by bounty program’s rules and what I did was on the line between “ok, proof of concept is required” and “am I getting into troubles?”; I should have asked for permission;
- Brute force attacks, excluded by bug bounty programs, can give malicious attackers access to sensitive data and ethical hackers won’t include them in their bug bounty reports because they are not considered important or too dangerous to perfom (and thus are not rewarded).
- Users are lazy. Users should not share domain credentials (but they will anyway).
- Strong password policies should be implemented. User enumeration vulnerabilities should be considered and fixed, even when they seem lame. 2FA should be activated for all apps (in this case, this saved the user from a lot of problems).
Timeline of events
|Analyst requested user file||2017-03-22|
|Provided users list||2017-03-27|
|Provided POC video||2017-03-27|
|Bug rewarded with maximum payout||2017-04-18|
Jar files decompiler (GUI - not supported anymore but still working) available at http://jd.benow.ca