You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Marc Slemko <ma...@znep.com> on 1998/01/14 19:44:26 UTC

mod_auth-any/1672: Authentication / .htaccess DoS attack (fwd)

I'm not sure I go for stat()ing every file we try to open an extra time,
but...



---------- Forwarded message ----------
Date: 14 Jan 1998 18:07:16 -0000
From: Jan Wedekind <ja...@wedekind.de>
To: apbugs@hyperreal.org
Subject: mod_auth-any/1672: Authentication / .htaccess DoS attack


>Number:         1672
>Category:       mod_auth-any
>Synopsis:       Authentication / .htaccess DoS attack
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    apache
>State:          open
>Class:          sw-bug
>Submitter-Id:   apache
>Arrival-Date:   Wed Jan 14 10:10:01 PST 1998
>Last-Modified:
>Originator:     jan@wedekind.de
>Organization:
apache
>Release:        1.2.*
>Environment:
Solaris 2.x, Linux & any other Unix
>Description:
(same report will be sent to bugtraq; this is the same splitted text)

At the beginning of the week (after the release of apache 1.2.5)
we discoverd a DoS attack in apache and (eventually) other / all (?)
httpd's. Many thanks to Bernard "sendmail" Steiner <bs...@de.uu.net>,
who got the important idea.

For apache 1.2.x (and very sure all versions before), the
DoS may be exploited if both of the following conditions are true:

- the intruder has (at least FTP) write access to (at least)
  one public HTML directory

- per directory access (AccessFileName configuration directive)
  is enabled and the filename is known to the intruder
  (default is .htaccess)

This configuration will be found very often at private homepages
with FTP-Upload accounts.

Now just put a new .htaccess file to the Server with the 
following contents:

AuthType Basic
AuthName DoS Attack
AuthUserFile /dev/zero
<Limit GET POST>
order deny,allow
allow from all
require valid-user
</Limit>

If you're now trying to open this directory (or any file within)
and enter any user / password combination, you'll get a
hanging (death running) client. This is, because it's reading
/dev/zero and searches for a colon (':') to separate
the user name from the password field (mod_auth.c, get_pw(), line 127).

Now the intruder may stop this request in the browser (the server 
client process will still continue) and start a new one. The next
client will be forced to read /dev/zero.
Repeat this, until 'MaxClient' will be reached. Not only this server
will stop to work (e.g. the parent will wait for all further 
requests for any of it's child), but also the machine will 
going almost to hang with a CPU load of about MaxClient.
>How-To-Repeat:
see Description
>Fix:
possible fixes:

a) workaround

Disable .htaccess in srm.conf by commenting out AccessFileName:
 (default is NULL in the apache distribution, e.g. disabled)

#AccessFileName .htaccess

b) patch to apache source

Because also other authentication methods may be exploitable 
I would prefer to patch it in a way that it's no longer be 
available to open /dev/zero (or any other device) for reading, 
so I patched fpopen() in alloc.c:

kirk: ~/src/apache_1.2.4/src> gdiff -uw alloc.c.orig alloc.c
--- alloc.c.orig        Thu Jan  8 14:14:13 1998
+++ alloc.c     Fri Jan  9 13:37:21 1998
@@ -839,9 +839,14 @@
 {
   FILE *fd = NULL;
   int baseFlag, desc;
+  struct stat buf;
 
   block_alarms();
 
+  if (   *mode != 'r' 
+      || (strcmp(name,"/dev/null") == 0)
+      || stat(name, &buf) == 0 && ((buf.st_mode & S_IFMT) == S_IFREG))
+  {
   if (*mode == 'a') {
     /* Work around faulty implementations of fopen */
     baseFlag = (*(mode+1) == '+') ? O_RDWR : O_WRONLY;
@@ -854,6 +859,7 @@
   } else {
     fd = fopen(name, mode);
   }
+  } 
 
   if (fd != NULL) note_cleanups_for_file (a, fd);
   unblock_alarms();
%0
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, ]
[you need to include <ap...@Apache.Org> in the Cc line ]
[and leave the subject line UNCHANGED.  This is not done]
[automatically because of the potential for mail loops. ]




