Nginx, SSL & php5-fpm on Debian Wheezy

October 11th, 2014

I decided to take a break from my love affair with Apache and set up a recent development project on Nginx. I’ve seen nothing but good things in terms of speed and performance from Nginx. I decided to set up a LEMP server (Linux, Nginx, MySQL, PHP), minus the MySQL as it’s already installed on my VM host server, and plus SSL. Here’s the full setup tutorial on Debian Wheezy:

Step #1 – Installing the packages

apt-get install nginx-extras mysql-client
apt-get install php5-fpm php5-gd php5-mysql php-apc php-pear php5-cli php5-common php5-curl php5-mcrypt php5-cgi php5-memcached

MySQL can be installed into the mix with a simple:

apt-get install mysql-server

Read the rest of this entry »

MySQL Master-Master Replication, Heartbeat, DRBD, Apache, PHP, Varnish MegaHOWTO

October 8th, 2014

I created this HOWTO while building a new development environment today. The intention is to take a single Apache2/Varnish/MySQL environment and scale it to two servers, with one effectively a “hot-standby” – increase redundancy and continuity whilst maintaining current performance. This HOWTO is based on Linux Debian-76-wheezy-64-minimal 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64

Our current server has IP 192.168.201.1/24 and our new server has IP 192.168.201.7.

Section #1: Set up MySQL Master/Master Replication


First, we’ll set up MySQL master to master replication. In this configuration, data can be written and read from either host. Bear in mind that issues may exist with autoincrement fields when written to at the same time. There are other caveats with replication so ensure to research them along with how to deal with corruption and repair before considering this setup for a live application. Also be sure to be using the same version of MySQL on both servers – this may not always be necessary, however unless you are very familiar with any changes between versions, not doing so could spell disaster.

Read the rest of this entry »

Blind SQL injection with sqlmap

December 11th, 2013

When an SQL injection vulnerability is attacked, the application will often display error messages from the database. We are able to retrieve the data we are trying to retrieve from the database by constructing a query that ensures it ends up in the error message passed back to us. This is the method we used in the previous SQL injection example. This is a very quick and efficient way of mining data through SQL injection vulnerabilities. Sometimes, code is constructed in a way that whilst it is vulnerable to injection, it’s not possible to get the data we want returned by the database. Consider the following code –

<?php
        $link = mysql_connect("localhost", "twl", "XXXX");
        mysql_select_db("twl");

        $sql = "SELECT * FROM wp_posts WHERE ID='" . $_GET['id'] . "';";
        $res = @mysql_query($sql);
        if (@mysql_numrows($res))
        {
                echo "We have rows!\n";
        } else {
                echo "We have no rows.\n";
        }
?>

Read the rest of this entry »

SQL injection with sqlmap

December 10th, 2013

sqlmap is web application & database penetration testing tool that automates detecting and exploiting many types of SQL injection flaw, and then taking over the database server. It’s able to detect a huge range of injection types.

Let’s take the following code –

<?php
        $link = mysql_connect("localhost", "twl", "XXXX");
        mysql_select_db("twl");

        echo "This is a page\n";
        $sql = "SELECT * FROM wp_posts WHERE ID='" . $_GET['id'] . "';";
        $res = mysql_query($sql);
        mysql_free_result($res);
        echo "This is some text\n";
        mysql_close($link);

?>

Read the rest of this entry »

Location header is optional not mandatory

September 13th, 2013

I thought I’d write a short post about this issue as I’ve seen it come up a couple of times in PHP code audits. The incorrect assumption is that the Location header somehow forces a browser or forces execution to move elsewhere.

Take a look at the following code sample –

<?php
	$logged_in = 0;

	/* Do login verification routine here */

	if (!$logged_in)
	{
		/* User is not logged in and shouldn't be here */
		header("Location: /index.php");
	}
	/* User is logged in */
	echo "Secret Member Content";
?>

Read the rest of this entry »

PHP Local and Remote File Inclusion (LFI, RFI) Attacks

August 15th, 2013

PHP supports the ability to ‘include’ or ‘require’ additional files within a script. If unsanitized data is passed to such functions, an attacker may be able to get remote code execution access to the server. A typical include block might look something like this:

<?php
require("config/settings.inc.php");
require("lib/db.lib.php");
require("lib/parser.lib.php");
include("contrib/users/user.contrib.php");
die("This is a test");
?>

Now, it’s also possible to dynamically require or include files based on variables or user input, say for example:
Read the rest of this entry »

CMS Development

August 16th, 2010

What is a CMS?

A CMS is a Content Management System. WordPress, Joomla, Drupal and osCommerce are 4 popular PHP content management systems that we work with. A CMS at minimum provides you with a user friendly means of managing your site and it’s content.

