Subject: GNU screen buffer overflow 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");