I've been playing with the telnet attack on the SGI, trying to figure out a good way around it since SGI apparently doesn't have a patch ready yet. I have figured an easy way to show how the bug operates, but haven't figured an easy way to stop it. # telnet telnet> environ define _RLD_ROOT /tmp telnet> environ export _RLD_ROOT telnet> o localhost Trying 127.0.0.1... Connected to localhost.xxx.xxx.xxx Escape character is '^]'. IRIX System V.4 (xxx) 7480:login: rld: Fatal Error: cannot map soname 'libgen.so' using any of the filenames /tmp/usr/lib/libgen.so:/tmp/lib/libgen.so:/tmp/lib/cmplrs/cc/libgen .so:/tmp/usr/lib/cmplrs/cc/libgen.so:/tmp/usr/lib/libgen.so.1:/tmp/lib/libgen .so.1:/tmp/lib/cmplrs/cc/libgen.so.1:/tmp/usr/lib/cmplrs/cc/libgen.so.1: -- e ither the file does not exist or the file is not mappable (with reason indica ted in previous msg) Connection closed by foreign host. # _RLD_ROOT isn't the only variable that the runtime linker will understand, I just picked this one as a good example. If you do a 'tog opt' in telnet before you open the connection to localhost you can watch the option negotiation and see the _RLD_ROOT variable being passed. There are two ways I know of to protect against this attack until SGI has a patch ready. One would be to write a wrapper that removes "dangerous" environment variables. Obviously, figuring out which ones are dangerous is the trick! Certainly anything that starts LD_ or _RLD should be removed. But there may always be others you don't know about. You'd take your wrapper and call it /usr/lib/iaf/scheme and rename the real /usr/lib/iaf/scheme to something like /usr/lib/iaf/scheme.real and have your wrapper call it (see below) You'd have to compile it non_shared, so it doesn't get hijacked by the bad environment variables itself. The other way I found is guaranteed to work, but breaks login slightly. If you create a simple wrapper program as follows: main(argc, argv) int argc; char **argv; { setuid(1); execv("/usr/lib/iaf/scheme.real", argv); } And compile it with the -non_shared option, call it /usr/lib/iaf/scheme and rename the old /usr/lib/iaf/scheme to /usr/lib/iaf/scheme.real, then you effectively have telnetd calling your wrapper, which sets its uid to 1, then calls the real login. I've only tested this on Irix 5.3, and most of my experience is with HPs, so I don't know if this works for all releases. But I know that on my 5.3 machine, telnetd calls /usr/lib/iaf/scheme directly, instead of /bin/login (which is a link to /usr/lib/iaf/scheme) Since the real login is not started as root, you see some odd things. I've noticed two things in particular: you get an error because quota is being run as uid 1 instead of root when you login, and rlogin no longer works with .rhosts. I assume that's because login will only accept some options when not run as root, for obvious reasons. There may be other problems with it as well. But since login is setuid, the uids don't match and the runtime linker won't honor any of the "dangerous" variables. I'm curious exactly to see exactly how the various vendors that have this vulnerability choose to fix it in the long term. In the short term, patching telnetd seems to be the solution. But what if the dynamic linker gets a new variable in the future, and the people responsible for that don't let the people responsible for telnetd know? A better fix, IMHO, would be some sort of way to compile some executables without support for altering paths in this way. HP by default does not allow you to modify the searching rules used for finding shared libraries. But with a linker option, you can allow the environment variable SHLIB_PATH to modify the searching rules. Its a bit less flexible than, say, Sun or SGI, but there are no worries about this sort of attack ever being possible unless HP compiled system binaries with this option, which they would of course be crazy to do. -- Doug Siebert dsiebert@icaen.uiowa.edu