CMS Development

Depending on the requirements for your CMS development project, there are two directions to consider:

  • Take an existing CMS, and build on it to meet your needs. Taking WordPress as an example, the possibilities and options for modification are infinite. This is achieved through the development of themes and plugins. There is really no limit to the customization that’s achievable with most popular CMSs and so bespoke CMS development is usually reserved for a project where the majority of functionality would need to be manually built irrespective of existing code and modules.
  • If your needs aren’t reasonably met by an existing CMS, then it may be more time and cost effective to build a CMS from the ground up. With this route, you also get to put exactly what features you want, where you want. We have a base framework that we usually build start our CMS development with. It contains the basics for rich page and text creation, article creation and SEO friendly URL management.

In reality, the term ‘CMS’ has been stretched to cover frameworks and beyond. Whilst strictly speaking a CMS is any system that allows content to be managed, the term also describes fully fledged online site management and development platforms.
Read the rest of this entry »

Redirecting all HTML files to PHP files

July 18th, 2010

Let’s say that you want to rename all your HTML files to PHP files to begin PHP Programming. However, you don’t want to lose all your inbound links to your HTML files. Here’s a quick and easy way to automatically convert all .html incoming addresses to .php files on your server, allowing you to switch to PHP and also keeping all your existing .html links working.

Create a .htaccess file, and enter:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*).html $1.php [R=301,NC]

This creates a permanent working 301 redirect (Search Engine Friendly) to your new .PHP file.

Securing PHPMyAdmin and SQL

July 14th, 2010

PHP is of course a valuable tool, and PHPMyAdmin is an equally valuable asset for those that don’t like command line administration. The problem is that because it’s a valuable tool, it’s a security exposure. As a website security consultant, I see the problem often: people don’t secure the one thing that, if accessed by a malicious party, can give carte blanche for destruction.

One simple way to secure your installation is to slightly modify your config.inc.php file:

Look for this line:

$cfg[‘Servers’][$i][‘auth_type’] = ‘config’;

Change “config” to “http”. By doing this, you will require that the database information (username and password) be entered prior to accessing PHPMyAdmin. Of course, this only addresses attacks over the web. If someone tries to remotely connect to your database and knows the root password, or the credentials for any of your database, then you’re still vulnerable.

One way to address the security of your config.inc.php file is to secure the directory that it’s stored in. This is especially important if you should be on a shared server.

Of course, there is still the matter of your SQL port, 3306, being open to remote attacks. The solution to this problem can be found in the /etc/my.cnf file.

You need to add this line to make it so that only your server can connect to the SQL server.

Ensure that it’s under the “[mysqld]” section:

bind-address = 127.0.0.1

This sets it so that the SQL daemon only listens for connections locally, i.e. on your server. Anyone who tries to connect remotely will be denied. Now, the argument could be made that you could also try to add “skip-networking” to your my.cnf file, and then specify the path to your socket file, but you still need a way to administer your SQL, preferably via SSH. By adding the “bind-address” command, you can do just that.

The name of the game is security, and assumption. You have to assume that everyone’s out to attack you. If you think like that, you’ll narrow down all the ports that are exposed, and secure your server. Your SQL server is, like your DNS server, vital. It most likely powers your site. If the database is attacked, the damage can be considerable. Do understand that if a hacker is intent enough, they will find a way in, but by making it as difficult as possible, you reduce the chances of that happening.

Disabling phpinfo

July 6th, 2010

The phpinfo() function is a very powerful one; through it, you can learn quite a lot about your PHP installation. The problem is, so can someone else. PHP, of course, is a very powerful application, but it is also a very powerful tool that can be used to compromise your server’s security if used by the wrong person.

The best way to combat the potential problems that someone using phpinfo() can cause is, of course, to not have a script accessible to the public that runs the command. Sometimes, during the testing process, you need to upload a simple script that executes the command, for your own reference. It’s simply phpinfo(), inserted into PHP brackets.

If you should forget to delete the script when you’re done, it’s possible that someone who’s intent on compromising your system could try to find the page, especially if you name it something simple such as test.php or phpinfo.php. If you’re the extremely cautious sort, there’s something you can do.

You can completely disable phpinfo(), and then re-enable it later should you need to perform more testing. To do this, find your php.ini file. The location can be found by executing the phpinfo() command, as the precise location depends on your operating system and distribution. Once you’ve found the file and opened it with your favourite text editor, insert the following command:

disable_functions = phpinfo

Reboot your server, and you’re secure. Just remember to re-enable it if you should need to do further testing on PHP.

