Re: DoS attack: apache (& other) .htaccess Authentication

Don Lewis (Don.Lewis@TSC.TDK.COM)
Thu, 15 Jan 1998 05:46:27 -0800

On Jan 14, 7:08pm, jan@WEDEKIND.DE wrote:
} Subject: DoS attack: apache (& other) .htaccess Authentication

} 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).

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

This may still be exploitable through a race condition. If the
user has shell access, he could specify the name of a symlink
in the .htaccess file. If the user can update the symlink to
change it so that it points to /dev/zero between the stat()
and the fopen(), he can still provoke the DoS. This is definitely
harder to exploit, but if you change the code to do an open(),
fstat() the resulting file descriptor, and finally fdopen() the
descriptor if fstat() returns a satisfactory result, then the
race condition is avoided.

There is still a less severe DoS possibility if the user specifies
a large colon-less file. It would probably be wise for get_pw()
give up if it's reading from a bogus looking file.

--- Truck