Potential restricted bash escape by modifying history file

2020-04-30 Thread Diffie
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -O2 -g -pipe -Wall -Werror=format-security 
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions 
-fstack-protector-strong -grecord-gcc-switches 
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic 
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection 
-Wno-parentheses -Wno-format-security
uname output: Linux host 5.5.17-200.fc31.x86_64 #1 SMP Mon Apr 13 15:29:42 UTC 
2020 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 5.0
Patch Level: 11
Release Status: release

*Description:*
It is possible to write/append arbitrary content to files from a restricted 
bash shell (with the privileges of the current user context) by tweaking the 
HISTFILE variable, or by specifying a filename to "history -[a][w]". This does 
not necessarily lead to a restriction bypass in all configurations, but does in 
a few that come to mind:

* If the user can write to their home directory they can append arbitrary code 
to .bashrc/other shell files. These shell files will execute the code without 
restrictions on subsequent runs of rbash (assuming rbash is not being run in 
posix mode, and that --norc is not being passed)
* If the user is root they can trivially get an unrestricted shell by modifying 
/etc/passwd, etc.
* If the cwd contains an executable script that the user can write to, they can 
append to the script with arbitrary code, then invoke this code from rbash: 
"hash -p executable_script mal_command ; mal_command" (this could be possible 
with an executable binary too, although would be a little more complex)
* SSH authorized keys, various other configs.
* etc...

Again, it will depend on the configuration, but this seems exploitable in most 
configurations of rbash (one where it may be more difficult to exploit is when 
the user is placed into a non-home directory chroot where they have limited 
write access).


*Repeat-By:*
[UNRESTRICTED] bash-5.0$ PATH= /bin/bash -r
[__RESTRICTED] bash-5.0$ export HISTFILE=$HOME/.bashrc
[__RESTRICTED] bash-5.0$ history -c
[__RESTRICTED] bash-5.0$ /usr/bin/whoami
[__RESTRICTED] bash: /usr/bin/whoami: restricted: cannot specify `/' in command 
names
[__RESTRICTED] bash-5.0$ history -a
[__RESTRICTED] bash-5.0$ exit

[UNRESTRICTED] bash-5.0$ PATH= /bin/bash -r
diffie # whoami inserted into .bashrc above
[__RESTRICTED] bash-5.0$

OR without using HISTFILE variable

[UNRESTRICTED] bash-5.0$ PATH= /bin/bash -r
[__RESTRICTED] bash-5.0$ history -a $HOME/.bashrc '
> /usr/bin/whoami
> '
[__RESTRICTED] bash-5.0$ exit

[UNRESTRICTED] bash-5.0$ PATH= /bin/bash -r
diffie
[__RESTRICTED] bash-5.0$


*Fix:
*
* Disable writing to a specific file in rbash with "history -[a][w] 
/tmp/bad_file bad_command" and make HISTFILE readonly. May be some other edge 
cases here.
* Disable history in rbash altogether.


Re: How functions are defined

2020-04-30 Thread Chet Ramey
On 4/27/20 10:03 PM, Dale R. Worley wrote:

> So it seems the reserved rule is more accurately:
> 
>Reserved words are words that have a special meaning to the
>shell.  The following words are recognized as reserved when
>unquoted and either (1) where the first word of a simple command
>could be (see SHELL GRAMMAR below), (2) the third word of a case,
>for, or select command, the (3) first word of the body of a function
>definition, or (4) after a semicolon or newline:
> 

> 
> ... Looking at this again, I think (1) and (3) can be replaced by "the> first 
> word of a command (see SHELL GRAMMAR below)", which helps.

I'll rework it to use "the first word of a command" with the two execptions
(third word of case/select, third word of for). This is pretty close to
what POSIX has. Thanks for the report.

Chet
-- 
``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: Local variable names clash with global read-only variable names.

2020-04-30 Thread Chet Ramey
On 4/28/20 2:28 PM, Greg Wooledge wrote:
> On Tue, Apr 28, 2020 at 08:14:28PM +0200, andrej--- via Bug reports for the 
> GNU Bourne Again SHell wrote:
>> f() { local x=a; }
>> declare -r x
>> f  # bash: local: x: readonly variable
>>
>>   This^^^ should not fail; it hinders reusability of shell functions and 
>> makes
>>   them context-dependent.
> 
> The purpose of 'readonly' as a variable attribute is to supplement a
> restricted shell environment.  If a variable is set readonly, it's because
> the system administrator, or whoever set up the enviroment, demands that
> this variable NOT be changed by the end user.

The second sentence is true, but extends beyond the restricted shell
environment. Variables are readonly for a reason.

-- 
``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: Local variable names clash with global read-only variable names.

2020-04-30 Thread Dale R. Worley
>>> f() { local x=a; }
>>> declare -r x
>>> f  # bash: local: x: readonly variable
>>>
>>>   This^^^ should not fail; it hinders reusability of shell functions and 
>>> makes
>>>   them context-dependent.

It's "natural" to think that a variable that is local to a function
should be independent of however it is declared globally.  The problem
is that bash local variables aren't lexically scoped -- when you enter
the function, the variable acquires the new value, but any function that
is called by this function sees the new value, even if that function
wasn't declared inside the function that declared the variable local.
So if a local declaration could override a readonly declaration, the new
value could be seen by code unrelated the function that did the
override.

This is a common issue in language design.  The Perl language originally
only had "local" declarations that behaved the same way as bash local
declarations.  But the above behavior got to be so much of a problem for
large programs that Perl added a separate lexically-scoped local
declaration.

Dale