Re: [PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Marc Slemko <ma...@worldgate.com>.
On Thu, 15 Jan 1998, Martin Kraemer wrote:

> On Thu, Jan 15, 1998 at 02:06:31PM -0700, Marc Slemko wrote:
> > 
> > No, read the first bit.  You trash the request if you don't reach end of
> > line before end of the 8k buffer you read from.
> 
> But suppose you read from /dev/tape, and the first n kilobytes
> indeed look sensible? Say, the tape is filled with 2GB worth of
> newlines?
> 
> I would prefer to check the device first.

But if they create a sparse file then they can do this anyway even if you
do check the device.

I'm not entirely convinced that checking if it is a device avoids all the
problems either.  Say you have a system with any large file on; poof, you
can still use it.  I really have trouble thinking of large world readable
devices that return text.


Re: [PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Thu, Jan 15, 1998 at 02:06:31PM -0700, Marc Slemko wrote:
> 
> No, read the first bit.  You trash the request if you don't reach end of
> line before end of the 8k buffer you read from.

But suppose you read from /dev/tape, and the first n kilobytes
indeed look sensible? Say, the tape is filled with 2GB worth of
newlines?

I would prefer to check the device first.

    Martin
-- 
| S I E M E N S |  <Ma...@mch.sni.de>  |      Siemens Nixdorf
| ------------- |   Voice: +49-89-636-46021     |  Informationssysteme AG
| N I X D O R F |   FAX:   +49-89-636-44994     |   81730 Munich, Germany
~~~~~~~~~~~~~~~~My opinions only, of course; pgp key available on request

Re: [PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Marc Slemko <ma...@worldgate.com>.
On Thu, 15 Jan 1998, Martin Kraemer wrote:

> On Thu, Jan 15, 1998 at 01:43:42PM -0700, Marc Slemko wrote:
> > This does not completely prevent the attempt at reading the file from
> > blocking (only in at least 99% of the cases; although 1% can be bad...)
> > but does make it a lot more difficult for it to block and prevents endless
> > reads.  
> I think that blocking is not the only result of this kind of DoS attack:
> even when the server continues to read (/dev/zero), it will NEVER reach
> EOF. So huge amounts of CPU power can be bound by a few evil processes.

No, read the first bit.  You trash the request if you don't reach end of
line before end of the 8k buffer you read from.

> 
> > Heck, lets think up some cool attacks on systems that use automounters or
> > AFS.
> 
> What a cruel idea...! Oh, yes, that could take some time...
> 
>     Martin
> -- 
> | S I E M E N S |  <Ma...@mch.sni.de>  |      Siemens Nixdorf
> | ------------- |   Voice: +49-89-636-46021     |  Informationssysteme AG
> | N I X D O R F |   FAX:   +49-89-636-44994     |   81730 Munich, Germany
> ~~~~~~~~~~~~~~~~My opinions only, of course; pgp key available on request
> 


Re: [PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Thu, Jan 15, 1998 at 01:43:42PM -0700, Marc Slemko wrote:
> This does not completely prevent the attempt at reading the file from
> blocking (only in at least 99% of the cases; although 1% can be bad...)
> but does make it a lot more difficult for it to block and prevents endless
> reads.  
I think that blocking is not the only result of this kind of DoS attack:
even when the server continues to read (/dev/zero), it will NEVER reach
EOF. So huge amounts of CPU power can be bound by a few evil processes.

> Heck, lets think up some cool attacks on systems that use automounters or
> AFS.

What a cruel idea...! Oh, yes, that could take some time...

    Martin
-- 
| S I E M E N S |  <Ma...@mch.sni.de>  |      Siemens Nixdorf
| ------------- |   Voice: +49-89-636-46021     |  Informationssysteme AG
| N I X D O R F |   FAX:   +49-89-636-44994     |   81730 Munich, Germany
~~~~~~~~~~~~~~~~My opinions only, of course; pgp key available on request

Re: [PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Thu, Jan 15, 1998 at 12:12:36PM +0100, Martin Kraemer wrote:
> +    if (name == NULL) {
> +	aplog_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL,
> +		    "Internal error: pcfg_openfile() called with NULL filename");
> +	/*assert(name != NULL);*/

Forget my patch. I just realized that someone mis-used the pcfg_openfile()
interface (instead of using the pcfg_open_custom() which was implemented
to deal with non-file based "custom" interfaces) to read the -c/-C
configure lines.

That's not good! And it leaves (as implemented) an uninitialized FILE*file
pointer in the returned configfile_t structure -- which isn't good either!

So do NOT use the patch - instead wait until I had a look at it and
maybe changed the memory-based cfg reading to use pcfg_open_custom(),
or at least *DOCUMENT* the inappropriate interface mis-use and
*INITIALIZE* a pointer if it is used further on.

    Martin
-- 
| S I E M E N S |  <Ma...@mch.sni.de>  |      Siemens Nixdorf
| ------------- |   Voice: +49-89-636-46021     |  Informationssysteme AG
| N I X D O R F |   FAX:   +49-89-636-44994     |   81730 Munich, Germany
~~~~~~~~~~~~~~~~My opinions only, of course; pgp key available on request

Re: [PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Marc Slemko <ma...@worldgate.com>.
On Thu, 15 Jan 1998, Martin Kraemer wrote:

> On Wed, Jan 14, 1998 at 02:50:01PM -0600, Igor Tatarinov wrote:
> > But why not do this checking in mod_auth ?
> > or pcfg_openfile might be the right function to fix.
> 
> I think that's a sensible idea. The number of pcfg_openfile() calls is
> limited to reading the config files, the htpasswd files, the .htaccess
> files, in short all those files where it is not acceptable to read
> from devices (or directories ;-).

How about opening with O_NDELAY and changing the routine to detect if we
hit the end of the 8k buffer before the end of the line and, if so,
returning an error?  This is something that really should be done
regardless to report a proper error.

This does not completely prevent the attempt at reading the file from
blocking (only in at least 99% of the cases; although 1% can be bad...)
but does make it a lot more difficult for it to block and prevents endless
reads.  

Heck, lets think up some cool attacks on systems that use automounters or
AFS.  Lots of room for making things block there, and the above doesn't
fix that.  Hmm.  If O_NDELAY stopped such network file read from blocking,
it would be no good.  If it didn't, it wouldn't prevent the above anyway.

[PATCH] fix pcfg_openfile() (was: mod_auth-any/1672: Authentication / .htaccess DoS attack)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Wed, Jan 14, 1998 at 02:50:01PM -0600, Igor Tatarinov wrote:
> But why not do this checking in mod_auth ?
> or pcfg_openfile might be the right function to fix.

I think that's a sensible idea. The number of pcfg_openfile() calls is
limited to reading the config files, the htpasswd files, the .htaccess
files, in short all those files where it is not acceptable to read
from devices (or directories ;-).

Why not add another fstat() and check for S_IFREG()? The appended patch
does that (and fixes some more bugs in pcfg_openfile():
    * the debug message was at the wrong place and would print an arbitraty
      setting of errno
    * filename==NULL was only checked in the debug message, but not in the
      corresponding fopen()
)

    Martin
-- 
| S I E M E N S |  <Ma...@mch.sni.de>  |      Siemens Nixdorf
| ------------- |   Voice: +49-89-636-46021     |  Informationssysteme AG
| N I X D O R F |   FAX:   +49-89-636-44994     |   81730 Munich, Germany
~~~~~~~~~~~~~~~~My opinions only, of course; pgp key available on request

Re: mod_auth-any/1672: Authentication / .htaccess DoS attack (fwd)

Posted by Dean Gaudet <dg...@arctic.org>.

On Wed, 14 Jan 1998, Igor Tatarinov wrote:

> But why not do this checking in mod_auth ?
> or pcfg_openfile might be the right function to fix.

'cause it'd be nice to have the protection by default so that all modules
don't need to be changed.  But for modules that are clued-in and already
need stat() for other reasons (i.e. your caching module, and the core) we
should provide a disable option. 

Dean


Re: mod_auth-any/1672: Authentication / .htaccess DoS attack (fwd)

Posted by Igor Tatarinov <ta...@prairie.NoDak.edu>.
But why not do this checking in mod_auth ?
or pcfg_openfile might be the right function to fix.

Sorry if I am being dumb,
igor

Marc Slemko wrote:
> 
> I'm not sure I go for stat()ing every file we try to open an extra time,
> but...
> 
> ---------- Forwarded message ----------
> Date: 14 Jan 1998 18:07:16 -0000
> From: Jan Wedekind <ja...@wedekind.de>
> To: apbugs@hyperreal.org
> Subject: mod_auth-any/1672: Authentication / .htaccess DoS attack
> 
> >Number:         1672
> >Category:       mod_auth-any
> >Synopsis:       Authentication / .htaccess DoS attack
> >Confidential:   no
> >Severity:       serious
> >Priority:       medium
> >Responsible:    apache
> >State:          open
> >Class:          sw-bug
> >Submitter-Id:   apache
> >Arrival-Date:   Wed Jan 14 10:10:01 PST 1998
> >Last-Modified:
> >Originator:     jan@wedekind.de
> >Organization:
> apache
> >Release:        1.2.*
> >Environment:
> Solaris 2.x, Linux & any other Unix
> >Description:
> (same report will be sent to bugtraq; this is the same splitted text)
> 
> At the beginning of the week (after the release of apache 1.2.5)
> we discoverd a DoS attack in apache and (eventually) other / all (?)
> httpd's. Many thanks to Bernard "sendmail" Steiner <bs...@de.uu.net>,
> who got the important idea.
> 
> For apache 1.2.x (and very sure all versions before), the
> DoS may be exploited if both of the following conditions are true:
> 
> - the intruder has (at least FTP) write access to (at least)
>   one public HTML directory
> 
> - per directory access (AccessFileName configuration directive)
>   is enabled and the filename is known to the intruder
>   (default is .htaccess)
> 
> This configuration will be found very often at private homepages
> with FTP-Upload accounts.
> 
> Now just put a new .htaccess file to the Server with the
> following contents:
> 
> AuthType Basic
> AuthName DoS Attack
> AuthUserFile /dev/zero
> <Limit GET POST>
> order deny,allow
> allow from all
> require valid-user
> </Limit>
> 
> If you're now trying to open this directory (or any file within)
> and enter any user / password combination, you'll get a
> hanging (death running) client. This is, because it's reading
> /dev/zero and searches for a colon (':') to separate
> the user name from the password field (mod_auth.c, get_pw(), line 127).
> 
> Now the intruder may stop this request in the browser (the server
> client process will still continue) and start a new one. The next
> client will be forced to read /dev/zero.
> Repeat this, until 'MaxClient' will be reached. Not only this server
> will stop to work (e.g. the parent will wait for all further
> requests for any of it's child), but also the machine will
> going almost to hang with a CPU load of about MaxClient.
> >How-To-Repeat:
> see Description
> >Fix:
> possible fixes:
> 
> a) workaround
> 
> Disable .htaccess in srm.conf by commenting out AccessFileName:
>  (default is NULL in the apache distribution, e.g. disabled)
> 
> #AccessFileName .htaccess
> 
> b) patch to apache source
> 
> Because also other authentication methods may be exploitable
> I would prefer to patch it in a way that it's no longer be
> available to open /dev/zero (or any other device) for reading,
> so I patched fpopen() in alloc.c:
> 
> kirk: ~/src/apache_1.2.4/src> gdiff -uw alloc.c.orig alloc.c
> --- alloc.c.orig        Thu Jan  8 14:14:13 1998
> +++ alloc.c     Fri Jan  9 13:37:21 1998
> @@ -839,9 +839,14 @@
>  {
>    FILE *fd = NULL;
>    int baseFlag, desc;
> +  struct stat buf;
> 
>    block_alarms();
> 
> +  if (   *mode != 'r'
> +      || (strcmp(name,"/dev/null") == 0)
> +      || stat(name, &buf) == 0 && ((buf.st_mode & S_IFMT) == S_IFREG))
> +  {
>    if (*mode == 'a') {
>      /* Work around faulty implementations of fopen */
>      baseFlag = (*(mode+1) == '+') ? O_RDWR : O_WRONLY;
> @@ -854,6 +859,7 @@
>    } else {
>      fd = fopen(name, mode);
>    }
> +  }
> 
>    if (fd != NULL) note_cleanups_for_file (a, fd);
>    unblock_alarms();
-

Re: mod_auth-any/1672: Authentication / .htaccess DoS attack (fwd)

Posted by Michael Douglass <mi...@texas.net>.
On Wed, Jan 14, 1998 at 02:50:17PM -0700, Marc Slemko said:

> Joy joy.  Now for .htaccess files we not only have to (by default) open
> (or try to open) a zillion files, we have to stat them too.  That sucks.

Not really.  I mean you aren't going to be scaling by a multiple of 2.
Think of it this way, you can do either one first.  If you 'open' first
and it fails, you don't have to 'stat'; and if you 'stat' first and it
fails with ENOENT, you don't have to open the file.  So pick the faster
of the two and use it first. :)

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: mod_auth-any/1672: Authentication / .htaccess DoS attack (fwd)

Posted by Marc Slemko <ma...@worldgate.com>.
On Wed, 14 Jan 1998, Dean Gaudet wrote:

> This is a cute DoS attack.  I like it :) 
> 
> It should be an fstat(), which is faster than stat() on many unixes
> because they don't have to do path resolution twice.  We also should have
> some way of disabling it in the call -- but should default every call to
> having the protection enabled.  We'd disable it in default_handler
> naturally, since we've already protected against devices. 

Joy joy.  Now for .htaccess files we not only have to (by default) open
(or try to open) a zillion files, we have to stat them too.  That sucks.

I would really like a nicer workaround, but... finding one is a different
matter.  If someone has access to the system (ie. a shell) they can still
mess with you no matter what you do.  

Apache is not compartmentalized between users; until you have some overall
way to be sure that no user can make requests eat "too much" of any
resource, you will always be subject to similar attacks.  I don't know of
any server of any type that isn't very restrictive that really is very
well; well, any server of this nature.  There are operating systems that
are and a few big apps that are, but... 

> 
> More generally:  we should change the server so that alarms just can't be
> blocked across system calls.  How to do this I'm not sure at all yet. 
> It's just not a good idea for us to be without a timeout, ever.
> 
> We could really use an efficient "MaxConnectionsPerIP".  But I'm worried
> about proxies.
> 
> Dean
> 
> On Wed, 14 Jan 1998, Marc Slemko wrote:
> 
> > I'm not sure I go for stat()ing every file we try to open an extra time,
> > but...
> 


Re: mod_auth-any/1672: Authentication / .htaccess DoS attack (fwd)

Posted by Dean Gaudet <dg...@arctic.org>.
This is a cute DoS attack.  I like it :) 

It should be an fstat(), which is faster than stat() on many unixes
because they don't have to do path resolution twice.  We also should have
some way of disabling it in the call -- but should default every call to
having the protection enabled.  We'd disable it in default_handler
naturally, since we've already protected against devices. 

More generally:  we should change the server so that alarms just can't be
blocked across system calls.  How to do this I'm not sure at all yet. 
It's just not a good idea for us to be without a timeout, ever.

We could really use an efficient "MaxConnectionsPerIP".  But I'm worried
about proxies.

Dean

On Wed, 14 Jan 1998, Marc Slemko wrote:

> I'm not sure I go for stat()ing every file we try to open an extra time,
> but...