quarta-feira, 9 de março de 2016

GitMiner - Advance Search for GitHub




De tempos eu tive a ideia de criar um script onde eu pudesse procurar de forma automatizada por códigos no Github, confesso que eu vivo perdendo scripts no Gist, plataforma do Github, como eu queria um pouco mais de agilidade na busca de alguns scripts antigos que eu tinha, eu fiz o GitMiner, na primeira versão da tool, eu usei scrapy já que eu estava aprendendo sobre o framework. Nesse tempo eu comecei a aprender um pouco mais sobre termos de pesquisa no próprio Github, isso facilitou para o desenvolvimento do GitMiner 1.2, versão mais nova e pública da tool que ajuda na pesquisa de códigos na plataforma.

Antes de falar da própria ferramenta, vou explicar sobre o Github e sua pesquisa avançada. Durante a semana passada, quando lancei a ferramenta e a ideia sobre pesquisas avançadas no Github, um brother veio me falar sobre um "full disclosure" já lançado em 2013 sobre o Github, nele já apresentavam a mesma ideia que a minha, o link do full disclusure você pode ver no final do artigo.

A Conviso fez um post sobre o full disclusure em 2013, assim que foi lançada a ideia de se usar o Github para pesquisas avançadas de código, o Cooler chegou até a desenvolver uma tool para isso, mas achei ela bem mais simples que a minha.

Voltando na questão da pesquisa avançada, com ela por si só, já podemos nos entreter um pouco. Assim como uma busca avançada no Google, a busca avançada no Github possui alguns operadores lógicos e alguns filtros que facilitam na pesquisa.

Operadores lógicos


O interessante da pesquisa avançada é você conseguir usar operadores lógicos em suas buscas para que ela fique mais precisa, o Github possui 3 operadores que nos ajuda a pesquisar com maior precisão, são eles AND, OR e NOT. São usados para filtrar ou complementar certos tipos de pesquisa, exemplo:

  • Operador "AND"
Usado para dizer a pesquisa que ela deve conter um termo E um outro termo, exemplo:


No caso acima, estou pesquisando dentro de arquivos no Github que contenham a palavra "root" E a palavra "password", ou seja, ele vai me trazer arquivos que contenham as duas palavras dentro do mesmo arquivo.

  • Operador "OR"
OR é como se estivesse praticamente dizendo ao buscador o mesmo que quando usei o AND, porém, eu digo que gostaria de pesquisar pela palavra "root" OU "password", nesse caso ele pode me retornar arquivos que possam conter as duas palavras dentro do mesmo como pode me retornar um arquivo que contenha apenas uma das palavras dentro.



  • Operador "NOT"


NOT serve para NÃO pesquisar determinada palavra, um exemplo de busca seria, eu quero pesquisa dentro de arquivos a palavra "password" mas não quero que contenha a palavra "root" em nenhum arquivo que eu pesquise. Exemplo:


Nesse caso acima, não contem a palavra "root", apenas password.

Isso não é tudo ainda, além de operadores lógicos, nós temos termos de buscas para facilitar ainda mais nossas pesquisas e realizar filtros mais precisos.


Termos de buscas avançadas


O Github nos proporciona alguns termos para pesquisas avançadas, com eles nós conseguimos filtrar ainda mais os resultados de buscas, durante minha pesquisa eu separei apenas alguns termos de busca para uma simples demonstração.


in:file
Pesquisa palavra dentro do arquivo, ex: root in:file , faz a pesquisa da palavra root dentro dos arquivos


path:etc
Pesquisa arquivo no diretório etc, ex: path:etc , pesquisa pastas que tenham o nome de etc


extension:php
Pesquisa por extensão de arquivo, como no exemplo do comando, ele procuraria por arquivos cuja extensão seja php


filename:wp-config root
Pesquisa por arquivos com o nome de wp-config que contenham a palavra root

Já com essa base de termos de buscas avançadas e alguns operadores lógicos, podemos montar querys de pesquisas avançadas e ver o que achamos, como exemplo eu procurei por aquivos de wordpress para ver se continham informações sensíveis.

A pesquisa consiste em procurar dentro de arquivos cujo nome seja "wp-config" a existência da palavra "FTP_HOST". Repare na imagem abaixo.





Assim que fiz a pesquisa, logo o primeiro resultado me trouxe um usuário, uma senha e o host onde ele está armazenado, eu fiz o teste para ver se a senha era válida e veja o que aconteceu:



Para confirmar que estava dentro do servidor FTP eu criei uma pasta chama "teste" e logo em seguida eu apaguei.





Um outro exemplo de uma pesquisa desse modo é a localização de arquivos de configurações de e-mail, veja o que foi encontrado.



