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 utilizacao e a 5984 sob o protocolo TCP. O daemon responsavel por sua execucao e o "beam", que faz parte do Erlang OTP. Conforme figura abaixo.Por padrao, CouchDB instala todos seus recursos (exemplo: apt-get install couchdb) sem exigir o cadastro de senha para se autenticar em funcoes 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 estao trafegando entre o servidor e o cliente, um exemplo classico, seria capturar o usuario e senha para se autenticar posteriormente, ja que a aplicacao utiliza sistema basico de autenticacao (Basic Authentication), visualizar os nomes das databases, usuarios etc.Acessando os recursos do CouchDB com o cURL. Com o utilitario de linha de comando cURL, podemos realizar basicamente as 4 funcoes 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_dbs2 - Criar um novo database.# curl -X PUT http://192.168.0.64:5984/new_db3 - Criando um documento de design.# curl -X PUT http://192.168.0.64:5984/new_db/_design/app --data-binary @design.json4 - 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/foo6 - Criando um usuario 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 usuarios.# curl http://192.168.0.64:5984/_users/_all_docs8 - Excluindo um database.# curl -X DELETE http://192.168.0.64:5984/new_dbCriando um script para o MetasploitPara facilitar o trabalho durante os testes de intrusao, desenvolvi um script para o metasploit, onde voce conseguira realizar todas as acoes possibilitando a automacao da analise. Seu uso e simples, basta definir o endereco do host remoto (RHOST), o metodo (GET, PUT, POST ou DELETE) e sua acao (TARGETURI). Em seu padrao, o modulo vem configurado para enumerar as databases existentes no servidor a ser testado, bastando apenas, definir o host remoto (RHOST), confirmar se a aplicacao roda na porta padrao (5984) e executar o comando "run".Script couchdb_enum.rbrequire '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 ' ], '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 ==