WriteUp PwnLab: init

Essa writeup é sobre a PwnLab:init, é uma BOX OSCP Like recomendada para pratica no exame OSCP. Segundo o autor da box, o nível de dificuldade é baixo.

Os desafios encontrados na resolução dessa box foram bem interessantes, o reconhecimento do alvo foi bem direto, com poucas aplicações. Na etapa de exploração, foram exploradas falhas na aplicação Web, sendo duas de LFI e uma de Arbitrary File Upload. Posteriormente, na etapa de escalação de privilégios, foi possível obter acesso root de duas formas distintas, sendo a primeira através de binários com a flag SUID e a forma alternativa foi através de execução de um exploit.

Target IpAddress:172.16.0.103
VulnHubMachineName:
PwnLab: init
URL: https://www.vulnhub.com/entry/pwnlab-init,158/

Descrição:

Wellcome to "PwnLab: init", my first Boot2Root virtual machine. Meant to be easy, I hope you enjoy it and maybe learn something. The purpose of this CTF is to get root and read de flag.

Can contact me at: claor@pwnlab.net or on Twitter: @Chronicoder

    Difficulty: Low
    Flag: /root/flag.txt

Reconhecimento

Durante a etapa de enumeração, foi possível identificar que o alvo possui diversas portas TCP abertas de serviços como HTTP(80/TCP) e MYSQL(3306/TCP).

Resultado da execução da ferramenta Nmap

Testes de enumeração de arquivos e diretórios foram realizados contra a URL http://172.16.0.103/, diversos arquivos PHP e diretórios foram identificados.

Diretórios e arquivos enumerados pela ferramenta GoBuster.

Exploração.

Testes na aplicação web identificaram uma falha de LFI na URL http://172.16.0.104/?page=. A falha de LFI detectada permitiu a leitura de arquivos do servidor alvo a partir da funcionalidade do php conhecida como filter, onde os caracteres são encodados em base64 quando se trata de arquivos php, evitando que eles sejam processados pelo server-side.

Payload utilizado:

http://10.1.0.114/?page=php://filter/convert.base64-encode/resource=config

A falha permitiu extrair as credenciais do banco de dados localizadas no arquivo config.php, arquivo qual foi enumerado em etapa anterior com o GoBuster.

Extração de credenciais em texto claro no arquivo http://10.1.0.114/config.php
$server	  = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";

Utilizando as credenciais encontradas no arquivo config.php, foi possível realizar o acesso ao banco de dados MySQL qual está exposto na porta default 3306/TCP.

Acesso a banco de dados em alvo e enumeração de bases de dados.

Com o acesso root no banco de dados remoto, foi possível enumerar além do banco de dados, as tabelas e colunas da aplicação web.

Enumeração de tabelas e colunas do banco de dados Users.

O acesso a base de dados permitiu obter acesso a credenciais de usuários na tabela users no banco de dados Users.

Dump de credenciais de usuários.

Foi identificado que as senhas estão encodadas em base64, posteriormente o processo de decode utilizando a ferramenta base64 com a flag de -d(ou –decode), foi possível obter as credenciais em texto claro.

kent:JWzXuBJJNy
mike:SIfdsTEn6I
kane:iSv5Ym2GRo 

A credencial do usuário Kane(kane:iSv5Ym2GRo) foi utilizada para acessar a plataforma, permitindo a realização de arquivos para a aplicação na URL http://10.1.0.114/?page=upload.

Teste de upload em funcionalidade de upload.php da aplicação web no alvo.

Com o objetivo de identificar as restrições que a feature de upload impõe, a falha de LFI encontrada anteriormente foi novamente explorada para obter acesso ao código fonte do arquivo upload.php.


$ curl -sq  http://10.1.0.114/?page=php://filter/convert.base64-encode/resource=upload | grep -e '[^\ ]\{40,\}' | base64 -d
<?php
session_start();
if (!isset($_SESSION['user'])) { die('You must be log in.'); }
?>
<html>
	<body>
		<form action='' method='post' enctype='multipart/form-data'>
			<input type='file' name='file' id='file' />
			<input type='submit' name='submit' value='Upload'/>
		</form>
	</body>
</html>
<?php 
if(isset($_POST['submit'])) {
	if ($_FILES['file']['error'] <= 0) {
		$filename  = $_FILES['file']['name'];
		$filetype  = $_FILES['file']['type'];
		$uploaddir = 'upload/';
		$file_ext  = strrchr($filename, '.');
		$imageinfo = getimagesize($_FILES['file']['tmp_name']);
		$whitelist = array(".jpg",".jpeg",".gif",".png"); 

		if (!(in_array($file_ext, $whitelist))) {
			die('Not allowed extension, please upload images only.');
		}

		if(strpos($filetype,'image') === false) {
			die('Error 001');
		}

		if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
			die('Error 002');
		}

		if(substr_count($filetype, '/')>1){
			die('Error 003');
		}

		$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;

		if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
			echo "<img src=\"".$uploadfile."\"><br />";
		} else {
			die('Error 4');
		}
	}
}

