Is it just me, or did someone actually implement set-uid scripts? I've proposed some silly things over the decades (my favourite is stty() working on things other than terminals, and guess what, we got ioctl() etc) but I have a vague recollection of this... The trouble is, I've worked with dozens of Unix-based vendors over the years (some good, some not so much) and so I've lost track of all the stupidity that I've seen. ObAnecdote: Just about every Unix vendor went belly-up shortly after I left them (under various circumstances), because the waste-of-space middle managers simply did not appreciate the importance of having a Unix guru on board if you're in the game of selling Unix boxen. I'd happily name them, but I think the principals are still alive :-) -- Dave
[-- Attachment #1: Type: text/plain, Size: 422 bytes --] On Sun, 4 Aug 2019 at 08:37, Dave Horsfall <dave@horsfall.org> wrote: > Is it just me, or did someone actually implement set-uid scripts? Yes, they were a thing for a while, until someone realised that you could do: ln -s /bin/scriptname ./-i "-i" # assuming that "." is already in your path ...and get a root shell. Source: I did this on (ISTR) 4.1 or 4.2BSD. -a -- http://dropsafe.crypticide.com/aboutalecm [-- Attachment #2: Type: text/html, Size: 982 bytes --]
Dave Horsfall <dave@horsfall.org> wrote: > Is it just me, or did someone actually implement set-uid scripts? I think it worked in the early Unixen (V7, 4.1 time frame, more or less by accident) but after that the implications were recognized and only compiled binaries could be run setuid. > The trouble is, I've worked with dozens of Unix-based vendors over the > years (some good, some not so much) and so I've lost track of all the > stupidity that I've seen. It's not just Unix vendors. It's software (and hardware) companies in general. Arnold
> From: Alec Muffett > until someone realised that you could do: > ln -s /bin/scriptname ./-i > "-i" # assuming that "." is already in your path > ...and get a root shell. I'm clearly not very awake this morning, because I don't understand how this works. Can you break it down a little? Thanks! Noel
On 4 Aug 2019 11:58 -0400, from jnc@mercury.lcs.mit.edu (Noel Chiappa): >> until someone realised that you could do: >> ln -s /bin/scriptname ./-i >> "-i" # assuming that "." is already in your path >> ...and get a root shell. > > I'm clearly not very awake this morning, because I don't understand how this > works. Can you break it down a little? Thanks! I'm guessing a little here, but could it be related to poor command line argument parsing in some shell, where "-i" forces the shell to start in interactive mode and the shell looks for parameters _anywhere_ in its argv[] (including argv[0]), not just at argv[1] and later? That would match the result described by Alec, and my modern dash's man page does give that meaning for "-i", but it also feels like a trivial bug to fix in the shell without prohibiting setuid scripts... -- Michael Kjörling • https://michael.kjorling.se • michael@kjorling.se “The most dangerous thought that you can have as a creative person is to think you know what you’re doing.” (Bret Victor)
[-- Attachment #1: Type: text/plain, Size: 187 bytes --] The cited filename is passed as argv[1] If the filename is "-i" then the command is "/bin/sh -i" This forces an interactive shell. Hence the important of not invoking it as "./-i" -a [-- Attachment #2: Type: text/html, Size: 450 bytes --]
[-- Attachment #1: Type: text/plain, Size: 1060 bytes --] when running a shell script, what's actually executed is the first line of the script (after #!) + the name of the script. If your script is named "-i", and in your path, just enter "-i", and /bin/sh -i is executed which gives you an interactive shell. There are probably half a dozen other ways to trick the shell into executing arbitrary code that is not contained in the script (more if the script actually does anything non-trivial, like e.g. an installer of some sort). So instead of trying to fix them all (and most likely missing a few), everybody just agreed that it was a terrible idea and removed the feature. On Sun, Aug 4, 2019 at 9:00 AM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote: > > From: Alec Muffett > > > until someone realised that you could do: > > ln -s /bin/scriptname ./-i > > "-i" # assuming that "." is already in your path > > ...and get a root shell. > > I'm clearly not very awake this morning, because I don't understand how > this > works. Can you break it down a little? Thanks! > > Noel > > [-- Attachment #2: Type: text/html, Size: 1524 bytes --]
On 4 Aug 2019 17:48 +0100, from alec.muffett@gmail.com (Alec Muffett): > The cited filename is passed as argv[1] Well, that's even more obvious, and a little harder to "just fix" indeed. I stand corrected. -- Michael Kjörling • https://michael.kjorling.se • michael@kjorling.se “The most dangerous thought that you can have as a creative person is to think you know what you’re doing.” (Bret Victor)
[-- Attachment #1: Type: text/plain, Size: 338 bytes --] On Sun, 4 Aug 2019 at 18:57, Michael Kjörling <michael@kjorling.se> wrote: > Well, that's even more obvious 32 years of security, and I can't say one has passed without someone saying "in retrospect, [the bug] was obvious" about *something* — so you're in good company. :-) -- http://dropsafe.crypticide.com/aboutalecm [-- Attachment #2: Type: text/html, Size: 808 bytes --]
> From: Alec Muffett >>> ln -s /bin/scriptname ./-i >>> "-i" # assuming that "." is already in your path 'scriptname' (above) would have to be a shell script which was SETUID root? That was part of what I was missing, along with the below. > The cited filename is passed as argv[1] I wonder why it passed the link name, instead of the actual filename of the target (script)? Perhaps to allow one script to have multiple functions, depending on the name it was called with? But that could have been done with hard links? (Adding a hard link must require write access, because the link count in the inode has to be updated? So it would be equally secure as not having an SUID program with write access.) Part of the problem is having the kernel involved in starting shell scripts; convenient in some ways, but V6 etc worked fine without that 'feature'. Noel
[-- Attachment #1: Type: text/plain, Size: 744 bytes --] On Sun, Aug 4, 2019 at 4:18 PM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote: > Part of the problem is having the kernel involved in starting shell > scripts; convenient in some ways, but V6 etc worked fine without that > 'feature'. > That's a tough call. I have mixed opinions about it as a feature. I kind of like the user/kernel interface really, really thin and unadorned. Adding, it certainly made allowing multiple interpreters to be supported much easier; but as you say it opens a new can of worms. Given the later proliferation of what bwk or Jon Bently once referred too as 'little languages' (awk, perl, tcl, and sigh eventually python), it was probably a good feature. But as you said, v6 worked fairly well without it. Clem [-- Attachment #2: Type: text/html, Size: 2345 bytes --]
[-- Attachment #1: Type: text/plain, Size: 1005 bytes --] BSD added the #! "magic number" based on a suggestion from Ken I believe. Didn't the exec (2) manpage warn about argv[-1] being clobbered until that was added? On Sun, Aug 4, 2019, 4:31 PM Clem Cole <clemc@ccc.com> wrote: > > > On Sun, Aug 4, 2019 at 4:18 PM Noel Chiappa <jnc@mercury.lcs.mit.edu> > wrote: > >> Part of the problem is having the kernel involved in starting shell >> scripts; convenient in some ways, but V6 etc worked fine without that >> 'feature'. >> > That's a tough call. I have mixed opinions about it as a feature. I > kind of like the user/kernel interface really, really thin and unadorned. > > Adding, it certainly made allowing multiple interpreters to be supported > much easier; but as you say it opens a new can of worms. Given the later > proliferation of what bwk or Jon Bently once referred too as 'little > languages' (awk, perl, tcl, and sigh eventually python), it was probably a > good feature. > > But as you said, v6 worked fairly well without it. > > Clem > [-- Attachment #2: Type: text/html, Size: 2920 bytes --]
Noel Chiappa: I wonder why it passed the link name, instead of the actual filename of the target (script)? Perhaps to allow one script to have multiple functions, depending on the name it was called with? ==== In fact the latter is still used here and there in standard system distributions. But from a security viewpoint it doesn't matter. For ln -s /bin/scriptname ./-i substitute execl("/bin/scriptname", "-i", (char *)0); If you can execute a program, you can fake its arguments, including argv[0]. There is no defence. Norman Wilson Toronto ON
Oops. Didn't think it through: the problem is argv[1], passed as the name of the script being executed, not argv[0]. Disregard my previous execl(...). A related problem is the inherent race condition: If you do ln -s /bin/setuidscript . ./setuidscript ./setuidscript is opened twice: once when the kernel reads it and finds #! as magic number and execs the interpreter, a second time when the interpreter opens ./setuidscript. If you meanwhile run something that swoops in in the background and replaces ./setuidscript with malicious instructions for the interpreter, you win. I remember managing to do this myself at one point in the latter part of the 1980s. That was when I fell out of love with setuid interpreter scripts. It looks like we didn't disable the danger in the Research kernel, though. I don't remember why not. Norman Wilson Toronto ON
On Sun, 4 Aug 2019, Noel Chiappa wrote:
> 'scriptname' (above) would have to be a shell script which was SETUID root?
> That was part of what I was missing, along with the below.
Well, it's in the Subject: line :-)
-- Dave
> From: Dave Horsfall > Well, it's in the Subject: line :-) That was my _assumption_, but you know the old line about assumptions. Noel
> A related problem is the inherent race condition: > If you do > ln -s /bin/setuidscript . > ./setuidscript > ./setuidscript is opened twice: once when the kernel > reads it and finds #! as magic number and execs the > interpreter, a second time when the interpreter opens > ./setuidscript. If you meanwhile run something that > swoops in in the background and replaces ./setuidscript > with malicious instructions for the interpreter, you > win. This was always described to me as the canonical reason why setuid interpreted scripts were a security hole, irrespective of any specifics in the shell or other interpreter. However, there's a workaround: use fdescfs. fdescfs allows the kernel to open the script, and then pass the fdescfs path for the (already open) descriptor to the interpreter as the command to run. According to https://www.in-ulm.de/~mascheck/various/shebang/#setuid, this is supported by many systems, including Solaris, several BSDs, and OSX (with a sysctl). -Jason
jason-tuhs@shalott.net wrote: > > A related problem is the inherent race condition: > > If you do > > ln -s /bin/setuidscript . > > ./setuidscript > > ./setuidscript is opened twice: once when the kernel > > reads it and finds #! as magic number and execs the > > interpreter, a second time when the interpreter opens > > ./setuidscript. If you meanwhile run something that > > swoops in in the background and replaces ./setuidscript > > with malicious instructions for the interpreter, you > > win. > > This was always described to me as the canonical reason why setuid > interpreted scripts were a security hole, irrespective of any specifics > in the shell or other interpreter. > > However, there's a workaround: use fdescfs. fdescfs allows the kernel to > open the script, and then pass the fdescfs path for the (already open) > descriptor to the interpreter as the command to run. I'm guessing by this you files like /dev/fd/42. > According to https://www.in-ulm.de/~mascheck/various/shebang/#setuid, this > is supported by many systems, including Solaris, several BSDs, and OSX > (with a sysctl). There's a historical disconnect here. Setuid scripts were disabled in the mid- to late 80s. /dev/fd didn't hit the commercial Unix world until SVR4 in 1989, and didn't get into the other systems you mention until even later. So yes, that might have worked, but the solution came along too late. Arnold
On Tue, 6 Aug 2019, jason-tuhs@shalott.net wrote:
[ Replacing a temporary set-uid file ]
> This was always described to me as the canonical reason why setuid
> interpreted scripts were a security hole, irrespective of any specifics
> in the shell or other interpreter.
It's a problem for any temporary files in a world-writable directory,
hence the extensions to directory permissions e.g. /tmp and /var/tmp...
Amusingly enough, the Mac works around this by symlinking /tmp to
private/tmp i.e. you get your own /tmp...
-- Dave
This brought to mind this old discussion: https://www.tuhs.org/Usenet/comp.unix.wizards/1988-November/023460.html On Tue, Aug 6, 2019 at 3:49 PM Dave Horsfall <dave@horsfall.org> wrote: > > On Tue, 6 Aug 2019, jason-tuhs@shalott.net wrote: > > [ Replacing a temporary set-uid file ] > > > This was always described to me as the canonical reason why setuid > > interpreted scripts were a security hole, irrespective of any specifics > > in the shell or other interpreter. > > It's a problem for any temporary files in a world-writable directory, > hence the extensions to directory permissions e.g. /tmp and /var/tmp... > > Amusingly enough, the Mac works around this by symlinking /tmp to > private/tmp i.e. you get your own /tmp... > > -- Dave
Just to extend this thread a bit more, when did the set[ug]id bit start getting turned off if the file was overwritten? I've used so many *x systems over the years that I cannot remember, but I don't think even root was exempt i.e. part of any upgrade process was to put it back again. -- Dave
On 8/6/19 6:48 PM, Dave Horsfall wrote: > It's a problem for any temporary files in a world-writable directory, hence > the extensions to directory permissions e.g. /tmp and /var/tmp... > > Amusingly enough, the Mac works around this by symlinking /tmp to > private/tmp i.e. you get your own /tmp... /private/tmp is still word-writable with the sticky bit set. What you do get is a private $TMPDIR, e.g., /var/folders/41/pgctqv8s3_301dzlcghzcbs800008y/T/ -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRU chet@case.edu http://tiswww.cwru.edu/~chet/
On Tue, 6 Aug 2019, Lyndon Nerenberg wrote: >> Just to extend this thread a bit more, when did the set[ug]id bit start >> getting turned off if the file was overwritten? > > I'm pretty sure that's been the case since the dawn of time. Hmmm... I have this vague memory of V5 (which I only used for a couple of months before we got V6) not clearing that bit, but after all these years my memory is starting to fail me :-( > It was certainly the case in every System V (release 0 and beyond) I > worked with, along with many BSDs derivatives (SunOS 3+, Ultrix, etc). > (And Xenix, which had it's own insanity that I now think selinux is > trying to inflict on me.) I've always thought that Xenix was insane to start with... Then again, my first experience with it was on a 286... Now, when porting Unify, should I use large memory model here or small memory model? Crazy. > This has been documented in chown(2) for as long as I can remember, so > that's a good place to start if you want to dig back through the various > source trees. I don't have access to the sources right now, but I'll take your word for it; it was just a passing thought. -- Dave
On Wed, 7 Aug 2019, Chet Ramey wrote:
>> Amusingly enough, the Mac works around this by symlinking /tmp to
>> private/tmp i.e. you get your own /tmp...
>
> /private/tmp is still word-writable with the sticky bit set. What you do
> get is a private $TMPDIR, e.g.,
>
> /var/folders/41/pgctqv8s3_301dzlcghzcbs800008y/T/
Aha! You have just unwittingly solved a mystery for me :-) I was
wondering where those files were coming from...
I'm not really a Mac freak; apart from the occasional port, I just use it
to SSH into my FreeBSD server, with multiple Terminals all over the
screen..
Thanks!
-- Dave
> On Aug 7, 2019, at 2:40 PM, Dave Horsfall <dave@horsfall.org> wrote: > > I'm not really a Mac freak; apart from the occasional port, I just use it to SSH into my FreeBSD server, with multiple Terminals all over the screen.. iTerm2 is really rather nice. Folks here may be interested in a new toy of mine: https://mvsevm.fsf.net Currently, the TOPS-10 guest account (42,42) and the Unix v7 account dmr have no passwords. Please treat the dmr account respectfully. I will get to account requests…eventually, probably. TImeliness is not guaranteed. All systems are hosted on Raspberry Pis (the 36-bit ones on a Pi 3B+ and the 16-bit and 32-bit ones on a Pi 2B+) on Debian Buster. Absolutely no guarantee of availability or usability is made. Adam
[-- Attachment #1: Type: text/plain, Size: 1273 bytes --] On 2019-Aug-08 07:33:47 +1000, Dave Horsfall <dave@horsfall.org> wrote: >I've always thought that Xenix was insane to start with... Then again, my >first experience with it was on a 286... Now, when porting Unify, should >I use large memory model here or small memory model? Crazy. Ah, yes. I remember it well. The large, small and various mixed modes were a consequence of the braindeadedness of the 286 - reloading segment registers (pretty much every memory reference in large mode) was abysmally slow. I recall hacking mg (a cut-down emacs clone) so that buffers were in "far" memory and everything else was "near". Some of the Xenix features I recall were: * occasionally fork() would return -1 in both the parent and child (or something like that - it would both succeed and report failure) * The contents of comments would affect the Pascal compiler's ability to compile the program (this was "using uninitialised variables" behaviour, rather than magic lint-style comments). It made software development "interesting" because checking a program into SCCS might stop it compiling. * fork()ing a large process could panic the system. * The C compiler barfed on parts of starchart (from comp.sources.???) -- Peter Jeremy [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 963 bytes --]
On 8/8/19, Adam Thornton <athornton@gmail.com> wrote: > > >> On Aug 7, 2019, at 2:40 PM, Dave Horsfall <dave@horsfall.org> wrote: >> >> I'm not really a Mac freak; apart from the occasional port, I just use it >> to SSH into my FreeBSD server, with multiple Terminals all over the >> screen.. > > > iTerm2 is really rather nice. > > Folks here may be interested in a new toy of mine: > > https://mvsevm.fsf.net I like this. CTSS would make a good addition to the collection. I've always loved the CTSS - Multics - Unix progression, with Multics having so much ambition, and Unix coming out of that with simplicity and taste and no expectations. > > Currently, the TOPS-10 guest account (42,42) and the Unix v7 account dmr > have no passwords. > > Please treat the dmr account respectfully. > > I will get to account requests…eventually, probably. TImeliness is not > guaranteed. All systems are hosted on Raspberry Pis (the 36-bit ones on a > Pi 3B+ and the 16-bit and 32-bit ones on a Pi 2B+) on Debian Buster. > Absolutely no guarantee of availability or usability is made. > > Adam > > >