Mas para realizar esse tipo de pesquisa e procurar manualmente código por código é um pouco cansativo, foi então que resolvi fazer uma versão atualizada e pública do GitMiner, para facilitar na busca por códigos dentro do Github.

Apesar dessa pesquisa ser "offensive security", vale como forma de conscientização de como desenvolvedores desatentos que usam o Github de forma pública e como isso pode prejudicar não só ele como a empresa na qual ele está postando o source-code.


GitMiner


Enfim a "tal" ferramenta, como já havia dito, ela realiza busca no Github, dessa forma vou pular apresentações e vou demonstrar como ela funciona de fato.

Para quem ainda não conhece, segue o link: [http://github.com/danilovazb/GitMiner]

Realizando Pesquisas:

Para pesquisar de forma normal, sem módulos(vou explicar mais a frente), basta digitar:

~$> python git_miner.py -q 'path:etc filename:shadow'

Ele vai perguntar se você deseja continuar a pesquisa sem um módulo carregado ou abortar a pesquisa, caso deseje continuar basta digitar N para que ele prossiga com a pesquisa.



Caso queira carregar um módulo, basta digitar Y para que cancele a pesquisa.

Se continuar a pesquisa sem um módulo carregado, ele vai trazer apenas o link do código da pesquisa e o nome do usuário.

Antes de mostrar a pesquisa com um módulo carregado, vou mostrar o que é o módulo que estou falando.

Quando fizer um git clone na ferramenta vai notar que há uma pasta chamada "config" e dentro dela tem um arquivo com o nome de "parsers.json", esse é o módulo que falei.

Dentro desse arquivo tem a configuração do que desejo filtrar e buscar com o GitMiner, vou exemplificar usando um módulo que já deixei por padrão no repositório.

A estrutura do json é a seguinte:


Temos o nome do módulo como "wordpress"(É ele que vamos passar como parâmetro pra ferramenta quando formos pesquisar, vou mostrar a frente, guardem esse nome) e alguns parâmetros abaixo, vou explicar um a um.

contains: filtra no código por uma palavra que desejar, mostra no resultado da busca a linha onde ela contém, caso haja mais de uma palavra, ele mostrará as demais linhas onde ela consta.

parameters: são separados por nomes como param1, param2, param3 e etc, nunca podendo repetir o nome da chave, sempre sendo nomes únicos e seguindo a mesma lógica acima, param+numero. Em cada chave dessas é colocado um nome no qual quer filtrar e printar na tela do resultado, como no exemplo acima do wordpress, ele printa a linha onde contem, FTP_USER, FTP_PASS, FTP_HOST e etc, assim como está acima.

splitparam: usado para separar palavras na linha onde contem os param, um exemplo de uso seria, pesquisar por um arquivo CSV onde seja separado por virgula, nesse parâmetro é passada a virgula(,) para que ele possa fazer a separação de palavras pela virgula.
Exemplo, caso meu param1 seja "DB_USER" e ele me retorne a seguinte linha:


define('DB_USER', 'USUARIO');

Eu posso setar o splitparam para separar por '(aspas simples) assim como está no código de exemplo acima.
Sendo assim a linha vai vir da seguinte forma:

['define(', 'DB_USER', ', ', 'USUARIO', ');']

Pra não confundir, coloquei a palavra separada em vermelho, ela vai vir dessa maneira. Podemos também já falar de um parâmetro de configuração que é utilizado em conjunto.

splitorder: serve para separar e trazer apenas o necessário para você, como no exemplo que usei acima da separação, se for ver ele em vetor ele tem 5 partes, começamos a contar a partir da 0, ficando do seguinte modo:

['define(', 'DB_USER', ', ', 'USUARIO', ');']
       0                 1          2             3         4

Sabendo disso, podemos usar o splitorder para trazer apenas o nome do campo e o usuário, assim como está no exemplo do código que dei acima, selecionei apenas o 1 e o 3 para que ele me retorne.

Entendendo como funciona o módulo, agora já podemos fazer uma pesquisa simples usando o módulo wordpress(lembra que pedi para guardar esse nome?) que foi setado no arquivo parsers.json.

$:> python git_miner.py -q 'filename:wp-config extension:php FTP_HOST in:file ' -m wordpress -o result.txt

E ainda no comando acima, adicionamos a opção "-o result.txt" para salvar o resultado em um arquivo de texto. Veja como ficou:



Bom galera, é isso que queria mostrar para vocês, como de costume, a musiquinha inspiradora do post:


[REFERENCIAS]

http://blog.conviso.com.br/github-hacking-for-fun-and-sensitive-data-search/
https://github.com/convisoappsec/research_github_hack
http://seclists.org/fulldisclosure/2013/Jun/15
http://www.hackinsight.org/news,573.html