GNU screen buffer overflow

From: Timo Sirainen (tss_at_iki.fi)
Date: 11/27/03

  • Next message: Werner Koch: "GnuPG's ElGamal signing keys compromised"
    To: bugtraq@securityfocus.com
    Date: Thu, 27 Nov 2003 03:29:05 +0200
    
    
    

    Summary
    -------

    Buffer overflow in GNU screen allows privilege escalation for local users.
    Usually screen is installed either setgid-utmp or setuid-root.

    It also has some potential for remote attacks or getting control of another
    user's screen. The problem is that you have to transfer around 2-3 gigabytes
    of data to user's screen to exploit this vulnerability.

    4.0.1, 3.9.15 and older versions are vulnerable.

    Details
    -------

    ansi.c:

                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                  if (curr->w_NumArgs < MAXARGS)
                    {
                      if (curr->w_args[curr->w_NumArgs] < 100000000)
                        curr->w_args[curr->w_NumArgs] =
                          10 * curr->w_args[curr->w_NumArgs] + (c - '0');
                    }
                  break;
                case ';':
                case ':':
                  curr->w_NumArgs++;
                  break;

    w_NumArgs is signed integer, so after you've sent 2GB of ';' characters in
    escape sequence it wraps to negative and the < MAXARGS protection fails.
    Then it's only a matter of finding a position in memory where the next if
    check passes and does something useful. I would guess there are multiple such
    possibilities, but I didn't try to find any.

    Window sizes
    ------------

    I didn't really check this, but the code looked like there could be some
    problems with large window sizes (eg. ESC[100000;100000t).

    Vendor status
    -------------

    Sent a mail to screen@uni-erlangen.de (16.10), no reply.
    Sent a mail to screen mailing list (24.10), didn't help much.

    Patch
    -----

    --- ansi.c.old 2003-11-15 18:04:12.000000000 +0200
    +++ ansi.c 2003-11-15 18:04:51.000000000 +0200
    @@ -559,7 +559,7 @@
                {
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
    - if (curr->w_NumArgs < MAXARGS)
    + if (curr->w_NumArgs >= 0 && curr->w_NumArgs < MAXARGS)
                    {
                      if (curr->w_args[curr->w_NumArgs] < 100000000)
                        curr->w_args[curr->w_NumArgs] =
    --- resize.c.old 2003-11-27 02:55:07.000000000 +0200
    +++ resize.c 2003-11-27 02:58:33.000000000 +0200
    @@ -682,6 +682,17 @@
       if (wi == 0)
         he = hi = 0;
     
    + if (wi > 1000)
    + {
    + Msg(0, "Window width too large, truncated");
    + wi = 1000;
    + }
    + if (he > 1000)
    + {
    + Msg(0, "Window height too large, truncated");
    + he = 1000;
    + }
    +
       if (p->w_width == wi && p->w_height == he && p->w_histheight == hi)
         {
           debug("ChangeWindowSize: No change.\n");

    
    



  • Next message: Werner Koch: "GnuPG's ElGamal signing keys compromised"