There are all sorts of things you can do to make your server secure. Securing PHP is one of the most vital things, because PHP can be used a gateway into your system, even being used to perform SQL injection attacks. Of course, one would really have to know what they’re doing to gain access to your system, but you never want to give out too much information. By disabling phpinfo(), you can accomplish that, at least as far as PHP is concerned.

PHP Developer – Base64

July 3rd, 2010

Base64 is a type of encoding (NOT encryption). Essentially, you can take any binary data and encode it into one of 64 characters for more information on the encoding process and how this is done, visit http://en.wikipedia.org/wiki/Base64.

It is useful for a variety of things, specifically encoding non standard characters that may not be safe to pass around such as in a browser address bar or in a plaintext email..

Here’s one example..

<?php
$obj = new stdClass();
$obj->a = “test”;
$obj->b = “string”;
$obj->c = 12345;
$output = base64_encode(serialize($obj));
echo $output;

?>

This returns ‘Tzo4OiJzdGRDbGFzcyI6Mzp7czoxOiJhIjtzOjQ6InRlc3QiO3M6MToiYiI7
czo2OiJzdHJpbmciO3M6MToiYyI7aToxMjM0NTt9’

We could now pass this as an HTTP safe string between pages; decoding using $v = unserialize(base64_decode());

This is obviously not an optimal way of storing or passing this example data between various pages however is one example of how base64 encoding can be used.

Cross Site Scripting XSS

June 30th, 2010

As a website security consultant, Cross Site Scripting or XSS vulnerabilities are something that I see just as often as the always popular SQL Injection attack.

Cross Site Scripting seems to have originally meant, placing some malicious code on your victim site, that would pull code (usually javascript, but sometimes vbscript) from another malicious domain. Each client that visited the victim site, would end up unknowingly having 3rd party malicious script code executed on his own browser. Now, it has become a term used to describe any type of malicious scripting attack.

The first example is a simple one. Many sites allow user comments. A user could quite easily enter:
This is my comment!<script type=”text/javascript”>
alert(“script!”);
</script>

Any user that hits this affected page, will now see a popup box with the text “script!”. The user could also just as easily have entered a script source of http://www.nastydomain.com/nastyscript.js which will be downloaded and executed.

The second option is to place some javascript code that steals the user’s cookies for that particular site, and then post them to a 3rd party site. His cookies may contain a login and password, or more likely a login hash. The attacker can then use these cookies to hijack the user’s session, and access possible sensitive areas of a site under that user’s account, as that hijacked user.

Fortunately the solution is simple. Either use htmlentities() to ‘escape’ HTML entities, i.e. converting <‘s to &lt; etc. Or, use strip_tags, to remove all HTML tag input.

PHP, MySQL and memcached

June 24th, 2010

According to memcached is a distributed object memory caching system. It can be used to set and get data by keys by any application that supports sockets.

As a website security consultant I advise you to ensure that your memcache server runs on 127.0.0.1 only and that you secure your server. Anyone with access to the server can telnet to the server’s local interface and get/set your memcache data.

I’ve used memcached for a number of PHP/MySQL projects, where I want greater cache control on database queries, than just relying on MySQL’s inbuilt caching abilities.

Now, whilst memcached should not be used to mask bad database design and optimization, or badly written SQL queries, it can help dramatically with queries that simply take a long time and have already been optimized as far as possible.

Assume that you had a simple database query wrapper:
Read the rest of this entry »

PHP – Passing Variables By Reference and By Value

May 19th, 2010

By default in PHP, variables are passed around ‘by value’. i.e.

<?php
function increment($i)
{
$i++;
return $i;
}

$a = 10;
$b = increment($a);
?>

At this point, $a remains as 10, however $b is now 11. $b = increment(10); works just the same, and you can assign 10 back to the original variable with: $a = 10; $a = increment($a); This is called passing variables by value. i.e. I am passing the VALUE of $a to the increment() function.

We also have the option of passing variables by reference. For programmers that have worked with C before, this is a ‘pointer’.

<?php
function increment(&$i)
{
$i++;
return $i;
}

$a = 10;
increment($a);
echo “a has now become: ” . $a;
?>

In the case above, I am passing $a by reference.  i.e. the increment() function is operating on the variable $a rather than the value of the variable. Certain things that shouldn’t work get fixed by PHP, i.e. increment(&$a). By the time the increment() function gets to it, it is actually passing the reference to the reference to the variable. Certain other things will fail entirely, i.e. increment(10); will give “Fatal error: Only variables can be passed by reference”

PHP Programmer – Remove characters from the end of a string

May 18th, 2010

<?php
$s = “This is my string”;
$s = substr($s, 0, strlen($s)-2);
?>

This trims 2 characters from $s, resulting in “This is my stri”;