Re: [PHP-DEV] preg_replace oddity [exploitable]

2003-02-03 Thread Maxim Maletsky

James E. Flemer [EMAIL PROTECTED] wrote... :

 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 );


In fact, /e eval()uates the code. It does with the replaced result just
what eval() does with a string PHP code. At most, it could be noted in
docs.



--
Maxim Maletsky
[EMAIL PROTECTED]


-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] preg_replace oddity [exploitable]

2003-02-03 Thread James E. Flemer
On Mon, 3 Feb 2003, Maxim Maletsky wrote:

 James E. Flemer [EMAIL PROTECTED] wrote... :

  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...
--snip--

 In fact, /e eval()uates the code. It does with the replaced result just
 what eval() does with a string PHP code. At most, it could be noted in
 docs.

Yes, I am aware of that, that is what /e is for.  The issue
is not that it eval()s the code, the issue is weather or
not the backrefs (\\1 or $1 etc) are enclosed in single
quotes.  The preg_replace()  code calls php_addslashes() on
the backref data, so if the backref is enclosed in quotes
then there is no way to do anything malicious.  However if
a PHP coder writes a script that uses preg_replace()
without placing quotes around a backref, and the subject
(arg 1) of the function can be supplied by the remote user,
then the remote user can easily insert potentially
dangerous code that will be executed on the server with the
running permision of the web server.

Now consider the use of this expliot in conjunction with a
know local-user expliot for some OS.  PHP provides
convinient easy access to execute arbitrary commands as a
local user...  I think it should be explicitly stated in
the docs for preg_replace() that Bad Things can occur if
backrefs are not enclosed in single quotes, and that mildly
bad things can occur if they are enclosed in double quotes
(i.e. variable expansion of possibly sensative local
variables).

-James


-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] preg_replace oddity [exploitable]

2003-02-02 Thread James E. Flemer
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




[PHP-DEV] preg_replace oddity

2003-01-30 Thread James E. Flemer
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