Cenzic 232 Patent
Paid Advertising
web application security lab

PHP Vulnerable to Null Byte Injection

A few days ago there was a post by 3APA3A about an exploit in PHPBB using poison null byte injection. For those of you who weren’t actively hacking in the 1990’s Rain Forrest Puppy came up with this technique in an article explaining common CGI exploitation techniques. RFP’s technique dealt with injecting a null byte at the end of a string, that was used for comparison. When the comparison failed (this will fail “root” == “root\0″) an operation is performed based on the input and since the null byte doesn’t do anything in other non comparison operations (like opening files for instance) it does so with higher privelages.

What 3APA3A disclosed on behalf of ShAnKaR is that PHP is also vulnerable to these same exploits. For some reason this strikes me as odd. One of the major lessons learned during the late 90’s during the PERL CGI script hay-days was that null byte injection must be detected and removed by stripping out erroneous null bytes from user input. It would have seemed safer to embed this sort of security into more functions without requring users to know anything about the form of exploitation.

If you didn’t do much security auditing or penetration testing in the 90’s this might seem fairly obscure, but I’ve found the problem in dozens of applications. I think PHP’s major benefit is that it made database integration much easier than PERL did (requring the correct DBI libraries) which makes null byte injection fairly less useful, but it’s certainly not gone, as this advisory explains. I guess the major issue with black box penetration testing is that it is fairly difficult to find what you are attempting to exploit in the first place without significant recon and even then you may not find what you are looking for. In the case of PHP most applications are open sourced these days, so it is fairly trivial to find exploitable code, just by downloading the most current revision.

I’ll be curious to see if this starts a rash of new forms of PHP exploitation. If I had more time to be auditing, I’m sure I could find a few places that used this type of string comparison to perform security operations. Good stuff coming from Russia!

