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

Reply via email to