Just one more example. Even when using double quotes, it
is possible to execute code:
<?php
$a = '___! ${`rm -rf /tmp/sess_*`} !___';
$b = preg_replace("/!(.*)!/e", "print(\"\\1\");", $a);
?>
Again, assume $a comes from a tainted source.
-James
On Mon, 3 Feb 2003, James E. Flemer wrote:
> A warning about preg_replace() command needs to be added to
> the docs page for this command. The preg_replace() command
> can use the "/e" modifier to have the "replacement" be
> eval()d by PHP, just like perl.
>
> There is a high potential for exploitable PHP code if a
> programmer uses the /e modifier and does not use quotes
> around the back references (backrefs). Without quotes,
> arbitrary commands may be executed by using the backtick
> operator. Other commands may be executed as well, but are
> more difficult, since addslashes() prevents the characters
> ['"\\\0] from being used.
>
> An clear and explicit warning should be added to the doc
> page for preg_replace, indicating the backrefs must always
> be quoted. Single quotes are preferable, since double
> quotes allow variable expansion.
>
> See the messages below for examples of how this may be
> exploited. (Assume that $a comes from an untrusted source,
> i.e. a get/post/cookie/header variable.)
>
> -James
>
> ---------- Forwarded message ----------
> Date: Mon, 3 Feb 2003 01:04:23 -0500 (EST)
> From: James E. Flemer <[EMAIL PROTECTED]>
> To: [EMAIL PROTECTED]
> Subject: Re: [PHP-DEV] preg_replace oddity [exploitable]
>
> 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 Documentation Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php