A kind of vulnerability allows to open and include local files. For example, the following code contains local file inclusion (LFI) vulnerabilities:
<?php $file = $_GET['file']; // "../../etc/passwd\0"
if (file_exists('/home/wwwrun/'.$file.'.php')) {
// file_exists will return true as the file /home/wwwrun/../../etc/ passwd exists include '/home/wwwrun/'.$file.'.php';
// the file /etc/passwd will be included
} ?>
Through this code, you will be able to control the parameters file. When the file has a value of “../../etc/passwd”, PHP will access the /etc/passwd file. But before that you need to solve a small problem:
include ‘/home/wwwrun/’.$file.’.php';
This will connect the variables and strings. If the value of $ file that the user controls is “../../ etc/passwd”, this code is equivalent to
include ‘/home/wwwrun/../../etc/passwd.php';
The included file is “/etc/passwd.php”, but this file does not actually exist.
PHP kernel can be implemented with C language, so a string from C language is used here. When we connect strings, 0 byte (\x00) will be a string terminator. Therefore, the attacker only needs to add a 0 byte after the file variable to truncate the string:
../../etc/passwd\0
We only need the UrlEncode if this is done through the web:
../../etc/passwd%00
The string truncation technique is the most commonly used technique in file inclusion.
But in general web applications, users do not need to use 0 byte, so they could disable 0 byte, for example
But this may not solve all problems. Domestic security researcher Cloie discovered a technique to effect truncation without using 0 byte: making the operating system limit the maximum length of a directory. Directory strings, 256 bytes under Windows, 4096 bytes of Linux, will reach the next maximum value and the subsequent characters beyond the maximum length will be discarded. How to construct such a long catalog? The “./”will help. For example
./././././././././././././abc
or
/////////////////abc
or
../1/abc/../1/abc/../1/abc
In addition to the four functions mentioned earlier, many other functions, which can manipulate files, are likely to create vulnerabilities in PHP. Although in most cases PHP code may not be executable, the consequence of reading files with sensitive data is also serious.
fopen()
fread()
……
File inclusion vulnerability can allow read access to sensitive files or server-side script source codes, which can be a foundation for executing further attacks.
In this case, using “../../../” to return to the parent directory is known as path traversal. Common path traversals can also bypass server-side logic through various encoding:
- %2e%2e%2f is equal to../
- %2e%2e/is equal to../
- ..%2f is equal to../
- %2e%2e%5c is equal to..\
- %2e%2e\ is equal to..\
- ..%5c is equal to..\
- %252e%252e%255c is equal to..\
- ..%255c is equal to..\ and so on.
Here are a couple of web container–supported encoding:
- ..%c0%af is equal to../
- ..%c1%9c is equal to..\
CVE-2008-2938 is a path traversal vulnerability in Tomcat.
If context.xml or server.xml allow to set “allow Linking” and “URI encoding” to “ UTF-8”, an attacker can get access to important system files with web permissions. http://www.target.com/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/ passwd.
Path traversal vulnerability is a method of reading files across directories. But when open_basedir is configured in PHP, it will protect the server against this attack. Open_basedir is to restrict which files PHP can open in a particular directory, and it does not matter if safe_mode is on or not.
For example, in a test environment, when open_basedir is not set, the file inclusion vulnerability will allow access to any file. When open_basedir is set as follows, file inclusion fails.
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a perdirectory
; or per-virtualhost web server configuration file. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
open_basedir = D:\soft\develop\env\sites\www.a.com\
And we get the following error message:
Warning: include() [function.include]: open_basedir restriction in effect. File(../../../../../../../../../../../../../../../../../x.txt)is not within the allowed path(s): (D:\soft\develop\env\sites\www.a.com\)
in D:\soft\develop\env\sites\www.a.com\test.php on line 3
Note that, the value of open_basedir is the prefix of the directory, so the following settings are assumed:
open_basedir = /home/app/aaa
In fact, the following directories are within the allowable range.
/home/app/aaa
/home/app/aaabbb
/home/app/aaa123
If you want to define a specific directory, you need to add “/” at the end.
open_basedir = /home/app/aaa/
Multiple directories should be separated by a semicolon in Windows and by a colon in Linux.
To resolve file inclusion vulnerabilities, we should avoid those including dynamic variables, especially those that can be controlled by a user. An alternative approach is to use an enumeration.
The $ file values are enumerated, thereby avoiding the risk of arbitrary files.