5

I have to make a script in PHP that will scan other PHP files to check for dangerous function calls like eval,exec . Is there any parser available that can give me a logical structure of code.

Or i have to go with Regex.

Thanks, any type suggestions are welcome.

Arshdeep

Edit: i am not considering it as "one shot kill all". I have some other things in mind too, but its still something that i have to do.

Jørgen R
  • 10,568
  • 7
  • 42
  • 59
Arshdeep
  • 4,281
  • 7
  • 31
  • 46
  • another question about this: http://stackoverflow.com/questions/1865020/php-how-to-disable-dangerous-functions – Zul Dec 09 '11 at 13:27
  • Your code will not work, even if you inspect the file, it can use Reflection or other ways to hide the original function name. You will never be fully safe. You need to disable the functions that isn't allowed. – Gabriel Gartz Dec 09 '11 at 13:28
  • possible duplicate of [Extracting function names from a file (with or without regex)](http://stackoverflow.com/questions/4622390/extracting-function-names-from-a-file-with-or-without-regex) -- A regex might be sufficient to detect *possible* occurences only. It won't see any `$fn = "unlink"; $fn();` or other obfuscated calls. Neither will the tokenizet approach (which is slightly more complex, due to filtering class methods actually needs a mini parser). – mario Dec 09 '11 at 13:29
  • 2
    Also the retarded security myth about `eval()`: That's just another name for `include()`. See also [exploitable php functions](http://stackoverflow.com/questions/3115559/exploitable-php-functions). – mario Dec 09 '11 at 13:31
  • 1
    just a warning: **don't rely on this**. There are nearly endless ways to do nasty things with your server. Think about `file_put_contents('nasty.php', 'ex' . 'ec("rm -rf /");'); include 'nasty.php';` or even `include 'http://badserver.com/nasty.php'` – Roman Dec 09 '11 at 13:35

3 Answers3

6

Don't, you'll only shoot yourself in the foot.

PHP is a highly dynamic language. You probably can't even imagine what possibilities there are to execute code. I had some attempts at preprocessing PHP for sandboxing and from my experience I can tell you that it is very hard to account for all cases. To get a rough overview of what you are facing, look at the exploitable functions list, which was created over time and still isn't perfect.

To answer your actual question, I maintain a PHP parser written in PHP. You could intercept all function calls by defining a node visitor looking roughly like this:

class MyNodeVisitor extends PHPParser_NodeVisitorAbstract {
    public function enterNode(PHPParser_Node $node) {
        if ($node instanceof PHPParser_Node_Expr_FuncCall) {
            if ($node->name instanceof PHPParser_Node_Name) {
                // static function name
            } else {
                // dynamic function name
            }
        }
    }
}
Community
  • 1
  • 1
NikiC
  • 100,734
  • 37
  • 191
  • 225
  • Yeh, i am not considering it as the sure-shot measure, but it will still hit good numbers i believe ? Many thanks for the link, super helpful . – Arshdeep Dec 09 '11 at 13:38
2

You can use tokenizer to do that:

print_r(token_get_all('<?php exec("rm -rf *"); ?>'));

Notice in the output the third element which is:

[1] => Array
    (
        [0] => 307
        [1] => exec
        [2] => 1
    )
Fabio
  • 18,856
  • 9
  • 82
  • 114
  • Note though, that you would also get a T_STRING for pretty much any other identifier - like class names, constants, method names, etc. – NikiC Dec 09 '11 at 13:55
  • 1
    lame ideal, what if the function is being called using variable variables, how would you detect that? – ajreal Dec 09 '11 at 19:53
2

Just use disable_function and disable_classes.
This can be changed only at the php.ini level.

ajreal
  • 46,720
  • 11
  • 89
  • 119