SFTP chroot: Writable root

halfdog me at halfdog.net
Wed Jan 10 08:21:14 AEDT 2018


Jakub Jelen writes:
> On Sun, 2018-01-07 at 18:41 +0000, halfdog wrote:
> > Hello list,
> > 
> > I created a page to demonstrate, what would happen when chroot
> > root directory is writeable. In fact, code execution is possible
> > already, when only /etc and /bin are writable. I also tried to
> > escape the chroot jail, but that did not work for non-root users.
> > 
> > As the 2009 CVE activities mention, that creating hardlinks
> > from outside gives trivial chroot, I showed that any cooperating
> > access from the outside - no matter if it is the same user or
> > another one - leads to root privilege escalation, even without
> > hardlinks, just using the default behaviour of any shared linked
> > SUID binary.
> > 
> > hd
> > 
> > [0]
> > https:///www.halfdog.net/Security/2018/OpensshSftpChrootCodeExecution
> > /
> 
> Thank you for the article describing this issue in understandable
> manner. What struck my attention is the reading of the /etc/ssh/sshrc
> from chroot.
> 
> Is it even correct that OpenSSH is searching for the /etc/ssh/sshrc
> file AFTER the chroot?

Yes, definitely - on Ubuntu Xenial and Debian stretch. Here is, how
you can test yourself:

* Connect to the test machine as root

* Find the main SSH process, usually something like:

root       752  0.0  0.1  55184  2788 ?        Ss    2017   0:00 /usr/sbin/sshd -D

* Use "strace -o trace.txt -s256 -f -p [pid]"

* Login via sftp and then terminate strace

* Search the file:

grep -E -e '(chroot|open|lstat|stat)\(' trace.txt

Some line should look like:

906   chroot("/var/lib/sftp")           = 0



There are multiple weaknesses to be seen:

* Ssh searches for /proc/[pid]/fd: I do not know, how sftp would
  react, when that directory is found, but it is not nice, that
  a hypothetical user "proc" could influence login behavior of
  other processes

907   open("/proc/907/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

  Same argument for:

906   stat("/usr/lib/openssh/sftp-server", 0x7fff75547e00) = -1 ENOENT (No such file or directory)

  (When found, it is still not executed in sftp-internal mode)

* Loading of sshrc - really bad:

907   stat("/etc/ssh/sshrc", 0x7fff75547460) = -1 ENOENT (No such file or directory)

* Search for other /etc files - I would not bet, that the passwd
  parser was hardened against malicious input. Simply not a use case.

895   open("/etc/localtime", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
895   open("/etc/passwd", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
895   open("/etc/group", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

* This is also seems not really nice: if the target directory does not
  exist, login does not stop. But maybe it is a requirement, e.g.
  to support login to users without having their own home directory.

907   chdir("/home/build")              = -1 ENOENT (No such file or directory)

> No, I am not advocating the writable chroots, but is sounds to me
> wrong, or at least nothing I would expect. Even though it is not
> exploitable out of the box, it might be if one chooses "wrong" names
> for users directories (well ... etc/ might not be too uncommon).

It is really bad from software design perspective because it indicates,
that code intended for shell login is also execututed in seemingly
unrelated context. If you take the pessimist's view: if ".sshrc"
execution deactivation was missed, what else could be there with
unexpected behavior?

hd




More information about the openssh-unix-dev mailing list