Re: I've found a vulnerability in bash
Date:Fri, 19 Nov 2021 13:40:16 -0600 From:Eric Blake Message-ID: <2029194016.5xn6gydfbtwmv...@redhat.com> | According to POSIX, perl should REALLY be passing a "--" argument | between "-c" and the scalar string given by the user; see | https://www.austingroupbugs.net/view.php?id=1440 posix says nothing at all about perl Further, even for the libc system() function, that change is still only in a draft, as you know, and while I don't expect there will be any issues with that particular change when the whole thing comes up for ratification, that's probably still the best part of a year away. Criticising anyone for not following an unpublished standard is hardly fair, even if it did apply. kre
Re: I've found a vulnerability in bash
On Fri, 19 Nov 2021 13:40:16 -0600 Eric Blake wrote: > On Fri, Nov 19, 2021 at 03:56:21PM +, Kerin Millar wrote: > > On Fri, 19 Nov 2021 10:05:39 -0500 > > Marshall Whittaker wrote: > > > > > Fair. I'm not saying anyone has to change it, but I will call out what I > > > think is a design flaw. But this is going to turn into some philosophical > > > discussion as to whether it should have been done this way from the start. > > > That I don't know, and hold no responsibility for, as I'm not a bash dev, > > > I'm an exploit dev. Maybe an asshole too. > > > > You appear to be missing the implication; it has nothing in particular to > > do with bash. Consider the following Perl program. At no point is a shell > > involved. > > > > @args = glob('*'); > > system('rm', '-f', @args); # bad > > I had to double-check you via 'strace -f -e execve ...', but you are > right, for this particular example. But according to 'perldoc -f > system', there ARE instances where perl's system() involves a shell: > >Note that argument processing varies depending on the > number of arguments. If there is more than one argument in LIST, > or if LIST is an array with more than one value, starts the > program given by the first element of the list with arguments > given by the rest of the list. If there is only one scalar > argument, the argument is checked for shell metacharacters, and > if there are any, the entire argument is passed to the system's > command shell for parsing (this is "/bin/sh -c" on Unix > > although /bin/sh is not always bash. But that brings up a bug in perl(1): > > $ strace -f -e execve perl -e 'system("echo \$HOME")' > execve("/usr/bin/perl", ["perl", "-e", "system(\"echo \\$HOME\")"], > 0x7ffc3e642e58 /* 72 vars */) = 0 > strace: Process 1248831 attached > [pid 1248831] execve("/bin/sh", ["sh", "-c", "echo $HOME"], 0x55d3099d69d0 /* > 72 vars */) = 0 > /home/eblake > [pid 1248831] +++ exited with 0 +++ > --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1248831, > si_uid=14986, si_status=0, si_utime=0, si_stime=0} --- > +++ exited with 0 +++ > > According to POSIX, perl should REALLY be passing a "--" argument > between "-c" and the scalar string given by the user; see > https://www.austingroupbugs.net/view.php?id=1440 While perl's system is not an implementation of system(3) per se, I concur. Good find. $ perl -E 'system("-h &")' sh: 0: Illegal option -h That does nobody any good. Indeed, it serves to remind me that even shebangs can be unsafe. $ mkdir -- -h $ printf '%s\n' '#!/bin/sh' > -h/script $ chmod +x -- -h/script $ -h/script sh: 0: Illegal option -h That's with dash as /bin/sh. The only defense would be to write the shebang as "#!/bin/sh --". -- Kerin Millar
Re: I've found a vulnerability in bash
(Copying the list back in ...) On Fri, 19 Nov 2021 17:37:54 +0100 Andreas Kusalananda Kähäri wrote: > On Fri, Nov 19, 2021 at 03:56:21PM +, Kerin Millar wrote: > > On Fri, 19 Nov 2021 10:05:39 -0500 > > Marshall Whittaker wrote: > > > > > Fair. I'm not saying anyone has to change it, but I will call out what I > > > think is a design flaw. But this is going to turn into some philosophical > > > discussion as to whether it should have been done this way from the start. > > > That I don't know, and hold no responsibility for, as I'm not a bash dev, > > > I'm an exploit dev. Maybe an asshole too. > > > > You appear to be missing the implication; it has nothing in particular to > > do with bash. Consider the following Perl program. At no point is a shell > > involved. > > I believe system() in Perl may well invoke sh -c depending on the > arguments given. See "perldoc -f system". Yes, but there would need to be "one scalar argument". > > @args = glob('*'); > > system('rm', '-f', @args); # bad At least two arguments are given there. Granted, the win32 port is an outlier but the sample clearly isn't intended for it. -- Kerin Millar
Re: I've found a vulnerability in bash
On Fri, Nov 19, 2021 at 03:56:21PM +, Kerin Millar wrote: > On Fri, 19 Nov 2021 10:05:39 -0500 > Marshall Whittaker wrote: > > > Fair. I'm not saying anyone has to change it, but I will call out what I > > think is a design flaw. But this is going to turn into some philosophical > > discussion as to whether it should have been done this way from the start. > > That I don't know, and hold no responsibility for, as I'm not a bash dev, > > I'm an exploit dev. Maybe an asshole too. > > You appear to be missing the implication; it has nothing in particular to do > with bash. Consider the following Perl program. At no point is a shell > involved. > > @args = glob('*'); > system('rm', '-f', @args); # bad I had to double-check you via 'strace -f -e execve ...', but you are right, for this particular example. But according to 'perldoc -f system', there ARE instances where perl's system() involves a shell: Note that argument processing varies depending on the number of arguments. If there is more than one argument in LIST, or if LIST is an array with more than one value, starts the program given by the first element of the list with arguments given by the rest of the list. If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix although /bin/sh is not always bash. But that brings up a bug in perl(1): $ strace -f -e execve perl -e 'system("echo \$HOME")' execve("/usr/bin/perl", ["perl", "-e", "system(\"echo \\$HOME\")"], 0x7ffc3e642e58 /* 72 vars */) = 0 strace: Process 1248831 attached [pid 1248831] execve("/bin/sh", ["sh", "-c", "echo $HOME"], 0x55d3099d69d0 /* 72 vars */) = 0 /home/eblake [pid 1248831] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1248831, si_uid=14986, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ According to POSIX, perl should REALLY be passing a "--" argument between "-c" and the scalar string given by the user; see https://www.austingroupbugs.net/view.php?id=1440 -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
Re: I've found a vulnerability in bash
On Fri, 19 Nov 2021 10:05:39 -0500 Marshall Whittaker wrote: > Fair. I'm not saying anyone has to change it, but I will call out what I > think is a design flaw. But this is going to turn into some philosophical > discussion as to whether it should have been done this way from the start. > That I don't know, and hold no responsibility for, as I'm not a bash dev, > I'm an exploit dev. Maybe an asshole too. You appear to be missing the implication; it has nothing in particular to do with bash. Consider the following Perl program. At no point is a shell involved. @args = glob('*'); system('rm', '-f', @args); # bad So, would it be Perl's fault that the programmer failed to demarcate the non-option arguments to rm(1)? Did I just publish a zero-day? No. Absolutely not. system('rm', '-f', '--', @args); # better Granted, one would normally use the native unlink function but that's besides the point. -- Kerin Millar
Re: I've found a vulnerability in bash
Fair. I'm not saying anyone has to change it, but I will call out what I think is a design flaw. But this is going to turn into some philosophical discussion as to whether it should have been done this way from the start. That I don't know, and hold no responsibility for, as I'm not a bash dev, I'm an exploit dev. Maybe an asshole too. On Fri, Nov 19, 2021 at 9:05 AM Kerin Millar wrote: > (Copying the list back in ...) > > On Fri, 19 Nov 2021 07:19:29 -0500 > Marshall Whittaker wrote: > > > Though I do disagree with you, this is the only message in this thread > that > > even makes sense. > > Firstly, rm * is a valid - albeit unsafe - simple command, and one that is > easily rectified. Secondly, the manner in which * expands is in accordance > with the documented behaviour. Thirdly, the manner in which simple commands > are processed is in accordance with the documented behaviour. In the event > that you can falsify the second and/or third of these assertions, then - > and only then - will you have discovered a bug in bash. > > As far as I can tell, your contention is that the default mode of pathname > expansion should be changed in order to paper over the first point. Very > well. Let's consider what would happen if, say, GLOBIGNORE=".*:-*" were to > be a default. > > * bash would violate POSIX [1] > * bash would be incompatible with other shells on this point > * existing scripts would change their behaviour and/or break (note: file > names beginning with a dash are perfectly legal) > * the behavioural change would not conclusively address the issue > > What do I mean by not addressing the issue? Fundamentally, the issue is > one of passing unsanitised input to an program, with the input taking the > form of an argument vector. Programs are free to act upon their arguments > in whatever way they see fit. While it may be common for argument beginning > with a dash to denote an option, this is by no means a cast-iron rule. If > the words produced by the expansion of a glob be arbitrary in nature, it is > your responsibility to understand how to convey them safely to a given > program. In many cases, assuming that responsibility turns out not to be > overly hard. The point is that it is beyond the purview of the shell. > > [1] > https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13 > > -- > Kerin Millar >
Re: I've found a vulnerability in bash
(Copying the list back in ...) On Fri, 19 Nov 2021 07:19:29 -0500 Marshall Whittaker wrote: > Though I do disagree with you, this is the only message in this thread that > even makes sense. Firstly, rm * is a valid - albeit unsafe - simple command, and one that is easily rectified. Secondly, the manner in which * expands is in accordance with the documented behaviour. Thirdly, the manner in which simple commands are processed is in accordance with the documented behaviour. In the event that you can falsify the second and/or third of these assertions, then - and only then - will you have discovered a bug in bash. As far as I can tell, your contention is that the default mode of pathname expansion should be changed in order to paper over the first point. Very well. Let's consider what would happen if, say, GLOBIGNORE=".*:-*" were to be a default. * bash would violate POSIX [1] * bash would be incompatible with other shells on this point * existing scripts would change their behaviour and/or break (note: file names beginning with a dash are perfectly legal) * the behavioural change would not conclusively address the issue What do I mean by not addressing the issue? Fundamentally, the issue is one of passing unsanitised input to an program, with the input taking the form of an argument vector. Programs are free to act upon their arguments in whatever way they see fit. While it may be common for argument beginning with a dash to denote an option, this is by no means a cast-iron rule. If the words produced by the expansion of a glob be arbitrary in nature, it is your responsibility to understand how to convey them safely to a given program. In many cases, assuming that responsibility turns out not to be overly hard. The point is that it is beyond the purview of the shell. [1] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13 -- Kerin Millar
Re: I've found a vulnerability in bash
On Fri, Nov 19, 2021 at 12:53 PM Marshall Whittaker < marshallwhitta...@gmail.com> wrote: > You could argue that bash should parse filenames globbed from * that start > with - and exclude them specifically, > Or a shell could prepend ./ to all globs relative globs. Not sure if that would change the behaviour of some program though. But you're free to write a shell or a patch to do something like that, and see if it gets any traction? I know at least zsh has some features to warn about doing things like rm *, but at least the version I tried doesn't seem to check for filenames that look like options. Though of course there's also the issue that some utilities take as options things that start with a plus, also. Like Bash's +O. > A short whitepaper on it has been made public at: > https://oxagast.org/posts/bash-wildcard-expansion-arbitrary-command-line-arguments-0day/ > complete with a mini PoC. > Given I just linked you two posts about that from 11 years ago, I fail to see how you could honestly consider that a "0-day" issue. Not that people falling into a decades-old trap is much better, actually, so it probably wouldn't be a bad thing if shells started warning about that.
Re: I've found a vulnerability in bash
On 19/11/2021 10:53, Marshall Whittaker wrote: You could argue that bash should parse filenames globbed from * that start with - and exclude them specifically, so I'll have to respectfully disagree. One could, but it would not make for a compelling argument. Define GLOBIGNORE, if you insist. Also, it is not the programs doing the parsing of *, that is a function of bash. Try typing * in just your terminal/command line and see what happens Yes. However, the presented 'exploit' hinges upon the behaviour of a selected external program. Luckily for you, any that uses getopt(3) will support -- as a means of concluding option recognition, rm(1) included. In the case that you are using a program where option arguments cannot be reliably separated from non-option arguments, specifying the glob as ./* will commonly suffice. A short whitepaper on it has been made public at: https://oxagast.org/posts/bash-wildcard-expansion-arbitrary-command-line-arguments-0day/ complete with a mini Po It's perplexing that your post relies upon the use of -- to get the point across, without acknowledging its import. At any rate, this does not constitute a vulnerability on the part of bash, much less a zero-day. -- Kerin Millar
Re: I've found a vulnerability in bash
dude, again, --version is not bashs arg, cp and touch et la are not bash and what u do there is start a suid bash is that such a wonder ? On Fri, Nov 19, 2021, 11:53 Marshall Whittaker wrote: > You could argue that bash should parse filenames globbed from * that start > with - and exclude them specifically, so I'll have to respectfully > disagree. Also, it is not the programs doing the parsing of *, that is a > function of bash. Try typing * in just your terminal/command line and see > what happens. > A short whitepaper on it has been made public at: > https://oxagast.org/posts/bash-wildcard-expansion-arbitrary-command-line-arguments-0day/ > complete with a mini PoC. > > On Wed, Nov 17, 2021 at 9:04 AM Chet Ramey wrote: > >> On 11/17/21 4:16 AM, Marshall Whittaker wrote: >> >> > This shouldn't happen beacuse you can drop a file and then redirect >> > other code for example calling a script if you only have access to drop >> > a file. Say a cronjob was running every hour, and it did rm * on some >> > folder, by expansion, you could expand it to -riv or whatever you >> > wanted and redirect program flow from there. >> >> That's just bad scripting. >> >> -- >> ``The lyf so short, the craft so long to lerne.'' - Chaucer >> ``Ars longa, vita brevis'' - Hippocrates >> Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/ >> >
Re: I've found a vulnerability in bash
You could argue that bash should parse filenames globbed from * that start with - and exclude them specifically, so I'll have to respectfully disagree. Also, it is not the programs doing the parsing of *, that is a function of bash. Try typing * in just your terminal/command line and see what happens. A short whitepaper on it has been made public at: https://oxagast.org/posts/bash-wildcard-expansion-arbitrary-command-line-arguments-0day/ complete with a mini PoC. On Wed, Nov 17, 2021 at 9:04 AM Chet Ramey wrote: > On 11/17/21 4:16 AM, Marshall Whittaker wrote: > > > This shouldn't happen beacuse you can drop a file and then redirect > > other code for example calling a script if you only have access to drop > > a file. Say a cronjob was running every hour, and it did rm * on some > > folder, by expansion, you could expand it to -riv or whatever you > > wanted and redirect program flow from there. > > That's just bad scripting. > > -- > ``The lyf so short, the craft so long to lerne.'' - Chaucer > ``Ars longa, vita brevis'' - Hippocrates > Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/ >
Re: I've found a vulnerability in bash
On 11/17/21 4:16 AM, Marshall Whittaker wrote: > This shouldn't happen beacuse you can drop a file and then redirect > other code for example calling a script if you only have access to drop > a file. Say a cronjob was running every hour, and it did rm * on some > folder, by expansion, you could expand it to -riv or whatever you > wanted and redirect program flow from there. That's just bad scripting. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: I've found a vulnerability in bash
On Wed, Nov 17, 2021 at 03:47:15PM +0200, Ilkka Virta wrote: > I don't see this in BashFAQ, though. Is it because it's not strictly about > Bash? Greg? https://mywiki.wooledge.org/BashPitfalls#pf3
Re: I've found a vulnerability in bash
On Wed, Nov 17, 2021 at 2:42 PM Marshall Whittaker < marshallwhitta...@gmail.com> wrote: > [marshall@jerkon]{04:09 AM}: [~/bashful] $ touch -- '--version' > [marshall@jerkon]{04:09 AM}: [~/bashful] $ rm * > rm (GNU coreutils) 8.30 > Copyright (C) 2018 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later < > https://gnu.org/licenses/gpl.html>;. > This is free software: you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law. > > Written by Paul Rubin, David MacKenzie, Richard M. Stallman, > and Jim Meyering. > [marshall@jerkon]{04:09 AM}: [~/bashful] $ > A common pitfall, due to how the utility can't tell what strings come from globs and what were given literally. See e.g. https://unix.stackexchange.com/questions/1519/how-do-i-delete-a-file-whose-name-begins-with-hyphen-a-k-a-dash-or-minus and https://dwheeler.com/essays/filenames-in-shell.html (though the latter is rather long and depressing.) I don't see this in BashFAQ, though. Is it because it's not strictly about Bash? Greg? Also, GNU rm has a helpful helptext about it: $ rm --help Usage: rm [OPTION]... [FILE]... Remove (unlink) the FILE(s). [...] To remove a file whose name starts with a '-', for example '-foo', use one of these commands: rm -- -foo rm ./-foo Note that if you use rm to remove a file, it might be possible to recover some of its contents, given sufficient expertise and/or time. For greater assurance that the contents are truly unrecoverable, consider using shred.
Re: I've found a vulnerability in bash
this is due to parsing of args by specific app, -- arg indicates end-of-switches On Wed, Nov 17, 2021, 13:41 Marshall Whittaker wrote: > Software: bash > Version: 5.0.17(1)-release (x86_64-pc-linux-gnu) > > --- SNIP --- > [marshall@jerkon]{04:09 AM}: [~/bashful] $ touch -- '--version' > [marshall@jerkon]{04:09 AM}: [~/bashful] $ touch a && mkdir b > [marshall@jerkon]{04:09 AM}: [~/bashful] $ ls -l > total 4 > -rw-rw-r-- 1 marshall marshall0 Nov 17 04:09 a > drwxrwxr-x 2 marshall marshall 4096 Nov 17 04:09 b > -rw-rw-r-- 1 marshall marshall0 Nov 17 04:09 --version > [marshall@jerkon]{04:09 AM}: [~/bashful] $ mv * b > mv (GNU coreutils) 8.30 > Copyright (C) 2018 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later < > https://gnu.org/licenses/gpl.html>;. > This is free software: you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law. > > Written by Mike Parker, David MacKenzie, and Jim Meyering. > [marshall@jerkon]{04:09 AM}: [~/bashful] $ rm * > rm (GNU coreutils) 8.30 > Copyright (C) 2018 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later < > https://gnu.org/licenses/gpl.html>;. > This is free software: you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law. > > Written by Paul Rubin, David MacKenzie, Richard M. Stallman, > and Jim Meyering. > [marshall@jerkon]{04:09 AM}: [~/bashful] $ > --- SNIP --- > > This shouldn't happen beacuse you can drop a file and then redirect > other code for example calling a script if you only have access to drop > a file. Say a cronjob was running every hour, and it did rm * on some > folder, by expansion, you could expand it to -riv or whatever you > wanted and redirect program flow from there. > > Thanks, > Marshall Whittaker / oxagast > > >
Re: I've found a vulnerability in bash
On Wed, Nov 17, 2021 at 04:16:36AM -0500, Marshall Whittaker wrote: > --- SNIP --- > [marshall@jerkon]{04:09 AM}: [~/bashful] $ touch -- '--version' > [marshall@jerkon]{04:09 AM}: [~/bashful] $ mv * b This isn't a vulnerability in bash. It's a bug in your script. Use this instead: mv -- * b