From owner-freebsd-security Wed May 12 2:34: 2 1999 Delivered-To: freebsd-security@freebsd.org Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by hub.freebsd.org (Postfix) with ESMTP id F10B915CCF for ; Wed, 12 May 1999 02:33:13 -0700 (PDT) (envelope-from robert@cyrus.watson.org) Received: from fledge.watson.org (robert@fledge.pr.watson.org [192.0.2.3]) by fledge.watson.org (8.8.8/8.8.8) with SMTP id FAA12507; Wed, 12 May 1999 05:33:03 -0400 (EDT) (envelope-from robert@cyrus.watson.org) Date: Wed, 12 May 1999 05:33:02 -0400 (EDT) From: Robert Watson X-Sender: robert@fledge.watson.org Reply-To: Robert Watson To: Darren Reed Cc: security@freebsd.org Subject: Generic Software Wrappers (fwd) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Since there have been a few questions about the reference I made to wrappers code from TIS, I'm forwarding the original mailing list announcement back to the list. Note: just because my .sig says TIS doesn't mean I know anything much about this particular project. :) Robert N Watson robert@fledge.watson.org http://www.watson.org/~robert/ PGP key fingerprint: AF B5 5F FF A6 4A 79 37 ED 5F 55 E9 58 04 6A B1 Carnegie Mellon University http://www.cmu.edu/ TIS Labs at Network Associates, Inc. http://www.tis.com/ Safeport Network Services http://www.safeport.com/ ---------- Forwarded message ---------- Date: Thu, 08 Apr 1999 17:17:35 -0400 From: Mark S Feldman To: freebsd-security@freebsd.org Cc: feldman@tislabs.com Subject: Generic Software Wrappers Almost 8 months back, I responded to a message on this list and described a research project we were working on. My message is below. At the end of the message, I said I would send another message to this list when we made our source available. Well, the first release of our Generic Software Wrappers Tool Kit -- still very much a research prototype -- is available. It runs under FreeBSD 2.2.x, Solaris 2.6, and, as much as we have ported to date, under Windows NT 4.0. We're limited to FreeBSD 2.2.x because we don't currently have the resources to port to 3.x. Check out ftp://ftp.tislabs.com/pub/wrappers if you're interested. Mark ------- Forwarded Message To: Philippe Regnauld cc: freebsd-security@freebsd.org, badger@tis.com, feldman@tis.com, Robert Watson Subject: Re: Fwd: "Using capabilties aaginst shell code" (fwd) Date: Wed, 19 Aug 1998 11:14:17 -0400 From: Mark S Feldman Sender: owner-freebsd-security@freebsd.org X-Loop: FreeBSD.org Content-Type: text Content-Length: 7470 Philippe, Your message to the freebsd-security list was passed to me. I'm the project leader for the Generic Software Wrappers project at TIS Labs at Network Associates. In short, under DARPA contract F30602-96-C-0333, we have developed a Wrapper Definition Language (WDL) based on 'C' which makes it easy to identify system events of interest (e.g., named system calls, all system calls containing a path parameter, system calls available only to root), to intercept them, and to deny, augment, or transform those events. We have developed a prototype under FreeBSD, including a wrapper compiler which compiles WDL into 'C', a Wrapper Support Subsystem implemented as a Loadable Kernel Module, and various support programs. We are currently porting to Solaris and Windows NT. Our source is not currently organized for distribution, but, once it is, it will be made available for free for non-commercial use. > Is this any form of restriction that can be implemented > in *BSD systems ? I.e.: restricting system calls to > certain classes of daemons ? One of our simpler wrappers is the noadmin wrapper, which prevents a wrapped process, even one running as root, from executing certain administrative system calls:: /* * $Id: noadmin.wr,v 1.5 1998/04/20 19:05:08 ko Exp $ * * noadmin.wr * * A wrapper that denies certain administrative syscalls. */ #include "../../wr.include/bsd.ch" wrapper noadmin { bsd::op{mount || unmount || ptrace || quotactl || acct || swapon || mknod || adjtime || ktrace || reboot || settimeofday} pre { return WR_DENY | WR_BADPERM; }; } In the wrapper, bsd.ch contains a characterization of the system API. It starts with the 'C' prototype, and then adds additional attributes that make it possible to group system calls and to deal with their parameters. The wrapper runs in the bsd domain and looks for the named operations. It intercepts before the operation occurs (pre keyword), prevents it from executing, making it appear to be a permission denied-type error. > As mentioned in the example below, why should POPd be allowed > to exec() ? This seems like a very sane approach (of course, > it implies knowledge/auditing of the code). In addition to our wrappers, which specify what events to look for and how to handle them, we have activation criteria, which determine which wrappers wrap a process. Activation criteria are simple boolean expressions which can be based on the uid, gid, program name, etc. If the pop daemon were named popd, the following activation criteria would cause it to be wrapped by the noadmin wrapper: prog == popd ==> noadmin As for not knowing what system calls a process needs to get the job done, it could first be run under a wrapper like dbcallcount, which tracks all system calls made by wrapped processes and uses Wrapper Query Language (WQL) to store call counts in our fast, lightweight database which can be viewed using our GUI or CLI from user space: /* * $Id: dbcallcount.wr,v 1.7 1998/08/06 19:45:17 ko Exp $ * * dbcallcount.wr * * This wrapper keeps track of the number of times each syscall is * attempted. * * Use the "wrselect" program to view the tables created. * */ #include "../../wr.include/bsd.ch" #include "../../wr.include/libwr.h" wrapper dbcallcount { DBTABLE callcountTable { char(20) key name; int count; }; callcountTable callcount; wr_activate() { int i; /* create the table. */ i = wql { create table callcount; }; if (i < 0) wr_printf("Error creating table.\n"); } wr_duplicate() { /* create the table. */ wql { create table callcount; }; } wr_deactivate() { /* Drop the table. */ wql { drop table callcount; }; } /* Catch all syscalls */ bsd::op{*} pre { int retVal; /* If syscall in in the db, increment count. */ /* If not, add the syscall to the database. */ retVal = wql { update callcount set .count = .count + 1 where .name = $$; }; if (retVal <= 0) { wql { insert into callcount values ($$, 1); }; } }; } > > Then we could have certain untrusted (i.e.: running as > root) daemons launched in such an environment, on top > of being chroot()ed. ... Yup. And wrappers provide a mechanism to do that. Take a look at the following wrapper which creates a simple, if silly, synthetic environment: /* * $Id: dbsynthetic.wr,v 1.5 1998/08/19 15:30:08 feldman Exp $ * * This wrapper provides a synthetic environment, doing string * substitutions on path names. * */ #include "../../wr.include/bsd.ch" #include "../../wr.include/libwr.h" wrapper dbsynthetic { /* Null-terminated array of substition string pairs. Each target * entry, if found in a path, will be replaced by the replacement * entry. Regular expressions, as defined in WDL, can be used for * the targets. */ DBTABLE path_table { char(256) target; char(256) replacement; }; DBTABLE alert_table { char(256) path; char(256) fullname; int pid; int uid; }; path_table global pathnames; alert_table global alerts; wr_install() { DBROW::path_table row; wql { create table pathnames; create table alerts; insert into pathnames values ( "/etc/master.passwd", "/etc/passwd"), ( "/kernel", "/etc/motd"), ( "/lkm", "/tmp"), ( "/usr/games", "/usr/bin"), ( "/usr/tmp", "/tmp"), ( "/var/tmp", "/tmp") ; select into row from pathnames; }; } wr_uninstall() { wql { drop table pathnames; drop table alerts; }; } /* Intercept all syscalls containing paths before they run */ bsd::pattr{path} pre { DBROW::path_table row; string fullname; int changed = 0; /* Attempt to convert path from relative to absolute. If * the conversion doesn't succeed, it's a bad path. This * would normally be the end, but since we may be * redirecting from a non-existent path to one that exists, * we'll proceed */ if ((fullname = wr_abspath($path)) == NULL) { fullname = wr_strdup($path); } wql { select into row from pathnames; }; do { /* Do string substitutions for each pair of pathnames * and remember if any occurred. */ if (fullname =~ s|row.target|row.replacement|) changed++; } while (row.next()); /* Write out an alert to the database and change the path * parameter if any substitutions occurred. */ if (changed) { wql { insert into alerts values ($path, fullname, _pid, _uid); }; $path = fullname; } /* Cleanup */ wr_free(fullname); }; } My response is undoubtedly way too long. I'll make sure that a message is sent to this list when we make our source available. In the mean time, if you have any questions, let me know. Mark - ----- Mark S. Feldman TIS Labs at Network Associates, Inc. phone: +1 301 854 6889 3060 Washington Road fax: +1 301 854 5363 Glenwood, Maryland 21738 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe security" in the body of the message ------- End of Forwarded Message To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message