14 Responses to “PHP Vulnerable to Null Byte Injection”

  1. WhiteAcid Says:

    I too have seen this in PHP. I’ve never looked into it but I’ve always thought it was due to the OS calls that PHP makes. Obviously I simply never pass any user controlled variables into (include|require)(_once)? , but it is very possible to use null byte injection on both includes and fopens, haven’t tried any more.

    Here’s the code I just used for testing:
    <?php
    include($_GET[’p'].”.txt”);

    $h = fopen($_GET[’p'].”.txt”,’r');
    echo “”.fread($h, 9).”";
    ?>

    Create a few text files and load them. On my windows XP box with latest apache and PHP I could inject 1.txt%00 and it’d load perfectly. On my web host (Linux, Apache 2.0.x PHP 5.1.x) I got a 503 error page, but that could be due to some web filter they have that I’ve simply never noticed before.

  2. WhiteAcid Says:

    oops, around the fread() command was <xmp> tags (opening and closing), forgot to convert those to something wordpress allows.

  3. Martin Straka Says:

    I have seen this three years ago:)

    http://www.phpbuilder.com/lists/php-general/2003101/0703.php

    and result of this discussion was that some functions (mainly filesystem related) are not binary safe and that this is not well documented in the PHP manual.

    When magic quotes are on, the null character is quoted,

    http://php.net/manual/en/security.magicquotes.php

    making this attack vector unusable.

  4. yawnmoth Says:

    Correct me if I’m wrong, but I don’t believe null byte injection will work when magic_quotes_gpc is enabled or when the string is passed through addslashes (which is pretty much what magic_quotes_gpc does). Doing stripslashes won’t revert the string back to the one that had the %00 character, either.

    Whether or not magic_quotes_gpc ought to be enabled is another matter, entirely. On well written PHP applications, it shouldn’t make a difference.

  5. yawnmoth Says:

    *shrugs* Didn’t see Martin’s reply (which kinda makes my reply redundant…)

  6. Soenke Ruempler Says:

    Nullbyte Injection is very useful for directory traversal attacks. I found several security holes in one of the biggest commercial PHP shop systems (german vendor, contacted) which allowed me to traverse over the whole machine.

  7. Chris Shiflett Says:

    “I’ll be curious to see if this starts a rash of new forms of PHP exploitation.”

    I doubt it. This isn’t new, and there are many web application security resources for PHP developers that describe it.

    In addition, only broken code is vulnerable, and this doesn’t work on all platforms. (Windows might be the only vulnerable platform.) Making sure another system interprets data correctly has never been PHP’s concern, although you could argue that magic_quotes_gpc was a misguided step in that direction.

    Maybe it’s just a knee-jerk reaction on my part, but this seems like yet another example of a phpBB vulnerability being incorrectly described as a PHP problem.

  8. RSnake Says:

    Thanks for writing, Chris. It’s probable… the other problem with it as a vector is that it does require a fair bit of knowledge about the issue. You’re right, it’s certainly not new (I’ve known about it since at least 1998). And you’re also right that it is only a coding issue, not a language issue.

    However, there is one point there, that I’m on the fence over. Since PHP is a fairly new programming language it feels like it should have taken this issue into account and found a way around it without requiring the developer to know about the issue. I know it sounds stupid, but a permanant “taint” mode seems like it would solve lots of these issues. It could be something you could turn off if you really knew what you were doing, but for users who didn’t they would be nicely warned that what they were doing with the variables was insecure.

    I certainly don’t think PHP is to blame - as this issue pre-dates PHP. However, I’m always wary of programming languages that make it too easy for developers to code complex applications without really understanding what they are doing. Ruby on rails will be the next big target (in another few years when it gains popularity) is my prediction.

  9. Soenke Ruempler Says:

    @RSnake: I hope someday the filter API (http://de3.php.net/filter) will be the default access method for external variables in PHP.

    @Chris: Unix/Linux is also vulnerable, not only Windows - or what did you mean?

  10. Chris Shiflett Says:

    PHP is certainly guilty of making it easy for people to develop complex applications with little understanding of what they’re doing. In the past, attempts to “automatically” solve security problems for those who don’t know what they’re doing (magic_quotes_gpc, safe_mode, etc.) have only worsened the situation.

    Out of curiosity, what do you think PHP should do to solve this issue? I can’t imagine ever needing a NULL byte in $_GET or $_POST, for example, but should PHP strip it? Also, do you know what precisely is at fault? Because this doesn’t work on all platforms, I am tempted to believe that a system library is at least partly to blame.

    Soenke, I think the filter extension is going to be a good thing for PHP. My only concern is that it has the potential to repeat some past mistakes. For example, consider this:

    http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html

    I’d like to draw your attention to one statement in particular:

    “You will notice a distinct lack of input filtering yet if you try to inject any sort of XSS it won’t work. This is because I am using the pecl/filter extension to automagically sanitize all user data for me.”

    Imagine a new era of PHP code examples that people learn from, and authors can omit necessary security practices with disclaimers like that. It’s also easy to imagine PHP applications that are vulnerable to a wide variety of exploits when running in any environment that’s not configured in exactly the right way. There’s also the fact that any filtering rules that can be applied globally are likely not going to be very strict. Most input that web applications deal with is not homogeneous.

    Regarding my statement that Windows may be the only vulnerable platform, that was based on some quick tests I did a few years ago. (This is why I didn’t make a definitive statement.) I am curious to know which Unix platforms you have found to be vulnerable.

  11. u Says:

    A few corrections.

    Article said:
    “RFP’s technique dealt with injecting a null byte at the end of a string, that was used for comparison.”

    As mentioned in RFP’s text he did not find this technique. It was publicly known.

    Martin Straka said:
    “When magic quotes are on, the null character is quoted,

    http://php.net/manual/en/security.magicquotes.php

    making this attack vector unusable.”

    Magic quotes does not prevent a nullbyte from terminating a string at the system level. It simply escapes the nullbytes in gpc (does not quote them). gpc is not the only way for data to be input into a php script. Also the data may be manipulated after magic quotes has taken place.

    Magic quotes may help prevent this issue in a large number of cases, but it does not make this attack vector unusable.

    Chris Shiflett said:
    “In addition, only broken code is vulnerable, and this doesn’t work on all platforms. (Windows might be the only vulnerable platform.)”

    He is correct when he points out it is platform dependant, but just to clarify, Windows is not the only vulnerable platform.

  12. Martin Straka Says:

    u said:

    “Magic quotes does not prevent a nullbyte from terminating a string at the system level. It simply escapes the nullbytes in gpc (does not quote them). gpc is not the only way for data to be input into a php script. Also the data may be manipulated after magic quotes has taken place.”

    You are absolutely right. The magic quotes close mentioned attack vector only in way, that you are not able to fully control the end of the string (by the null) and that there is \ character added.

    So if there is (bad) code:

    readfile(”$file.txt”);

    without magic qoutes you can access file with every extenstion

    xxxx.php%00

    and with them no:

    xxxx.php\%00

    but definitively _the code_ is bad. It’s only luck, that with magic quotes, the threat is less. As you wrote “they may help prevent”:)

    Thanks.

  13. Soenke Ruempler Says:

    Hi Chris,

    all linux platforms are potentially vulnerable, I’ll send you an example privately.

  14. nullbyte Says:

    VERY DANGEROUS..