Website Hacking, Part II

Introduction

In this Part, we are going to briefly introduce Path Traversal, usage of Delimiters, and Information Disclosure attack.

We are going to present simple solutions to simplified problems involving the attacks.

Content

Exercise 8: Path Traversal

Figure : A simple webpage in which you choose an article and view it

The website (index.php) in the PathTraversal folder contains a simple form which submits to the same page through the GET request method. Once a choice of article has been made and “View article” has been clicked, the following PHP code executes:

1

2

3

4

5

6

7

<?php

//If the article GET parameter is set

if(isset($_GET["article"])) {

// Create a div block and fill it with the contents from the file in the GET value.

The result is the following URL: http://localhost/2/PathTraversal/?article=1.htm

It loads the relevant article file placed in the GET method. The parameter article is formed via:

1

<selectname="article"required=""></select>

And the values are also directly given through the HTML code (the value attribute):

Domain Slamming

Now, legitimate users will use the interface provided in the website to browse it, but with the code as it is we can easily open myriad files they do not want you to open by directly tampering with the URL parameters. Many websites have config directories where they store important data – let’s see if you can do it.

Tasks

Go back one directory and open openme.txt by changing the URL parameters.

We assume that we cannot open the folder config from our computer but only from the local server. Assume you do not know what files there are in the directory. First, you should check whether the directory exists.

The directory exists and now we know that there is HTTPAuth in place. Your task is to somehow find out the username and the hashed password for the folder without using any brute-force or dictionary attacks on the username and password.

Spoiler (Task 2)

If we know that there is a HTTPAuth security mechanism in place, then we can automatically deduce there is an .htaccess file. Therefore, we can open the .htaccess file that we would not be able to open normally via the path traversal vulnerability of the article viewer page.

Firstly, checking if the file exists and echoing it out only if it exists prevents another attack – that of information disclosure.

There is a PHP warning thrown out if we type a non-existent file deliberately. Of course, another way to resolve such information disclosure issues is by turning off the display_errors In the php.ini file (this is most desirable if the site is live anyway).

With the above mentioned code we get a clean and neat error that the article does not exist, along with prevention of any path traversal attempts.

Figure: We now receive an error when we try to go back one directory and open the openme.txt file

Note: in old editions of PHP (older than 5.5.3) you could use the %00 marker to end the string abruptly and pass your own file extension in place of the “.htm” one in our solution code.

if (!file_exists($article . “.htm”)) could be exploited in older versions of PHP by typing:

“accounts.txt.htm” forcing the server to ignore the .htm part of the string.

Exercise 9: Information disclosure

Figure: Comment page

For this exercise, I have created a working but problematic comments page which looks similar to a chat. You have to write a comment, and then you view all the comments up to now. The comments are stored in a .txt file rather than in a database and there is one PHP file that creates new comments and one that displays them on the screen.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

//Index.php server-side code

<?php

$path= "comments/";

?>

<?php

if($_SERVER["REQUEST_METHOD"] === "POST") {

include("add_comment.php");

}

//Add_comment.php

<?php

//Open file and create an array with all comment information as indices

$comments= file_get_contents($path. "comments.txt");

$newcomment= [];

$newcomment[] = $_POST["name"];

$newcomment[] = $_POST["topic"];

$newcomment[] = $_POST["message"];

// Convert to string and add a delimiter to store in file

$newcomment= implode(":", $newcomment);

// Write the string to the file

$comments_w= fopen($path. "comments.txt", 'w');

fwrite($comments_w, $comments. "n". $newcomment. ":");

// Show all comments

include($path. "view_comments.php");

?>

Figure: How the comments file looks

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// View_comments.php

<?php

//Convert to array and echo all out in a certain format within the comments div

$comments= explode(":", file_get_contents($path. "comments.txt"));

echo"<div id='comments'>";

for($i= 0; $i< count($comments) - 1; $i+= 3) {

echo"<p>User: ". $comments[$i] . "<br> posted about: ".

$comments[$i+ 1] . "<br> and he wrote: ". $comments[$i+ 2];

echo" </p>";

}

echo"</div>";

?>

This application works just fine when viewed as is, but imagine if a user enters add_comment.php separately, without the file being included from the index.php. This can easily happen as the name of the service implies the file name, and this particular file name is frequently used, and the fact that add_comment.php is in the same directory facilitates the process.

Figure: Viewing add_comment.php on its own

Now, the attacker would know that we have a variable called $path and he can probably guess that we are setting the path to the comments file as there is a warning that file_get_contents(comments.txt) cannot be opened. Thus, he knows the name of the file that contains all our comments as well. Because the include is failing, he also knows the whole include_path which can also be dangerous. Also, the attacker knows another file in our directory tree (view_comments.php) so he can access it and look for some more errors. He also knows that in this file we are working with the POST values from the form, as he can view the HTML and see they are the same.

This comments form is also vulnerable to diferent code injection attacks. You can easily insert in one of the comment fields to test it out. In that way, the browsers of the users’ will execute any code that you like each time they visit the page.

A probable solution is easy: wrapping the post values in htmlspecialchars() function which converts < and > amongst others as special characters (<, >, etc.) preventing them from being interpreted as code.

$newcomment[] = htmlspecialchars($_POST[“name”]);

$newcomment[] = htmlspecialchars($_POST[“topic”]);

$newcomment[] = htmlspecialchars($_POST[“message”]);

Solution

A simple solution to get rid of all those errors in this example is to wrap the code in add_comment.php and view_comments.php inside the following if statement:

Dimoff

I am a student of IT, a freelance web designer / developer and a tech writer. I deal with both front-end and back-end stuff. Whenever I am not in front of an Internet-enabled device I am probably reading a book or traveling