Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:5465
HistoryNov 28, 2003 - 12:00 a.m.

GNU screen buffer overflow

2003-11-2800:00:00
vulners.com
8

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 [email protected] (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 &#40;curr-&gt;w_NumArgs &lt; MAXARGS&#41;
    
  •         if &#40;curr-&gt;w_NumArgs &gt;= 0 && curr-&gt;w_NumArgs &lt; MAXARGS&#41;
              {
                if &#40;curr-&gt;w_args[curr-&gt;w_NumArgs] &lt; 100000000&#41;
                  curr-&gt;w_args[curr-&gt;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&#40;0, &quot;Window width too large, truncated&quot;&#41;;
    
  •  wi = 1000;
    
  • }
  • if (he > 1000)
  • {
  •  Msg&#40;0, &quot;Window height too large, truncated&quot;&#41;;
    
  •  he = 1000;
    
  • }
  • if (p->w_width == wi && p->w_height == he && p->w_histheight == hi)
    {
    debug("ChangeWindowSize: No change.\n");