Re: Apache - all versions vulnerability in OLD procesors.

From: Chris Adams (cmadams_at_hiwaay.net)
Date: 04/25/04

  • Next message: Chris Adams: "Re: Apache - all versions vulnerability in OLD procesors."
    Date: Sat, 24 Apr 2004 20:15:14 -0500
    To: bugtraq@securityfocus.com
    
    

    Once upon a time, Adam Zabrocki <pi3ki31ny@wp.pl> said:
    > There are few scenarios, few calls leading to that bug.
    > The first call is in mod_auth, mod_auth3 and mod_auth4. As follows:
    >
    > "src/modules/standard/mod_auth.c"
    > and
    > "src/modules/standard/mod_aut3.c"
    > and
    > "src/modules/standard/mod_aut4.c"

    Apache HTTPD 1.3.29 doesn't include a mod_aut3.c or mod_aut4.c, so this
    is not a "default install".

    > static int authenticate_basic_user(request_rec *r)
    > {
    > ...
    > ...
    > const char *sent_pw;
    > char *real_pw;
    > ...
    > ...
    > if ((res = ap_get_basic_auth_pw(r, &sent_pw)))
    > return res;
    > ...
    > ...
    > if (!(real_pw = get_pw(r, c->user, sec->auth_pwfile))) {
    > ...
    > ...
    > }
    > ...
    > ...
    > invalid_pw = ap_validate_password(sent_pw, real_pw);
    > ...
    > ...
    > }
    >
    > request_rec structure is declared in "src/include/httpd.h".
    >
    > Now look at ap_validate_password() function in "src/ap/ap_check.c":

    You mean src/ap/ap_checkpass.c?

    <snip>

    > while (count >= SHA_BLOCKSIZE) {
    > ebcdic2ascii((AP_BYTE *)sha_info->data, buffer, SHA_BLOCKSIZE);
    > buffer += SHA_BLOCKSIZE;
    > count -= SHA_BLOCKSIZE;
    > maybe_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
    > sha_transform(sha_info);
    > }
    > ebcdic2ascii((AP_BYTE *)sha_info->data, buffer, count);
    > ...
    > ...
    > }

    This whole section only gets called when CHARSET_EBCDIC is defined,
    which is only on a few mainframe platforms, so this is not even active
    on the vast majority of platforms.

    > Aha... good, while count is bigger or equal following constant:
    >
    > "src/ap/ap_sha1.c"
    > ...
    > ...
    > #define SHA_BLOCKSIZE 64
    > ...
    > ...
    >
    > Hm... ok, this get's evaluated further more in ebcdic2ascii() ?
    >
    > "src/ap/ap_ebcdi.c"
    > API_EXPORT(void *)
    > ebcdic2ascii(void *dest, const void *srce, size_t count)
    > {
    > unsigned char *udest = dest;
    > const unsigned char *usrce = srce;
    >
    > while (count-- != 0) {
    > *udest++ = os_toascii[*usrce++];
    > }
    >
    > return dest;
    > }
    >
    > Above function copies 64 bytes, structre AP_SHA1_CTX is an array of 16
    > elements. Take a look at structure element declaration :
    >
    > "src/include/ap_sha1.h"
    > typedef unsigned long AP_LONG; /* a 32-bit quantity */
    >
    > This is fine, assuming that we have 32 bits CPU, and sizeof(unsigned
    > long) equals 4. So 4*16=64. There is no guarantee that on some archs
    > unsigned long is going to stay 32 bit width. When it's either longer
    > or shorter (I am not sure if long can be 16 bits long, but possibly
    > ANSI C standart doesn't say anythin about it's length in bits). Ie. on
    > 64bit platforms, depending on compiler options, and compiler it self
    > long can be either 64 (default) or 32 bits.

    See my other message; an unsigned long will always be at least 32 bits
    (or a storage size large enough to hold a 32 bit unsigned number, which
    I believe on all Apache 1.3 supported platforms will be a binary 32 bit
    or 64 bit allocation).

    > When sizeof( unsigned long )!=4 it can lead to memory corruption in
    > function ebcdic2ascii(), which will either copy too much, copyied in
    > this example 32 bytes more than he should and that situaction do this
    > bug! To bypass this not popular vulnerability we should only
    > resolution is quite simple, SHA_BLOCKSIZE should be declared as
    > sizeof(unsigned long)*16. Possibly SHA_BLOCKSIZE must stay 64 bytes
    > long, than obviously author should take care more about single
    > elements size.

    I don't see a potential for a problem, because the ->data field is
    always at least 64 bytes long, but only the first 64 bytes are used (and
    since they are byte-addressed always, there is no uninitialized data
    read).

    Also, IIRC, the C compilers on the EBCDIC platforms uses a 32 bit
    unsigned long, so there would be no problem anyway.

    -- 
    Chris Adams <cmadams@hiwaay.net>
    Systems and Network Administrator - HiWAAY Internet Services
    I don't speak for anybody but myself - that's enough trouble.
    

  • Next message: Chris Adams: "Re: Apache - all versions vulnerability in OLD procesors."

    Relevant Pages

    • Re: "Sorting" assignment
      ... issue on some ancient compiler doesn't make a lot of sense. ... to his on a few commonly used platforms and compilers, ...  Be sure and call the swap ... reason to find algorithms which operate independent of it. ...
      (comp.programming)
    • Re: Death of Kylix and migrating towards Java
      ... But it can't beat Delphi's compiler speed! ... app developers on non-Windows platforms. ... It is NOT Delphi. ... > I do agree that Kylix was a very good promise and concept, that Borland ...
      (borland.public.delphi.non-technical)
    • Re: Need help with REDEFINES (I think)....
      ... preclude the compiler optimizing it. ... (a compiler generated subroutine) ... generated subroutine) because it uses a simple compare (or series of ... would be fairly consistent across platforms, but even if I'm wrong and there ...
      (comp.lang.cobol)
    • Re: Using C to program the 8051 family
      ... C may be fine for larger platforms but it's ... > you forget to turn the optimizer off. ... You must either trust the compiler or learn to use a ... > language to debug by. ...
      (comp.arch.embedded)
    • Re: Thou shalt have no other gods before the ANSI C standard
      ... Because of these two platforms ... > The C standard does allow memcpy of pointer objects. ... New compiler development for such platforms is not a poor economic ...
      (sci.crypt)