Likes Likes:  0
Resultaten 1 tot 6 van de 6
Geen
  1. #1
    Adam Zabrocki
    Apache - all versions vulnerability in OLD procesors.
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Apache - all versions vulnerability in OLD procesors.



    Apache - all versions vulnerability in OLD procesors.

    I. Entry.

    Vulnerability in probably all versions of apache web server, default
    install (as of version 1.3.29).

    II. Vulnerability details.

    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"
    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":

    API_EXPORT(char *) ap_validate_password(const char *passwd, const char *hash)
    {
    char sample[120];
    ....
    ....
    /* Netscape / SHA1 ldap style strng
    */
    else if (strncmp(hash, AP_SHA1PW_ID, AP_SHA1PW_IDLEN) == 0) {

    ap_sha1_base64(passwd, strlen(passwd), sample);
    }
    ....
    ....
    }

    AP_SHA1PW_ID in "src/include/ap_sha1.h" is defined as:
    ....
    ....
    #define AP_SHA1PW_ID "{SHA}"
    ....
    ....

    Ok. So to the heart of problem. So for strncmp hash to be zero, above must be
    passwd to ap_get_basic_auth_pw() function:

    "src/main/http_pro.c"
    API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
    {
    ....
    ....
    }

    The second argument, pw is evaluated inside ap_validate_password that is called
    from inside get_pw():

    "src/modules/standard/mod_auth.c"
    static char *get_pw(request_rec *r, char *user, char *auth_pwfile)
    {
    ....
    ....
    }

    Ok function ap_validate_password calls ap_sha1_base64(). Take a closer look:

    "src/ap/ap_sha1.c"
    API_EXPORT(void) ap_sha1_base64(const char *clear, int len, char *out)
    {
    ....
    ....
    AP_SHA1_CTX context;
    ....
    ....
    ap_SHA1Init(&context);
    ap_SHA1Update(&context, clear, len);
    ....
    ....
    }

    AP_SHA1_CTX:

    "src/ap/ap_sha1.c"
    typedef struct {
    AP_LONG digest[5]; /* message digest */
    AP_LONG count_lo, count_hi; /* 64-bit bit count */
    AP_LONG data[16]; /* SHA data buffer */
    int local; /* unprocessed amount in data */
    } AP_SHA1_CTX;

    ok, now ap_SHA1Init():

    "src/ap/ap_sha1.c"
    API_EXPORT(void) ap_SHA1Init(AP_SHA1_CTX *sha_info)
    {
    sha_info->digest[0] = 0x67452301L;
    sha_info->digest[1] = 0xefcdab89L;
    sha_info->digest[2] = 0x98badcfeL;
    sha_info->digest[3] = 0x10325476L;
    sha_info->digest[4] = 0xc3d2e1f0L;
    sha_info->count_lo = 0L;
    sha_info->count_hi = 0L;
    sha_info->local = 0;
    }

    "src/ap/ap_sha1.c"
    API_EXPORT(void) ap_SHA1Update(AP_SHA1_CTX *sha_info, const char *buf,
    unsigned int count)
    {
    ....
    ....
    const AP_BYTE *buffer = (const AP_BYTE *) buf;
    ....
    ....
    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);
    ....
    ....
    }

    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.
    Take a look at that:

    siusiak% uname -a; cat a.c; cc a.c; ./a.out
    OSF1 sirppi V4.0 1229 alpha
    int main(void) {
    printf("%d\n",sizeof(unsigned long));
    return 0;
    }
    8
    siusiak%

    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.


    III. Exploit.

    I no time to have a very close look on it, so no proof of concept is provided this time.
    Thanks for attention for read this shit.

    --
    pi3 (pi3ki31ny) - pi3ki31ny@wp.pl (BIG thx for appelast and giejot)
    http://www.pi3.int.pl

    "MJINKS, swanky pijemy w czerwcu no nie? ;-)"

  2. #2
    Chris Adams
    Apache - all versions vulnerability in OLD procesors.
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: Apache - all versions vulnerability in OLD procesors.

    Once upon a time, Adam Zabrocki <pi3ki31ny@wp.pl> said:
    > 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).


    In ANSI C the basic types are not defined in terms of bits, however
    there is a minimum magnitude required. An unsigned long is supposed to
    hold at least 4294967295, which is 2^32-1. On most normal platforms,
    that means an unsigned long must be at least 32 bits.

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

  3. #3
    Peter J. Holzer
    Apache - all versions vulnerability in OLD procesors.
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: Apache - all versions vulnerability in OLD procesors.

    --fdj2RfSjLxBAspz7
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: inline
    Content-Transfer-Encoding: quoted-printable

    On 2004-04-24 15:53:03 -0000, Adam Zabrocki wrote:
    > Apache - all versions vulnerability in OLD procesors.


    Hmm, 64 bit processors are old?

    [...]

    > Aha... good, while count is bigger or equal following constant:
    >=20
    > "src/ap/ap_sha1.c"
    > ...
    > ...
    > #define SHA_BLOCKSIZE 64
    > ...
    > ...
    >=20
    > Hm... ok, this get's evaluated further more in ebcdic2ascii() ?
    >=20
    > "src/ap/ap_ebcdi.c"
    > API_EXPORT(void *)
    > ebcdic2ascii(void *dest, const void *srce, size_t count)
    > {
    > unsigned char *udest =3D dest;
    > const unsigned char *usrce =3D srce;
    >=20
    > while (count-- !=3D 0) {
    > *udest++ =3D os_toascii[*usrce++];
    > }
    >=20
    > return dest;
    > }
    >=20
    > Above function copies 64 bytes, structre AP_SHA1_CTX is an array of 16 el=

    ements.
    > Take a look at structure element declaration :
    >=20
    > "src/include/ap_sha1.h"
    > typedef unsigned long AP_LONG; /* a 32-bit quantity */
    >=20
    > This is fine, assuming that we have 32 bits CPU, and sizeof(unsigned long=

    ) equals 4. So 4*16=3D64.
    > There is no guarantee that on some archs unsigned long is going to stay 3=

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


    How about looking it up? The C standard defines long as having at least
    32 bits (and int and short as having at least 16 bits, and char as
    having at least 8 bits, just for completeness).

    > Ie. on 64bit platforms, depending on compiler
    > options, and compiler it self long can be either 64 (default) or 32 bits.=

    =20

    Correct.

    > When sizeof( unsigned long )!=3D4 it can lead to memory corruption in fun=

    ction ebcdic2ascii(),
    > which will either copy too much, copyied in this example 32 bytes more th=

    an he should and
    > that situaction do this bug!


    No. It will still copy 64 (SHA_BLOCKSIZE) bytes, but the buffer will now
    be 16*8 =3D 128 bytes long. So half of the buffer will be wasted, but no
    overflow will occur.=20

    hp

    --=20
    _ | Peter J. Holzer | Shooting the users in the foot is bad.=20
    |_|_) | Sysadmin WSR / LUGA | Giving them a gun isn't.
    | | | hjp@wsr.ac.at | -- Gordon Schumacher,
    __/ | http://www.hjp.at/ | mozilla bug #84128

    --fdj2RfSjLxBAspz7
    Content-Type: application/pgp-signature
    Content-Disposition: inline

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.0.7 (GNU/Linux)

    iQDQAwUBQIzAOFLjemazOuKpAQEbPwXUCNUJBs/ZvAs0fw9od2x2SCqexoutolNU
    l9gIGuwHMJsu+u6MznzkoXIeIt1lIlX83bt4t/UldrFAEYpFUn7yN/e5IaeB1BC/
    wQcQeS8i+3n5i53+Jnn69qCuNrOOtcoiBVGsqa71fpepjCMMV+ c6n+dtfV1s22XZ
    MbI/8LuoMBhUqlycQz9wYnOKRiN2j8EJsZmsE+571NZ3ct/OOA+KYYbWt+6smHw3
    KabG5oPoRvBMwPjr/o3c/6aLDw==
    =fvq/
    -----END PGP SIGNATURE-----

    --fdj2RfSjLxBAspz7--

  4. #4
    Chris Adams
    Apache - all versions vulnerability in OLD procesors.
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: Apache - all versions vulnerability in OLD procesors.

    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.

  5. #5
    Adam Zabrocki
    Apache - all versions vulnerability in OLD procesors.
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: Apache - all versions vulnerability in OLD procesors.



    Hello

    In OLD procesors (i mean like x286 and some version x386) when the sizeof (unsigned long) == sizeof (unsgined int) there is bug becouse it's 2 bytes and... 2*16=32 but i don't have in this time box with that procesors for research this situactions and
    this is only theory that bug becouse i don't know whether apache we can run on this OLD procesors. Second question is what about new and not standard procesor like 64 bits or alpha, risc and etc. (in this time it's no in standard uses in box). Some calls
    for functions to copied bytes is given argument like sizeof (sha_info->data) and that write 8*16-64=64 bytes more and not control what can start some conflict in farther run that server.

    Best regards Adam Zabrocki (pi3 - pi3ki31ny).

  6. #6
    Peter Pentchev
    Apache - all versions vulnerability in OLD procesors.
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: Apache - all versions vulnerability in OLD procesors.

    --Ns7jmDPpOpCD+GE/
    Content-Type: text/plain; charset=windows-1251
    Content-Disposition: inline
    Content-Transfer-Encoding: quoted-printable

    On Mon, Apr 26, 2004 at 08:12:26PM -0000, Adam Zabrocki wrote:
    >=20
    > Hello
    >=20
    > In OLD procesors (i mean like x286 and some version x386) when the
    > sizeof (unsigned long) =3D=3D sizeof (unsgined int) there is bug becouse =

    it's
    > 2 bytes and... 2*16=3D32


    Eh?

    Yes, you are talking about 16-bit processors, where the word size was 16
    bits (two bytes), and sizeof(int) =3D=3D 2. However, I can't remember any C
    compilers for Intel x86 processors where sizeof(long) !=3D 4. Yes, 'int' w=
    as
    a 16-bit type, but IIRC, 'long' has always been a 32-bit type (a so-called
    DWORD back then) - just as the C standard requires, as others mentioned.

    > but i don't have in this time box with that
    > procesors for research this situactions and this is only theory that bug
    > becouse i don't know whether apache we can run on this OLD procesors.


    It's not just a matter of processors. You have to have OS support for
    sockets and stuff. Yes, this can be done under Windows in 16-bit mode or
    MS-DOS with the appropriate socket library, like WATTCP -
    http://google.com/search?q=3DApache+WATTCP

    Still, see above for the reasons this will NOT be a problem even then.
    sizeof(long) >=3D 4, and that's that.

    G'luck,
    Peter

    --=20
    Peter Pentchev roam@ringlet.net roam@sbnd.net roam@FreeBSD.org
    PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
    Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553
    Thit sentence is not self-referential because "thit" is not a word.

    --Ns7jmDPpOpCD+GE/
    Content-Type: application/pgp-signature
    Content-Disposition: inline

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (FreeBSD)

    iD8DBQFAj1077Ri2jRYZRVMRAnI8AJwJPqNqL/YYngIu1MDasZxBVzDA6QCfR1Af
    XhMG9xccP+uxfn9H6ITmq7w=
    =CAb7
    -----END PGP SIGNATURE-----

    --Ns7jmDPpOpCD+GE/--

Webhostingtalk.nl

Contact

  • Rokin 113-115
  • 1012 KP, Amsterdam
  • Nederland
  • Contact
© Copyright 2001-2026 Webhostingtalk.nl.
Web Statistics