I recently discovered a path traversal vulnerability on a bash script exposed through the cgi-bin directory on an Apache server. Using the vulnerability, I was able to read arbitrary files on the remote system (as long as the access controls of the Apache user allowed it).

This allowed me to download known files to better understand the target. I poked around the /etc and /var/log/ directories, grabbing select files such as passwd, httpd.conf, access_log and error_log. This revealed the operating system to be SunOS 5.10 (which is the same as Solaris 10), a list of users, the web root, and exact names of various files within the web root.

One of the limitations of a file disclosure vulnerability is that you need to know the exact name of the file you want to read. This is fine for reading well-known files that should always exist, such as /etc/passwd; but to read many of the more interesting files, some investigation and educated guessing needs to be done.

Sometimes the information gleaned from reading a well-known file can be helpful in finding other useful files. For example, by reading /etc/passwd, a list of valid usernames can be found. From that, I checked all users’ home directories for poorly-protected SSH private keys (id_rsa). In addition, we were able to steal some of the source code of the application, using filenames discovered within the Apache logs.

Analyzing the source code showed no command injection vulnerabilities or otherwise potentially-dangerous functionality such as arbitrary file writes.

I wanted the ability to list directory contents and perform a more in-depth search on the target. A little-known method that I discovered during OSCP is the ability to download the locatedb (/var/cache/locate/locatedb) or mlocate.db (/var/lib/mlocate/mlocate.db) files. You can then use inspect the downloaded database using the locate command to find files on the target. It turns out that SunOS 5.10 does not have the locate command and consequently the locate databases were not present.

Since the vulnerability was occurring through a Bash script, globbing was being performed on the path. Globbing is essentially wildcard matching on pathnames. The two examples below will print the contents of /etc/passwd. The question mark matches any single characters, and the square brackets match any one character given in the bracket.

This is useful because it gives us the ability to read files, even if we don’t know their exact name. This can be achieved by continually appending the ? symbol to a pathname. Once you match a valid file the contents should be returned. Example:

Depending on the behavior of the local file disclosure, matching multiple files might break the application. In our case, if the globbing matched multiple files, no data was returned. However, I was able to differentiate between zero matches, one match and multiple matches with the response returning an error message, the file contents or nothing, respectively. In the case of the pattern matching multiple files, the bracket wildcard was used to drill down to a single file:

The example uses a binary search pattern to be efficient. If all you require is the files contents, you can safely stop after retrieving each file. The technique can also be used to disclose the full filename, and consequently determine a list of directory contents. This is especially useful for the cgi-bin, were full filename are required to execute the script.

This would be painful by hand, so I created a tool to automate the process. I was now able to download the remaining source code, search home directories for credentials left in cleartext, check the temp folder for anything suspicious, view Samba shares, etc. I never ended up compromising the target, but it was an excellent learning process.