I found a more evil example:
<?php
$a = "___! `rm -rf /tmp/sess_*` !___";
$b = preg_replace("/!(.*)!/e", "print(\\1);", $a);
?>
This happily executes "rm -rf /tmp/sess_*". I will not
give out more examples, but if one examines the code for
addslashes() it is quite obvious what you can an cannot do
here. Thus it is clearly a Bad Thing for someone to use
preg_replace with the /e modifier and not use quotes around
the \\n or $n backrefs.
The docs should be updated to include a very noticeable
warning about this hole. I am contemplating possible
solutions for this problem...
Also as a side note, it does not seem to be possible to use
'echo' as part of the expression, print must be used. (Yes
I know why, just pointing it out.)
-James
On Thu, 30 Jan 2003, James E. Flemer wrote:
> Can someone explain what is going on here:
>
> --- foo.php ---
> <?php
> $a = "___! 52); echo(42 !___";
> $b = preg_replace("/!(.*)!/e", "print(\\1);", $a);
> print("\n---\na: $a\nb: $b\n");
> ?>
> --- end ---
> --- output ---
> 52
> ---
> a: ___! 52); echo(42 !___
> b: ___1___
> --- end ---
>
> I understand that one is supposed to use single quotes
> around the \\1 in the above preg_replace. But what happens
> when they do not? Clearly the echo(42); is not executed,
> and it is not printed by print(). Even more interesting is
> if you put something like echo(\"42 in $a, then you get a
> bunch of errors including:
> Fatal error - Failed evaluating code:
> print( 52); echo(\"42 );
>
> It seems like preg_replace() is doing some strange things,
> and might be something that could be exploitable if a
> remote user can supply the first argument, and the second
> argument does not enclose \\n options.
>
> -James
>
>
>
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php