Panoptic - A tool to exploit path traversal vulnerabilities
Occasionally during a penetration test, I encounter a path traversal vulnerability which cannot be converted to a RFI and exploited easily. This can be quite a frustrating vulnerability to escalate your access with when you don't have a large database of the default locations of known configurations, logs or other important files. It was out of this frustration that Panoptic was born. With the collaboration and invaluable help of Miroslav Stampar, we wrote a tool that searches for commonly known files through LFI vulnerabilities. In this post, I will be demonstrating some of the features and capabilities of Panoptic.
To get started, you will need Python 2.6+ (previous versions may work as well, however I haven't tested them)
- Python 2.6+
- Git (Optional)
The next step is to download the project.
In order to do so, you can clone Panoptic from the repository hosted on Github (Recommended)
git clone https://github.com/lightos/Panoptic.git
or download the ZIP file directly from
The reason cloning the project from the git repository is recommended over downloading the ZIP file is mainly because you will later be able to use the --update feature which does a git pull request.
Running the program
To run Panoptic, simply execute the main script panoptic.py.
$ python panoptic.py -h
Figure 1: Panoptic's help menu.
If you look closely at the above screenshot, you will notice that Panoptic has all the basic features one would expect from a web exploitation tool (GET/POST requests, socks 4/5 + HTTP proxy support, random user-agents to choose from, ability to add custom headers and cookies, etc...). I won't go over these, since most people already understand what they are meant for.
Panoptic has heuristics built in to detect when a file is found, however on rare occasions this can fail. In this situation, you can use the --bad-string argument to specify a string to be matched in the HTML response when a file is not found. If Panoptic detects the bad string in the response then it knows the file was not found.
All file paths are found in the cases.xml file. Each file path is associated with a software, a software category, an Operating System and a classification depending on whether the file is a log, configuration file or other. This is where the arguments --os, --software, --category and --type come in. With these arguments, you can filter your search to only look for those specific files.
./panoptic.py --url "http://localhost/lfi.php?file=x" --os "Windows" --software "WAMP" --type "log"
Figure 2: The XML containing all of the files information.
If you would like to see all the available options, you can use the --list argument.
./panoptic.py --list software
Not only will Panoptic display the found file paths, it can save the actual files as well. With --write-file, the content of each file will be saved to output/<domain>/<file path>.txt, so you don't have to request the file again to view it. It also runs the output through a clean up function to remove the unwanted HTML.
Figure 3: A screenshot of the output folder created by Panoptic with the --write-file argument used to save all found files.
A lot of the time the LFI inclusion vulnerability will be inside folders and have an extension added at the end. In this case, we can use --prefix, --multiplier and --postfix
<?php include("Library/Webserver/Documents/" . $_GET["file"] . ".php"); ?>
This vulnerable PHP code is a classic example where a nullbyte is required to terminate the include and ignore the file extension at the end. With the following command Panoptic can meet these requirements:
./panoptic.py --url "http://localhost/lfi.php?file=x" --prefix "../" --multiplier 3 --postfix "%00"
As some of you may know, bypassing filters is sort of a hobby of mine. In saying that, I couldn't exclude the possibility of having the request blocked by some firewall and no way around it. For that reason I included the --replace-slash argument. This argument replaces all the forward slashes in the filepath for whatever you specify.
./panoptic.py -u "http://localhost/lfi.php?file=x" --replace-slash "/././"
In this case /etc/passwd would become /././etc/././passwd. An excellent tool that can be used to find filter bypasses and determine the depth of the path traversal for LFI's is DotDotPwn which is included in Backtrack.
A neat feature that we incorporated into Panoptic is file parsing. Although basic at the moment, it can currently parse the *NIX passwd file to extract the user's home folders and search for different common file combinations such as:
For a full list you can check the home.txt file. Another file that it parses is the MySQL binary log index (mysql-bin.index), which it uses to get the list of binary logs. This feature is on by default any can be disabled with --skip-file-parsing.
Figure 4: Panoptic detects the passwd file and parses the home folders to search for common files.
More features will be added once we get some user feedback and fix possible bugs that may exist. All contributions are always welcome!