lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20040425011514.GB694998@hiwaay.net>
Date: Sat, 24 Apr 2004 20:15:14 -0500
From: Chris Adams <cmadams@...aay.net>
To: bugtraq@...urityfocus.com
Subject: Re: Apache - all versions vulnerability in OLD procesors.


Once upon a time, Adam Zabrocki <pi3ki31ny@...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@...aay.net>
Systems and Network Administrator - HiWAAY Internet Services
I don't speak for anybody but myself - that's enough trouble.


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