Archive for the “php” Category
Welcome to part one of the ‘zen of secured shared hosting’ series.
In this part I will be covering the concepts of secured shared hosting, and why you as a shared hosting provider should be taking steps to ensure this is how you deploy your hosting environments.
Let’s first take a typical L.A.M.P setup:
PHP Compiled from source as apache module. mySQL installed from RPM or update package (yum / up2date). HTTPD installed as RPM or update package (yum / up2date).
Please note at the time of writing if you yum / apt-get / up2date install your PHP package you will have varying results when attempting to compile and install suPHP, as such grab the source code from php.net, and follow this series.
As a shared hosting provider lets say you have 5 clients all hosted from the one server, each client using vsftpd is chrooted() into their home directory, and their ssh access disabled, supposedly secure enough.
Unfortunatly not so, due to the L.A.M.P configuration the ‘apache’ user needs a minimum of read and execute permissions over all the PHP files on the system, why is this a problem?
This is a problem largely due to human nature of the client, your ‘joe bloggs’ client doesn’t care about the technical aspects of web hosting or websites, they just want an easy pretty interface to get their corner of the internet online, downloading something like drupal or joomla.
Now this isn’t a dig at open source CMS, this is an insight into human nature, look at the changelog for any open CMS and you will see ’security fixes’, unfortunatly all ‘joe bloggs’ cares about is that their website is working, and this is wher things take a turn for the worse.
Joe Bloggs never updates his open CMS platform, meaning any vulnerabilities patched in subsequent releases are still exploitable on his website, worst case scenario that this is an XSSI (Cross Server Script Includes) vulnerbility.
An attacker finds this website and idetifies the security hole, using XSSI to install a PHP interactive shell, giving the attacker SSH like access to the hosting environment, most people at this point think so the attacker has compromise one site … so what we can restore that site from backups and it’s only one site that’s affected, the other 4 users either do not use open CMS or are up to date with all the security patches.
Well that’s where you would be wrong, with the hosting setup outlined above the SSH like PHP shell is now running as the apache user, meaning the attacker can go anywhere and read anything apache can, and with the hosting setup oulined above that mean reading things like datbase connection files, suddenly all the clients on the hosting environment have their websites compromised as the attacker gains mySQL access and starts changing content on thewebsites, despite the fact that the other 4 sites themselves were never exploited.
One clients error just became a cascading exploit on your hosting platform, now make that a more realistic platform say 30 clients on the box, some are online shops, the issue just became a whole lot bigger there is lost revenue due to downtime of the shop sites, and worse still the attacker now has access to any customer details those shops were storing! but it’s not Joe Bloggs that’s accountable it’s YOU as the hosting provider, you can take steps to prevent one exploited site becoming 30, and this web series will tell you host to do it.
coming in part 2:
an introduction to suPHP compiling php as a cgi binary, and why you need to do so
No Comments »
I am in the process of contacting charitable organisations for project “sanctimonia”.
The project is a wordpress plugin to aid publishers to allow their content subscribers to donate to registered charities.
I had a paypal link saying donate to me on the right of this site at one point …. but then I thought to myself why … It would of gone on gadgets or caffeine products, why not let my readers donate to charities via my blog?
Currently I have contacted:
globalangels NSPCC Hope House
And am currently awaiting their reply.
Any suggestions or names of charities to add?
PLEASE LEAVE A COMMENT!
Cheers
3 Comments »
Whilst I wait for a reply here: http://community.flowplayer.org/node/1051
I am making version 0.1 of this plugin available.
Installation
- Unzip wpfp
- Upload to /wp-content/plugins/
Usage
- Make a new directory in the root of wordpress called “videos”
- Upload streaming media (.flv, .mp4) to /videos/
- In the wordpress panel (/wp-admin/) under plugins activate “Flowplayer for Wordpress”
- Write a post and add the tag (see example: here) *
* Where “media.flv” is your video file, 600 and 450 are the width and height to make the flash player in the page.
Notes
The version of flowplayer provided with this plugin is version 2.2.2 and is provided under the GPL license as specified by the authors of flowplayer (http://flowplayer.org/).
I am not the author or owner of flowplayer as such all copyright for flowplayer remains that of the respective parties.
I am the author of the included flowplayer.php file and have made this available under the Creative Commons license similar to the GPL: http://creativecommons.org/licenses/by-nc-sa/2.0/uk
If the authors of flowplayer object to the distribution of their works under the original GPL license, I reserve the right to remove the download of this plugin*
* Whilst GPL does allow for me to legally redistribute the “free software” under the original license.
Remember this is version 0.1 as such this only uses the flowplayer minimum embed code, support for playlists etc has not yet been added, depending on the popularity of this plugin I may continue to work on it to provide full access to the flowplayer features (http://flowplayer.org/player/advanced.html).
Please leave a comment with feedback.
wpfp Download
As pointed out by Mons PHP 4.x does not support the intial release of this plugin.
6 Comments »
Posted by: Buzz in hacking, php, tags: php, portscan
This is another _old_ proof of concept I had several years ago, you can infact use PHP to scan ports, bare in mind the legality of this is still somewhat _hazy_ therefore if you must portscan I recomend you only do so on Systems you operate.
Disclaimer: This tutorial is provided for informational purposes only.
-
-
<?PHP
-
/**
-
* Proof of concept class for port scanning in PHP
-
* @author David Busby
-
*
-
* The MIT License
-
*
-
* Copyright (c) 2005-2008 David Busby
-
*
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
-
* of this software and associated documentation files (the "Software"), to deal
-
* in the Software without restriction, including without limitation the rights
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-
* copies of the Software, and to permit persons to whom the Software is
-
* furnished to do so, subject to the following conditions:
-
*
-
* The above copyright notice and this permission notice shall be included in
-
* all copies or substantial portions of the Software.
-
*
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-
* THE SOFTWARE.
-
*/
-
class port_scan
-
{
-
private $result_stack = array();
-
private $out = ”;
-
-
public function __construct($tgt = ‘127.0.0.1′, $protocol = ‘tcp’, $start_port = 80, $end_port = 90) {
-
-
$str = ‘—– PORT SCAN ‘.(($end_port - $start_port) + 1).‘ ‘
-
. strtoupper($protocol). ‘ PORT’. (((($start_port - $end_port) + 1) > 1 )? ‘S’ : ”)
-
. ‘ —–’;
-
$this->push_result_stack($str);
-
$str = ‘HOST: ‘.$tgt;
-
$this->push_result_stack($str);
-
$str = ‘DATE: ‘. date(‘r’);
-
$this->push_result_stack($str);
-
$this->run_scan($tgt, $protocol, $start_port, $end_port);
-
$this->output_results();
-
-
}
-
-
private function run_scan($tgt, $protocol, $start_port, $end_port) {
-
-
switch($protocol) {
-
case ‘tcp’:
-
$host = ‘tcp://’;
-
break;
-
case ‘udp’:
-
$host = ‘udp://’;
-
break;
-
default:
-
$host = ‘tcp://’;
-
break;
-
}
-
-
if($start_port != $end_port) {
-
while($start_port <= $end_port) {
-
//using @ to suppress error on can not connect
-
@ $fp = fsockopen($host, $start_port, $errno, $errstr, 0.5);
-
$this->record_result($start_port, $fp);
-
$start_port++;
-
}
-
} else {
-
//using @ to suppress error on can not connect
-
@ $fp = fsockopen($host, $start_port, $errno, $errstr, 0.5);
-
$this->record_result($start_port, $fp);
-
}
-
}
-
-
private function record_result($port, $open = false) {
-
$res = ”;
-
switch($open) {
-
case true:
-
$res = ‘OPEN’;
-
break;
-
case false:
-
$res = ‘CLOSED’;
-
break;
-
}
-
$this->push_result_stack(‘PORT ‘.$port.‘ ‘.$res);
-
}
-
-
private function push_result_stack($str) {
-
-
}
-
-
private function output_results() {
-
-
foreach($this->result_stack as $key => $data) {
-
$this->out .= $data."\n";
-
}
-
-
}
-
}
-
-
$scan = new port_scan();
-
-
?>
-
Sample output:
----- PORT SCAN 11 TCP PORTS -----
HOST: 127.0.0.1
DATE: Thu, 19 Jun 2008 08:43:13 +0100
PORT 80 OPEN
PORT 81 CLOSED
PORT 82 CLOSED
PORT 83 CLOSED
PORT 84 CLOSED
PORT 85 CLOSED
PORT 86 CLOSED
PORT 87 CLOSED
PORT 88 CLOSED
PORT 89 CLOSED
PORT 90 CLOSED
PORT 87 CLOSED
PORT 88 CLOSED
PORT 89 CLOSED
PORT 90 CLOSED
NOTE: The current timeout is 0.5s per socket meaning you have a potential runtime of (($endport - $start_port) * 0.5) seconds. Make sure this does not excced your max execution time, or in the construct add:
-
-
$time = (($endport - $start_port) * 0.5) + 5;
-
-
This will increased the max execution time with a 5 second buffer.
Please also note in most cases of “shared” hosting you will not be able to crate socketed connections, they will either be blocked by the hosting providers firewall, or disabled at the php runtime, therfor not giving an accurate result.
Again please note this is a proof of concept, you may freely distribute the code under the MIT licence
No Comments »
Posted by: Buzz in Acies, Linux, php, tags: Acies, php
Well the XML rendering API has been giving me no end of head ache during the development … the end is in sight however.
Acies is moving along nicely, I am debating the use of globals over extended classes.
At this moment all objects are callable using the $this->CLASS->method(); this is fine in the current model of parent executing child, this does make accessing the parent objects from the child classes, much more difficult, however I want to avoid the use of many “Global” declarations …
*sigh* … Well as I strive to get this framework done no doubt there will be much more “hairpulling” …
No Comments »
So I thought maybe it’s time for an update.
The project is moving, albeit slowly, and I realy do not like the current PHP implementation, I want to move towards a C++ version, and I will do so as soon as I figure out how to do CLI “update/refresh” …
i.e. See how W GET works with the progress bar and kbps all in text, I have NO idea how that works.
I am also looking at adding RRDTOOL support.
Anyway here’s the current sample output:
[buzz@server01 .sysadmin]$ ./dbstat.php summary
----- mySQL dbStat v1.1 Summary Report-----
10 Databases checked
exampledb1: 13 tables (0 VIEWS 13 INNODB 0 MYISAM) 0.77MB DATA 0.64MB INDEX
exampledb2: 15 tables (0 VIEWS 14 INNODB 1 MYISAM) 0.22MB DATA 0.19MB INDEX
exampledb3: 62 tables (0 VIEWS 0 INNODB 62 MYISAM) 0.45MB DATA 0.5MB INDEX
exampledb4: 3 tables (0 VIEWS 0 INNODB 3 MYISAM) 0.02MB DATA 0.01MB INDEX
exampledb5: 4 tables (0 VIEWS 0 INNODB 4 MYISAM) 0.02MB DATA 0.01MB INDEX
exampledb6: 4 tables (0 VIEWS 0 INNODB 4 MYISAM) 39.81MB DATA 22.22MB INDEX
exampledb7: 3 tables (0 VIEWS 0 INNODB 3 MYISAM) 0.04MB DATA 0.01MB INDEX
exampledb9: 599 tables (8 VIEWS 1 INNODB 590 MYISAM) 8702.79MB DATA 4559.42MB INDEX
exampledb10: 22 tables (0 VIEWS 21 INNODB 1 MYISAM) 6.66MB DATA 2.26MB INDEX
Detail:
----- START mySQL dbStat v1.1 Detail Report: exampledb9 -----
exampledb9: 599 tables (8 VIEWS 1 INNODB 590 MYISAM) 8893.7MB DATA 4583.54MB INDEX
--- Table Index Ratio Report index:data (457 Tables) ---
exampledb9.table1: 315.0769:1
exampledb9.table2: 315.0769:1
exampledb9.table3: 157.5385:1
exampledb9.table4: 146.2857:1
exampledb9.table5: 128.0000:1
… (I’ve truncated this very long list)
--- Table Fragmentation Report (2 Tables) ---
exampledb9.atable: 0.6067
exampledb9.atable: 0.1285
--- Table Low Size Report (47 Tables) ---
exampledb9.atable: 0 bytes
exampledb9.atable: 0 bytes
exampledb9.atable: 0 bytes
exampledb9.atable: 0 bytes
exampledb9.atable: 0 bytes
… (Truncated again)
--- Table Detail Report (591 Tables) ---
SCHEMA.TABLENAME: ENGINE: ROWS: TOTAL SIZE (MB): DATA SIZE (MB): DATA PERCENTAGE OF TOTAL (%): INDEX SIZE (MB): INDEX PERCENTAGE OF TOTAL (%): LAST UPDATE TIME
exampledb9.a_table: MyISAM: 28906414: 3272.43531003: 3031.82567548: 92.6474: 204.63809450: 7.3526: 2008-05-22 11:59:42
.. (truncated)
----- END mySQL dbStat v1.1 Detail Report: exampledb9 -----
No Comments »
Now this one was annoying!
Whilst adding imap support to a php 5.2.2 installation running from a red hat linux 4 distro, I kept getting the same error, when running my custom config script.
/usr/bin/ld: cannot find -lltdl
collect2: ld returned 1 exit status
make: *** [libphp5.la] Error 1
Very strange as the files were there!
[root@dev01 ~]# ldconfig -p |grep ltdl
libltdl.so.3 (libc6) => /usr/lib/libltdl.so.3
libguile-ltdl.so.1 (libc6) => /usr/lib/libguile-ltdl.so.1
So guess what the problem was … PHP’s make script.
Note the “/usr/lib/libltdl.so.3″ this as it would turn out was a symlink to “/usr/lib/libltdl.so.3.1.0″
So just by adding out own symlink without the version number “ln -s /usr/lib/libltdl.so.3.1.0 /usr/lib/libltdl.so” voila the compile runs perfectly!
Another obscure bug *sigh*, ah well at least I can play with the imap extentions now
2 Comments »
Acies Latin: a sharp edge or point; mental acuity, sharpness of vision
A fitting name I thought for my new project, rather a name of a framework (yes I actually intend to finish this one!), initially the framework will comprise of code I have written over the years (brought in-line with PHP5).
More details will appear @ http://acies.saiweb.co.uk as I complete the modules.
There are several projects lined up awaiting completion of Acies, once in place I should be able to turn these around quite rapidly.
More Soon
No Comments »
Due to latency issues, and the lack of multi site support I have ditched my old web-host.
In favour of an all singing all dancing NEW ONE! nativespace thus-far I have had excellent ticket turn around (all in 30 mins or less), and my initial sales enquiry (consisting of a lot of lengthy questions) responded to in …. 6 minutes!
So thus far definitely on my recommended list
1 Comment »
To often I get passed code to review that quite frankly is so full of holes it wouldn’t make an adequate sieve…
So in this quick blog I outline a few simple and easily implemented steps to ensure as you start out in the world of PHP, your first site isn’t hacked within 5 minutes, leaving you a whimpering wrek …
PHP DON’T EXAMPLE 1:
Passing RAW globals to mysql!
i.e.
$sql = "SELECT * FROM users WHERE email='.$_GET['email'].”‘ and password=’”.$_GET['password']“‘;”;
$result = mysql_query($sql);
So what is wrong with the above? SQL INJECTION welcome to a world where people want to break your website, simply because they can …
I am not going to add more description, just click through to the wiki pedia entry linked above …
To avoid this PHP comes with two functions mysql_escape_string() and mysql_real_escape_string()
An example taken from the mysql_real_escape_string() page:
Example#2 An example SQL Injection Attack
<?php
// Query database to check if there are any matching users
$query = “SELECT * FROM users WHERE user=’{$_POST['username']}’ AND password=’{$_POST['password']}’”;
mysql_query($query); // We didn’t check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] = ‘aidan’;
$_POST['password'] = “‘ OR ”=’”;// This means the query sent to MySQL would be:
echo $query;
?>
The query sent to MySQL:
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
This would allow anyone to log in without a valid password.
So in summary READ the mysql_real_escape_string() page, and even if you don’t implement the “best practice” example on that page PLEASE make sure you at least escape $_SESSION $_GET $_POST inputs with a mysql escape function!
3 Comments »
|