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

Reply via email to