Background
This type of flaw is not very common, since databases are usually used for information storage and because there are usually other ways to link to files or make them downloadable. However, it is nonetheless a very important flaw that one should know about when developing a website or when trying to test a website for vulnerabilities.
So what is directory traversal? Directory traversal is a flaw through which an attacker can gain access to all of the files which the web server has access to. In most situations it is read access that we are dealing with, however there are some situations in which we are able to write files, so we would be dealing with the locations on the system where the web server has write access to. It will all make sense in a moment.
Methods of Exploitation
Say you are visiting a small blog website made by one of your friends, where he complains about various issues that are bothering him such as global warming or Santa's budget cuts this year. You have a simple PHP webpage with links to the individual blogs. You click the global warming link and it takes you to the actual blog, but when you look at the address bar you see something like this:
Code: http://www.i-yak.com/readblog.php?file=global%20warming
You go back to the main page and click the next one and you're shown this URL:
Code: http://www.i-yak.com/readblog.php?file=Santa's%20budget%20cuts
You notice that the script's variable is clearly named file, so you know that you're dealing with text files being read and displayed by the readblog.php script.
You can grab the filename and paste it right after the domain name, ignoring the script, forming the URL:
Code: http://www.i-yak.com/Santa's%20budget%20cuts
The website now shows you the text file with your friend's blog, minus the style of the page. This confirms to you that all your friend is doing is reading the blogs from simple text files, adding the CSS style to them and displaying them. You can run another check to make sure that what you're seeing is right. You use the URL:
Code: http://www.i-yak.com/readblog.php?file=readblog.php
Now you know for sure that he is doing that, because you're looking at his PHP script and you can see the fopen(). You want to let him know about it, but you want some good proof so he can see how serious the vulnerability he left in his script is.
Normally what one would do is traverse through the system directories (hence the name of the vulnerability) looking for data that they normally wouldn't have access to.
A typical method of exploitation that you would find in almost all of the articles on directory traversal, but which doesn't really help gain access to a system, nowadays, is viewing the contents of the /etc/passwd file. This would allow the attacker to see the users that exist in the system, however, most of the Unix based systems out there now use /etc/shadow to store the hashed passwords of the users, file which is only accessible to root or someone with root priviledges. So unless the web server is running with the same user ID (UID) or effective user ID (EUID) as root, chances are that you're not going to have access to /etc/shadow, and therefore the user password hashes.
As we know, two adjacent dots (..), in Unix based operating systems, represents the parent directory. If we make a request for ../file.txt we are requesting file.txt from the directory that is one level up from our present location, or in other words the location of the script readblog.php. Now readblog.php would probably return us an error saying that the file 'file.txt' cannot be found, unless a file.txt really does exist in the parent directory. Another possibility of an error that you can receive is something along the lines of: you do not have permission to read the file 'file.txt', which happens if the file exists but the web server does not have the permission to read it. But our aim is not trying to guess the filenames of each file that our friend has on the server, but rather pinpoint the location of a specific file that we know the system has, such as /etc/passwd.
We can try simply using /etc/passwd as the value of file, if the PHP script does not add a prefix to the filename entered (in other words, we're using an absolute path to the file):
Code: http://www.i-yak.com/readblog.php?file=/etc/passwd
Suppose the PHP script adds the prefix '/home/blogger/blogs/' to the filename entered. This is where directory traversal comes in again. We can use the following URL to move up 3 directories (/home/blogger/blogs) and then request /etc/passwd (here, we're using a relative path):
Code: http://www.i-yak.com/readblog.php?file=../../../etc/passwd
So what else could we do with this? We could read our friend's bash history, for example:
Code: http://www.i-yak.com/readblog.php?file=../.bash_history
Or, for something a little bit more exciting, we could check if, say, another machine on the network is mounted to his server:
Code: http://www.i-yak.com/readblog.php?file=../../../proc/mounts
From here, we could grab the mount point and start looking through the files on that machine. Basically, knowing where things are, typically, in a Unix based operating system, will help you look for anything you want.
But let's take this a step further and say we found a spot on the page where our buddy can log in and add entries to his blog. First he would be sent to the login page, after which he would be redirected to the page where he can add the blog entry. The login page URL, which is all we can see for now, could be:
Code: http://www.i-yak.com/login.php
We can use readblog.php to read the script and see what he is up to. In the best case scenario the password he will be comparing the input with will be right inside the script, but let's assume that he assumed a little security by placing his password in a file called 'passwd', in a directory 'secure'. The location of the file would be visible when we are looking through login.php. Again, we can use readblog.php to read the file, which is probably going to be in plaintext and grab his password. The URL would be:
Code: http://www.i-yak.com/readblog.php?file=../secure/passwd
Since the webserver needs to have read access to that file in order to compare the inputted password with that in the file, we know for sure we are able to read it.
Now all we will do is use the password we found in ../secure/passwd and log in, showing us the name of the script that is used to write the blogs, let's say addblog.php. Again, we browse through the script using readblog.php and find out that all it does is creates a file whose name is the title of the blog entry and whose content is the body of the blog entry.
We go back to the addblog.php script add a new entry...
Title:
Code: Vulnerable
Body:
Code: Hello, folks. Welcome to my insecure blog. Thanks to my good friend BluePass, I am now working on securing this page. The page will be up in a few days.
Thank you for visiting and please come back soon.
Lastly, we take the original readblog.php script, copy it to a text editor, remove the variable 'file' and make the fopen() open the file Vulnerable.txt. We go back to addblog.php and use the title 'readblog.php' and the body: our new code, and submit. Then we give our friend a call.
Prevention Methods
The best way to prevent this type of vulnerability from happening is by using a database to store whatever information needs to go on the website. MySQL is a free, open source solution for that, with numerous articles and tutorials on the internet. If you need to make files available for download, put them all in a directory which your webserver gives public access to, and lock the rest of the system down from public use, then make the links directly to the files in that directory.
Finally, if you still find the need of reading and writing files for the purpose of your website, make sure you validate user input. Make your script filter strings like '../' and '..\', and
remove them once found.
Another prevention method would be using suffixes. If you're working with a site similar to the one I presented above, when you write the blog entry you could make your script add a suffix to the file name which would act as an extension, such as '.blog'. This will prevent someone from overwriting your script files, as the resulting file will always be a '.blog'. The same applies to reading a blog entry. Pass the script which reads the file only the name of the blog, and make sure that it automatically adds the extension '.blog' to the input. Finally, make sure that the extension you use for this type of file is not one that already exists somewhere on your system, such as '.config'.
Well, I hope you learned something from this example and that it all makes sense. Directory traversal can be more complex than this, but in all cases it involves using relative paths to move around on the remote system. Wikipedia's example, for instance, uses cookies as the means of passing these file locations. I suggest you have a look at that as well and understand how it works. Finally, it is all a matter of using your knowledge and instincts to find out ways to exploit this vulnerability once found. There is never one definite way of exploiting vulnerabilities.
0 comments:
Post a Comment