I have found a path traversal vulnerability that allows me to read any path on the server that does not require sudo.

To fully exploit this, I would like to know which files exist in each directory so I can read them.

In other words, I can do cat /any/path, but not ls /any/path nor sudo cat /any/path. So how can I find as many files as possible to cat them (without trying all possibilities...)

Reading special files like dev or proc, or files present on most Linux distributions is OK. For example, if I could read locates /var/lib/mlocate/mlocate.db database the problem would be solved: but I can't because I don't have sudo.

If there is no ideal answer that lists all files, I am also interested in answers that list large number of existing files.

In this particular instance, the traversal happens inside a remote VM, so privilege escalation in itself is not the main goal: what I'm interested in is confidential source code that may be found on the VM. But very common privilege escalation paths are also welcome as those would give us mlocate and solve the problem, besides being directly useful in other systems.

More precisely, the system in my case is a build on push Git service analogous to GitHub / GH pages (assuming each Jekyll build runs on VM, which I don't know). Mentioning this because it has already been fixed by vendors of course :) It is me who creates the Git repo: that is the attack vector, so reading the Git repository is not very interesting.

  • One process you can access is the one currently running the command: /proc/self. Here self is a symlink alias of the it's PID. Commented Mar 24, 2017 at 15:43

2 Answers 2


You can try other locate implementations that index world-accessible files in a world-readable index, typically located at /var/lib/locate/locatedb or /var/cache/locate/locatedb or some such.

I don't see a lot of need for file listing to escalate your access on a typical server. Usually you'd know what application you're attacking and retrieve its configuration files and its database and obtain credentials this way. You might try files such as .netrc, .ssh/id_rsa and .ssh/config to see if the account can be a gateway into other accounts. If you aren't sure what may be running on the box, try lots and lots of plausible file names.

The one thing that's a bit long to exhaust is the PID values, to explore what's running. It takes 32k requests to exhaust pid_t under Linux by default, and you can check the maximum value in /proc/sys/kernel/pid_max. The command line is in /proc/PID/cmdline; you don't get to see the list of open files (you need readlink for that) but you can see their content (cat /proc/PID/fd/0 …).

For the specific case of a build service, do check the configuration files of that service. That should help you locate the git repository. If you've been able to locate a git checkout, look in .git/index and .git/logs/HEADS and perhaps other files in .git/logs (experiment with that service to see which branches are used and what operations it uses). This should let you retrieve object IDs which you can then read from .git/objects.

Other than finding a locate database, I can't think of a way to elevate read-files access into list-files with a typical configuration.


On some versions of Unix (especially older ones), you may be able to cat directories themselves; e.g., cat /any or even cat /.  The result will be a binary file whose format is different on different versions of Unix, but which will always contain the names of all the entries in the directory (starting with . and ..) and their inode numbers (in binary form).  So, for example, the output of cat / will include any, etc.

See When did directories stop being readable as files?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .