Introduction
Haystack is classified as an easy difficulty machine on HTB. An ELK (Elasticsearch, Logstash, Kibana) based machine it offered me a chance to dig into the logging technology. I thought this was machine was particularly well designed and allowed me to go from simply knowing what ELK is to going through each part of the stack and working through vulnerabilities for each component.
Initial Recon
As usual, let's start with an nmap enumartion to see what we are working with.
Port 9200 seems interesting. It looks like it's a web-service of some kind so let's open it up and take a look.
Elasticsearch eh? Even have the version that is running. I'll table that for later if needed. I'll fully admit that while I knew what elasticsearch was I had absolutely no idea how to work with it prior to this engagement. After doing a bit searching around and getting the hang of some basics I was able to take get search and queries working. Discovered the quotes index and found some interesting information.
User exploitation
At this point I hit my first roadblock. I could surmise from _id
that there was data I was not being shown with the query. After a bit more reading I believe it was related to the max_score
and score
attributes. A bit more beating my head against the queries and I took a step back. A quick search for "how to dump all data from elasticsearch" led me to a useful tool - es2csv. After getting everything setup I fired it off and managed to dump 1254 entries. Wow! That's a lot more than what I originally found manually.
Digging through the output file I don't see much useful information. It definitely doesn't help I don't speak Spanish fluently and I didn't think that translating the entire dump would be part of the required steps.
Ok time to take another step back. During initial enumeration I did quickly take a look at port 80. All there was is a jpg and quick look at the source didn't turn anything up. Considering the box is called Haystack and the picture was ominously named needle.jpg
I figured it warranted a closer look. Sure enough within 30 seconds I find something very interesting.
Which after a quick decode and google translate we get something that makes a little more sense.
So the needle is "key" eh? After parsing through the csv dump grepping for various "key"-words, I ended up going more literal and it paid off.
That's more like it. From earlier we saw that ssh
was open so let's give it a try.
Alright user down!
Root exploitation
With our new access I took a poke around the box for the usual suspects. Unfortunately security had quite limited access on the host. I was able to see one interesting thing as far as listening ports.
Listening only on 127.0.0.1 seems intriguing as an avenue. Knowing that elasticsearch was installed on the box I searched around and it did not take much time to get to - this article.
The default settings configure Kibana to run on localhost:5601. To change the host or port number, or connect to Elasticsearch running on a different machine, you’ll need to update your kibana.yml file. You can also enable SSL and set a variety of other options. Finally, environment variables can be injected into configuration using ${MY_ENV_VAR} syntax.
We know the version from our initial enumeration. After attempting to glean some information from the port unsuccessfully I stumbled on to CVE-2018-17246.
Kibana versions before 6.4.3 and 5.6.13 contain an arbitrary file inclusion flaw in the Console plugin. An attacker with access to the Kibana Console API could send a request that will attempt to execute javascript code. This could possibly lead to an attacker executing arbitrary commands with permissions of the Kibana process on the host system.
We just happen to have 6.4.2 running, check, and we have access to the console api, double check. We get the reverse shell file over to /tmp
where we have write permissions. With everything in place, we set up a listener and kick off the exploit.
User pivot, done. Now the question of the day - what do we have access to as kibana that we didn't as security. After several various dead ends I found something worth taking a deeper look.
By itself this wasn't that meaningful, however the type => "execute"
is where they got me interested. I followed through and looked at /opt/kibana
to see how deep the hole went.
Ok so it looks like it is pointing to script and based on my understanding at this point it seems like it would be executed. Very, very interesting. After spending some time reading this Logstash reference I started understanding how it all worked together.
- Based on input.conf - logstash checks
/opt/kibana
every 10 seconds for files starting withlogstash_*
- Based on filter.conf - if the contents of these logstash_* files match the Grok filter of "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" then...
- Based on output.conf - execute the command that was supplied as
comando
With this understanding let's add our reverse shell to /tmp
and create our own logstash_
entry in /opt/kibana
and setup the listener locally.
And with that Haystask is in the books.
Thanks folks. Until next time.