Admin Life Errors, Fixes, and Encounters

27Sep/11Off

Install eAccelerator on FreeBSD – High Performance PHP

eAccelerator is a PHP caching system, it caches frequently used portions of PHP files to RAM to increase performance. This is especially great on high traffic websites such as forums. Performance gains of up to 1000% have been seen with eAccelerator. The following tutorial is how to install eAccelerator on FreeBSD using ports.

Using ports, compile and install:


cd /usr/ports/www/eaccelerator
make install clean

Make modifications to php.ini:

If you are using Zend:

vi /usr/local/Zend/etc/php.ini (this is the default location)

Add the following:

zend_extension="/usr/local/lib/php/20020429/eaccelerator.so"
eaccelerator.shm_size="32"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"

Comment out the following lines:

zend_extension_manager.optimizer=/usr/local/Zend/lib/Optimizer-2.5.7
zend_extension_manager.optimizer_ts=/usr/local/Zend/lib/Optimizer_TS-2.5.7

If you are not using Zend optimiser the add the following to your php.ini:

extension="eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

Create the caching directory:

mkdir /tmp/eaccelerator
chmod 0777 /tmp/eaccelerator

look inside /tmp/eaccelerator/ to see if the cache files were created.

Filed under: Code, FreeBSD, PHP No Comments
8Jun/11Off

PHP MySQL injection

Here is an example of how an SQL injection that was found, monitored, and fixed!

When dealing with a large website with legacy code sometimes it's not possible to check every query after one starts.

One day while reviewing a new clients slow quries via MySQL. I started to notice these types of quries showing up.

# [email protected]: test_db[test_db] @ db.domain.com [12.13.14.15]
# Query_time: 0 Lock_time: 0 Rows_sent: 1 Rows_examined: 48648
select * from serv_main where id = 71261 and 3=8 union select 1,2,3,concat(0x232425,ifnull(`idClient`,0x4E554C4C),char(9),ifnull(`username`,0x4E554C4C),char(9),ifnull(`pass`,0x4E554C4C),char(9),0x252423),5,6,7,8,9,10,11,12,13,14,15,16 from `test_db`.`private` where idClient>2119021 limit 16215,1 --;

# [email protected]: test_db[test_db] @ db.domain.com [12.13.14.15]
# Query_time: 1 Lock_time: 0 Rows_sent: 1 Rows_examined: 48654
select * from serv_main where id = 71261 and 3=8 union select 1,2,3,concat(0x232425,ifnull(`idClient`,0x4E554C4C),char(9),ifnull(`username`,0x4E554C4C),char(9),ifnull(`pass`,0x4E554C4C),char(9),0x252423),5,6,7,8,9,10,11,12,13,14,15,16 from `test_db`.`private` where idClient>2119021 limit 16217,1 --;

Knowing the table serv_main I knew the developer that wrote that code did not use a UNION.
After a few moments of thinking what was going on I tailed Apaches access log and confirmed what I thought.

120.2.194.136 - - [1/Jan/2010:10:08:40 -0500] "GET /viewAd.php?id=71261%20and%203%3D8%20union%20select%201,2,3,concat%280x232425,ifnull%28%60idClient%60,0x4E554C4C%29,char%289%29,ifnull%28%60username%60,0x4E554C4C%29,char%289%29,ifnull%28%60pass%60,0x4E554C4C%29,char%289%29,0x252423%29,5,6,7,8,9,10,11,12,13,14,15,16%20from%20%60test_db%60.%60private%60%20where%20idClient%3E2119021%20limit%2034642,1%20-- HTTP/1.1" 200 1093 "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"

It was an SQL Injection attack. so I did the next logical step (to me at least). Block the offender.

I did this by adding his IP to the .htaccess file along with a bigger subnet block.
Order allow,deny
deny from 120.2.194.136
deny from 120.2.194.
allow from all

Now that the Injections had stopped, the next step was to figure out where it was done, how it was done, and how to fix it.

WHERE was it done)
That was easy to find, it's right there in the access log viewAd.php

How was it done)
$sql = "select * from serv_main where id = " . $_GET['id'];
$result = mysql_query($sql);

Fix)
That was the easy part, and the hard part.

The EASY part was just to just use mysql_real_escape_string.

we have 2 quick options here.

Option 1.

$_GET['id'] = (int) $_GET['id']; //cat whatever is passed into id as an integer.

Option 2.

$sql = "select * from serv_main where id = " . mysql_real_escape_string($_GET['id']); //escape user input
$result = mysql_query($sql);

The HARD part, fix the whole site...
Not having time to check 1000's of quries, here was what I did in a 30 mintue span.

1) include a function somewhere in a global include that can clean all input (or cast all input)
a good place was in our db_include.php file.

function sanitize_user_input(&$input) {

$int_keys = array ('id', 'item', 'item_id' );

foreach ( $int_keys as $key ) {
if ( isset($input[$key]) ) {
if ( !empty($input[$key]) && !is_numeric($input[$key]) )
$input[$key] = (int) $input[$key];
}
}
}

if (isset($_GET)) sanitize_user_input($_GET);

The hard part was easier than I thought.

But the truly hard part started, going though the 1000's of queries to fix them.

Some interesting points and notes.

#http://www.asciitable.com/
# 0x232425 = #$%
# 0x252423 = %$#
# 0x4E554C4C = NULL
# 0x4E554C4C = NULL
# CHAR(9) = Tab
# CHAR(10) = Line feed
# CHAR(13) = Carriage return
select concat(0x232425,
ifnull(`idClient`,0x4E554C4C),
char(9),
ifnull(`username`,0x4E554C4C),
char(9),
ifnull(`pass`,0x4E554C4C),
char(9),
0x252423)

Filed under: Errors, MySQL, PHP No Comments
6Aug/10Off

Online wedding planner

http://ultimateweddingplanner.ca/ that's the new site I've been working on... it's a free online wedding planner software, wedding planning, guests, seating advice, etiquette, budget, vendors, timetable, invitations.

If it helps anyone, it would have been worth the time doing a wedding planner.

Filed under: Code, General, PHP No Comments
24Jan/10Off

PHP

Just upgraded PHP or change hosting providers and your code seems to have stopped working? Look at php.ini (usually found in /usr/local/etc/php.ini) There is a section that disables short tags for future compatibility.

If any of your code used instead of well, your code needs to be changed. Or better yet, enable short tags in php.ini, restart apache and you should be good to go.

21Jan/10Off

memcached php mysql freebsd

Too many slow queries running on MySQL and some can not be fixed without a major change? Here's a potential solution, cache it!

Step 1) Install memcache, in this case on FreeBSD

1. cd /usr/ports/databases/memcached; make install clean
2. vi /etc/rc.conf, and add memcached_enable="YES"
3. /usr/local/etc/rc.d/memcached start
4. run "netstat -an" to check that a process is listening on TCP 11211
5. cd /usr/ports/databases/pecl-memcache ; make install clean
6. /usr/local/bin/php -i | grep -i 'memcache'
7. Play with memcached in PHP scripts

step 2)
use memcache in your scripts!

Filed under: MySQL, PHP No Comments