?>

O código upload.php demonstra possuir alguns mecanismos de validação, como:

  • Validação por extensão de arquivo com base em whitelist com extensões permitidas.
$whitelist = array(".jpg",".jpeg",".gif",".png");
if (!(in_array($file_ext, $whitelist))) { 
  • Verificação utilizando função strpos da existência da string image na variável $filetype
$filetype  = $_FILES['file']['type'];
if(strpos($filetype,'image') === false) { 
  • Verificação de mimeType passado na requisição.
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {

Posteriormente, o arquivo é submetido para o diretório upload e seu nome é alterado para uma função de hash md5 que é gerado a partir do nome e extensão do arquivo.

$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;
Identificação de destino de arquivo posteriormente, no diretório upload/ com combinação de hash md5

Analisando como a feature de upload(upload.php) realiza as validações, é possível realizar o upload de um arquivo que contenha código PHP, porém não seria possível executar ele diretamente.

Upload de arquivo malicioso.

A execução do arquivo malicioso foi executada a partir de uma segunda falha de LFI encontrada posteriormente uma analise do código fonte do arquivo index.php.

LFI encontrado na variável lang definida a partir de cookie no arquivo index.php

A analise identificou que existe outro LFI na variável lang definida a partir de um cookie permitiu carregar o jpg e executar código arbitrário. Uma vez que a variável lang é definida em cookie, é possível executar o código malicioso.

Validação de falha foi realizada com comando simples de PING.

A partir disso, o upload de uma webshell php foi realizada, uma vez definido o path do arquivo malicioso na variável LANG através do cookie, foi possível obter uma conexão reversa.

Conexão reversa sendo estabelecida com o alvo.

Privilege Escalation.

Com acesso shell a partir de uma conexão revesa executada pela segunda falha de LFI, foi possível testar se as credenciais localizadas no banco de dados podem ser utilizadas para lateralização. A credencial do usuário kane(kane:iSv5Ym2GRo) localizada no banco de dados é a mesma para o sistema operacional.

Lateralização para usuário kane com credenciais encontradas em banco de dados.

No diretório do usuário kane foi encontrado um binário cujo nome é msgmike. Esse arquivo pertence ao usuário Mike(owner) e possui a flag SUID ativada.

Identificação de binário msgmike, localizado no diretório /home/kane.

Uma analise estatica no binário identificou que ele executa o comando “cat /home/mike/msg.txt“.

Dump de strings em binário identificou execução de comando.

Caso o PATH do usuário seja alterado, é possível executar um programa que se chame ‘cat’ no mesmo diretório. Nesse cenário é possível que binário execute esse novo comando como usuário mike, possibilitando a obtenção de uma lateralização de usuário.

Foi criado uma copia do binário /bin/bash para o diretório /home/kane/ com o nome de cat. Posteriormente foi necessário alterar o path para o diretório local. Uma vez que o programa msgmike fosse executado, uma shell com o usuário mike seria aberta.

Alteração do PATH e execução de programa /bin/bash com nome alterado para cat no diretório local.

No diretório home do usuário mike, existe um arquivo msg2root, esse binário possui SUID habilitado, logo, seria possível obter acesso root(id 0). Durante analise, foi identificado que o binário msg2root possui uma falha de command injection, permitindo abrir uma shell com privilégios de usuário root devido ao SUID.

Nota: A abertura do shell bash não resultava no usuário id 0, a abertura do sh permitiu acesso shell com usuário id 0.

Execução de command Injection e obtenção de shell /bin/sh com usuário root.

Uma vez com usuário root, é possível obter acesso a flag e finalizar a challenge.

Leitura de arquivo /root/flag.txt com usuário admistrativo.

Privilege Escalation, part 2.

Uma segunda forma de escalar privilégios foi identificada. É possível a partir do exploit cowroot.c que explora a falha DirtyCow, obter acesso root no sistema.

Execução de exploit em alvo permitiu a obtenção de usuário root.

Conclusão

Foi uma box interessante, a utilização das falhas de LFI com a utilização da funcionalidade php://filter para extrair arquivos php do servidor. A segunda falha de LFI foi necessária para o sucesso da execução do arquivo malicioso e obtenção do primeiro acesso ao sistema. A escalação de privilégios teve seus desafios, um fato curioso foi a exploração do binário com SUID de root só ter sido possível com a utilização da shell /bin/sh, ao que aparenta é alguma medida de proteção do sistema.

Links/Recursos:

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.