4

I am on Debian 9 (Stretch). I have a deploy user where I've set the shell to /bin/rbash. Here is the line from /etc/passwd:

deploy:x:9000:9000::/home/deploy:/bin/rbash

If I am the root user, and I run su - deploy or su -l deploy, then it starts rbash (echo $SHELL # => /bin/rbash), but commands are not being restricted:

~$ echo $SHELL  
/bin/rbash
~$ cd /tmp
/tmp$ echo asdf > /tmp/file
/tmp$ /bin/cat /tmp/file  
asdf   
# (Should not allow any commands with a slash)

If I just run su deploy:

~$ echo $SHELL
/bin/rbash
~$ cd /tmp
rbash: cd: restricted
~$ /bin/cat /etc/passwd
rbash: /bin/cat: restricted: cannot specify `/' in command names

Why doesn't rbash apply any restrictions if this is a login shell?

  • echo $SHELL just lists the login shell, but that doesn't prove that you're running it. What does echo $0 $- report? – muru Jun 03 '19 at 09:41
  • Thanks @muru, the output of echo $0 $- is: -su himBHs – ndbroadbent Jun 03 '19 at 09:57
  • Ah interesting, if I run su deploy, then the output of echo $- is himrBHs, where the r is the --restricted flag. I wonder why it's not being added for su - deploy? – ndbroadbent Jun 03 '19 at 10:00

1 Answers1

4

From the Bash manual:

If Bash is started with the name rbash, or the --restricted or -r option is supplied at invocation, the shell becomes restricted.

Now, "started with the name" means that $0, or the zeroth element of argv is that name. But when su starts it as a login shell, it sets the name to -su. And the -r option wasn't used either, so neither method of starting a restricted shell was used when su starts a login shell.

It should still take effect for other, proper means of login (such as SSH, or login(1) over a TTY).

muru
  • 72,889
  • Hello, thanks for your answer! I think you might be right!

    I've discovered something else in the su man page, in the --shell section that talks about the shell that will be invoked. It says that shell will be chosen first from the -s or --shell flag, then if --preserve-environment is used, it uses the existing $SHELL variable. Finally it looks at the entry in /etc/passwd.

    So I've been able to force the restricted bash shell by running: su -s /bin/rbash deploy. (And su -p -s /bin/rbash deploy, since I want the same env.)

    – ndbroadbent Jun 03 '19 at 10:14
  • But for some reason this still doesn't work if I run su -l -s /bin/rbash deploy. The bash flags are still himBHs, and it's not a restricted shell. If I run echo $0, I still get: "-su". – ndbroadbent Jun 03 '19 at 10:17
  • The other problem is that su -s /bin/rbash deploy doesn't load the deploy user's .bashrc or .profile, which is why I wanted the -l flag. – ndbroadbent Jun 03 '19 at 10:19
  • I also tried exec -a rbash su -l deploy to change the name in $0, but that didn't seem to do anything. echo $0 still shows: -su. But I finally realized that I can pass an argument to bash by using --.

    My final command is: exec su -l -p -s /bin/rbash deploy -- -r. Now echo $0 shows returns -su, but I'm explicitly passing the --restricted flag (-r), so echo $- shows hirBHs. (And I checked that I can't turn it off with set +r.)

    (exec is also a great idea because an attacker can't just exit to get back to the root user.)

    – ndbroadbent Jun 03 '19 at 10:32
  • One last thing! This command was still trying to load the .bashrc for the root user, because $HOME was not being reset properly (even though the su man page says that it should be.) So I needed to explicitly set the $HOME variable so that it loads the correct .bashrc: export HOME="/home/deploy" && exec su -l -p -s /bin/rbash deploy -- -r.

    Thanks for your help!

    – ndbroadbent Jun 03 '19 at 10:39