sexta-feira, 1 de abril de 2016

Usando o embedded comemorativo da #H2HC para montar um rubberduck

Nossa, desculpe o título longo, mas não achei nada que pudesse resumir rsrs
Galera, vamos lá, para quem foi na Hackers to Hackers Conference(H2HC) do ano passado pode ter recebido uma placa(embedded) comemorativa igual a esta:


Essa plaquinha vem com um chip Atmel 32u4, o mesmo usado no arduino leonardo, o legal dela é que esse chip tem uma interface HID(Human interface device), (obrigado @Rogy153 por me ensinar sobre) com esse recurso conseguimos emular um teclado ou até mesmo um mouse no computador, dessa forma conseguimos montar um "payload" capaz de executar comandos de forma automática em sistemas, montando assim um vetor para um ataque ou até montar um brute-force.

Como exemplo vou utilizar ela para criar um payload que abre o terminal no meu linux e digita comandos para a abertura de outro programa, mas no caso eu poderia usar para outros fins, tanto no Mac quanto no windows também!

Vamos lá?

Primeiro, baixe o interpretador do arduino, nesse caso não vou mostrar como funciona a instalação, vou pular para a configuração da placa na IDE do arduino e o código.

Abra a interface da IDE do arduino e clique em Tools>Board>Arduino Leonardo



Dessa forma ele vai configurar para enviar o código para o chip Atmel 32u4 usado no arduino leonardo.

Feito isso e tando com a placa conectada ao seu computador, podemos usar o código abaixo:



Interessante é que podemos fazer códigos para abrir terminais e realizar conexões remotas via netcat, vai da sua imaginação.

Segue um pequeno vídeo que fiz com o código acima e o embedded da H2HC.





Caso queira saber mais sobre como montar sua payload, pode consultar direto no site do arduino pelos comando: https://www.arduino.cc/en/Reference/MouseKeyboard

Lembrando, apenas chips com interface HID tem esse resultado, consulte o site da Atmel antes.


Como de costume, aquele som ao fazer o vídeo.

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

domingo, 21 de fevereiro de 2016

Utilizando argumentos no framework scrapy e usando tesseract com python

Olá meninos e meninas, hoje vou mostrar um pouco do framework scrapy, eu tenho desenvolvido um crawler para um amigo (Balestra, to terminando hehehe) e cada vez mais tenho usado o scrapy para poupar tempo no desenvolvimento de crawlers, pela facilidade de interação e de escrita de código.

Hoje eu vou compartilhar com vocês algo que achei interessante durante o desenvolvimento do crawler que tenho estudado, é a passagem de parâmetros que achei bem simples e uma questão nova que tenho visto que é a utilização do tesseract com python para processar textos de imagens.

Primeiro, vamos iniciar um projeto no scrapy(Caso não saiba como, leia esse artigo).

Eu iniciei da seguinte forma:

(sim, vou sacanear e colocar os comandos em imagens, quanto mais você digitar mais você aprende)


De acordo com os comandos da imagens, eu startei o projeto e criei um spider da olx, agora vamos começar o coding do spider.

Como disse em outro post, a estrutura de arquivos é a seguinte:

#:> tree olx_crawl/
olx_crawl/
├── olx_crawl
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   ├── settings.pyc
│   └── spiders
│       ├── __init__.py
│       ├── __init__.pyc
│       └── olx_spider.py
└── scrapy.cfg

Vamos editar o arquivo "olx_spider.py" que fica dentro da pasta spiders, como pode ver na árvore de diretório acima.

Inicialmente ele vem nessa estrutura:


Certo, nesse caso eu quero demonstrar para vocês como usar argumentos no scrapy, vamos modificar o arquivo padrão para que ele aceite argumentos passados na hora de realizar o crawler, primeiro eu entrei no site da OLX e fiz uma pesquisa qualquer na sessão de carros para ver como ele interpretava minha consulta, percebi que ele passa a query por GET da seguinte forma http://sp.olx.com.br/veiculos/carros?q=%22Golf+GTI%22 , onde "?q=" é a variável da pesquisa e o %22Golf+GTI%22 é o parâmetro que queremos pesquisar.

Desse modo vou editar o arquivo padrão e incluir um método __init__ para receber os parâmetros de pesquisa, ficando da seguinte forma:


Agora vamos fazer o teste?

Se ficar pequena a imagem, clique nela para expandir.
Podemos ver na imagem como foi feio o teste passando o parâmetro depois de ter editado o código, repare no comando:


Eu fiz uma pesquisa pelo termo exato(adicionando aspas duplas ele pesquisa pelas palavras exatas no titulo do anúncio, pode ver mais search tips aqui http://www.olx.com.br/search_tips.htm) de Golf GTI, por isso a pesquisa com aspas simples e aspas duplas.
Voltando ao comando, para utilizar o parâmetro basta colocar "-a" e o termo que vai pesquisar que foi inserido no código, pode ver na linha 8 do código, eu atribui a variável como "pesquisa", mas poderia ter colocado a variável como "piricutisco" e usado da seguinte forma:
 
#:> scrapy crawl olx_spider -a piricutisco='"Golf GTI"'

Sacaram? 

- Poxa mano, mas e se minha pesquisa tiver N argumentos?
R: Poderá fazer desse modo:


#:> scrapy crawl olx_spider -a piricutisco='"Golf GTI"' -a Goku="majin boo"

Note que cada vez que adiciona um parâmetro a chamada(-a) do parâmetro tem que ser usada.(Exemplo acima é meramente ilustrativo, ele não funciona na pagina da OLX)

E podemos verificar que o parâmetro foi passado corretamente no LOG, reparem na imagem abaixo:



Certo, voltando ao código original que estávamos desenvolvendo, vamos começar a implementar a inteligência do robô, nesse exemplo, como quero demonstrar o uso também do tesseract, vamos fazer o download e a salvar o telefone de contato do anunciante, caso não tenham reparado, o telefone tem duas proteções contra crawlers:

  1. Ele está atrás de um javascript.
  2. O texto do telefone está como imagem, para evitar o salvamento automático do telefone ou sei lá o que.

Mas, como somos trakinas, vamos realizar um bypass.

Primeiro, vamos entender a pagina onde vamos realizar o parser. Assim que realizamos a pesquisa ele nos leva para a pagina onde ficam os resultados, nosso robô tem que entrar em anuncio por anuncio e passar a pagina e assim por diante até acabar os resultados.

Vou usar como referência o artigo do Gileno[1] para realizar o parser das paginas da OLX, mas para entender melhor e não ter que ficar pulando de artigo p/ artigo, vou explicar como realizar o parser aqui.

Abrindo a pagina de pesquisa (estou usando o chrome), eu abri a ferramenta de desenvolvedor do chrome para analisar o código fonte, como na imagem abaixo eu procuro a tag html responsável pela lista de carros, observe:

Se ficar pequena a imagem, clique nela para expandir.
No caso da OLX a tag que eu procurava é a div class="section_OLXad-list " que contém a listagem dos carros, agora vamos pegar a tag li class="item" que contém o anuncio do carro, dessa forma vamos montar uma consulta de xpath para adicionar no código do crawler pra quele possa realizar o parser.

//div[contains(@class,"section_OLXad-list")]//li[contains(@class,"item")]

Acho que o entendimento é bem simples, mas vou tentar explicar da forma que aprendi, caso esteja errado, por favor me corrijam.

Antes, vou explicar sobre os operadores // e / do xpath, eles são utilizados para definir a pesquisa dentro do texto HTML.

/div - usado para fazer a pesquisa da tag div dentro da raiz do html, caso não tenha entendido a questão da raiz, ela funciona da seguinte forma, o html ele tem uma estrutura, assim como uma estrutura de diretórios ou a indentação de um código, o xpath ele faz essa distinção, quando usamos apenas uma barra ele faz a procura penas no "diretório" raiz do HTML.

//div - usado para fazer a pesquisa da tag div em todo o código HTML, seguindo o exemplo acima, seria como pesquisa de forma recursiva dentro de todos os diretórios, trazendo tudo que ele encontrar com a tag div.

Ok, entendido isso, acho que fica mais fácil explicar o xpath acima, ele procura em todo o código pela tag div que contenha o parâmetro class que seja igual a "section_OLXad-list" e assim que ele achar, ele pesquisa dentro de todos esses "divs" encontrados a tag li que contenha a classe "item".

Não sei se consegui ser claro, mas qualquer dúvida que fique, postem nos comentários que vou tentar responder o quanto antes.

Vamos montar o código agora no nosso spider, apenas seguindo o que o Gileno fez, segue o código abaixo com parte do que o Gileno desenvolveu no artigo dele, a princípio esse código servirá como base para coletarmos o telefone e alguns dados a mais.

Caso queira entender como foi realizado as outras linhas de código, visite o artigo do Gileno.


Certo, agora vamos para a parte que interessa, vou mostrar como usar o tesseract junto com o python, fazendo ele reconhecer a imagem a partir da pagina web.

No site da OLX, na pagina do anuncio, podemos ver que tem um telefone de contato como mostra na imagem abaixo:


O telefone está "protegido" por um javascript, dificultando a ação de crawlers, porém ele foi mal implementado, podemos notar no código fonte da pagina que a imagem original do telefone se encontra dentro das tags noscript, veja na imagem abaixo:


Repare que dentro da tag noscript tem a imagem original dentro da tag img, nesse caso eu implementei da seguinte forma o código para a leitura da imagem:


Dessa forma eu extraio o link da imagem original, assim consigo acessar a imagem com o telefone e usar o tesseract para transformar a imagem em texto, pode observar no código abaixo que fiz alguns imports novos e add mais 7 linhas no final do código.


Agora, vamos rodar o código para ver se está tudo OK.



Ao som de Astrix:


REFERÊNCIAS:
[1] http://www.gilenofilho.com.br/usando-o-scrapy-e-o-rethinkdb-para-capturar-e-armazenar-dados-imobiliarios-parte-i/
[2] Livro Web Scraping com Python - Capítulo 11 - Processamento de imagens e reconhecimento de texto - Pag 207
[3] https://pypi.python.org/pypi/pytesseract

quarta-feira, 6 de janeiro de 2016

HTTP Dangerous Method - Automatizando exploração com Python

E ai galera, depois de muito rivotril, reconter e pristiq, to de volta no role kkkkk

Bom, o motivo de postar hoje é uma vul que peguei em um cliente hoje.
O titulo já diz o nome da vul, pelo menos é o que o Nessus me trouxe como nome dela, eu achei interessante a falha pq sinceramente, nunca peguei essa falha realmente vul a não ser em LAB, ai como peguei ela hoje eu resolvi escrever um pouco sobre ela.

O que acontece é que está habilitado no servidor web os métodos PUT e DELETE, pra quem não conhece, vou explicar melhor.

PUT:
O método PUT faz uma requisição no servidor web que realiza uma criação de um arquivo remoto, caso já exista, ele é modificado.

DELETE:
Delete o recurso solicitado.

OPTIONS:
Retorna os métodos HTTP que o servidor suporta para a URL especificada.

Bom, sabendo sobre esses 3 métodos já da pra entender como funciona a falha, de grosso modo, eu faço uma requisição OPTIONS e vejo o que está habilitado no servidor como na imagem abaixo:


O que eu fiz ai foi, usar o netcat pra mandar uma solicitação de OPTIONS e ver o que está permitido(Allow) no meu server, veja que no meu apache está apenas OPTIONS, GET, HEAD e POST.

No caso do cliente, estava habilitado o método PUT e DELETE, permitindo eu inserir um arquivo e deletar.

Então eu procurei alguns artigos que mostravam como fazia manualmente o insert, no final do artigo eu vou colocar as fontes de pesquisa que me ajudaram na falha.

Mas por preguiça de fazer manual nos servers que encontrei a falha eu fiz um script que facilita a minha vida, vou postar ele aqui em baixo:



No script, é preciso criar um arquivo vul.htm antes, assim ele faz o upload, mas se quiser, pode melhorar o script, ele é livre.

Bom, basicamente é isso galera, uma outra dica, tem um comando no nmap que ajuda da identificação dessa falha:

nmap --script=http-methods.nse --script-args http-methods.retest=1 127.0.0.1

Obvio, troque o ip de loopback para o ip ou o range que vai testar.
Em um pentest isso pode ser crucial para conseguir uma vul.

É isso galera, tks....e estou de volta no role ;)

[Referencias]
http://pt.stackoverflow.com/questions/9419/quais-s%C3%A3o-os-m%C3%A9todos-de-requisi%C3%A7%C3%A3o-http-e-qual-%C3%A9-a-diferen%C3%A7a-entre-eles
https://tools.ietf.org/html/rfc7231
https://www.owasp.org/index.php/Test_HTTP_Methods_(OTG-CONFIG-006)
http://httpsecure.org/?works=how-to-exploit-http-methods-put-and-delete

quarta-feira, 2 de dezembro de 2015

Gerando wordlist de username com python e scrapy

Fala galera suave?
Faz um tempo que não posto nada não é verdade?

Bom, agora estou de "férias"(sem trampo rsrsrs) e vou tentar me dedicar mais ao blog, pra falar a verdade, tenho 2 artigos para finalizar, a preguiça e o Elder Scrolls não estão deixando kkkk

Um deles eu quero passar o básico para se examinar um aplicativo mobile, desde o tráfego de dados até o source code, com foco em apk(Android), algo bem howto mesmo, eu penei um pouco pra achar bons tutos que explicam desde o decompilar até o recompilar com assinatura e tal, enfim.
Outro que quero mostrar é algo que estou criando com o scrapy, mesmo framework que vou demonstrar nesse artigo, enfim, vamos ao que interessa certo?

Agora na madruga eu estava fazendo um pentest e precisava de nomes de usuários para fazer uma wordlist para enumerar um ssh, porém, queria nomes de pessoas do BR, a solução que achei foi procurar no google por nomes de pessoas brasileiras, então eu achei esse site: http://www.dicionariodenomesproprios.com.br/

Certo, nele existe uma lista com nomes masculinos e nomes femininos, o que vou mostrar é como automatizar isso para que se pegue todos os nomes do site de forma rápida e fácil.

Primeiro, caso não tenha instalado o python e/ou scrapy, leia sobre aqui.

Caso já tenha instalado, prosseguiremos. (Obs: não pretendo explicar o que cada comando faz nesse tutorial, estou preparando outro para isso, no final do artigo vou colocar uns posts que me ajudaram a aprender sobre o scrapy caso alguém queira)

Em seu terminal, digite:

~$ scrapy startproject nomes_galera

Será criada uma pasta com o nome de "nomes_galera", agora digite a sequencia de comandos abaixo:

~$ cd nomes_galera
~$ scrapy genspider masc_nome dicionariodenomesproprios.com.br

Vejamos, você criou o projeto dando um start nele e atribuindo o nome "nomes_galera", em seguida você entrou na pasta e criou um robo(spider) que vai coletar os dados a partir do domínio dicionariodenomesproprios.com.br com o nome do robo(spider) de masc_nome.

Certo, espero que até aqui você tenha entendido, caso não, ligue 190 e peça ajuda aos universitários rsrsrs briks, qualquer coisa deixa nos comentários que eu ajudo galera.

Vamos entrar na pasta onde se encontra o spider, antes de entrar, segue a árvore do diretório só para terem uma noção.

#:> tree
.
├── nome_galera
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   ├── settings.pyc
│   └── spiders
│       ├── __init__.py
│       ├── __init__.pyc
│       ├── masc_nome.py
│       └── masc_nome.pyc
└── scrapy.cfg

Entre na pasta spiders com o comando abaixo:

~$ cd nome_galera/spiders/

Vamos editar o arquivo que acabamos de criar, no caso, o robo com o nome de masc_nome.py

A princípio o arquivo é criado com um layout padrão, dessa maneira:


Note que na linha 9 ele mostra apenas o site certo? Não é isso que queremos, vamos analisar o site e ver onde estão os nomes masculinos.

Se você entrar nesse link: http://www.dicionariodenomesproprios.com.br/nomes-masculinos/
Vai ver que tem apenas nomes masculinos certo? Nosso desafio é pegar todos esses nomes e de todas as paginas. (Desculpem se não estiver sendo bem claro, estou com um pouco de sono)

Pra fazer isso, vamos olhar o código fonte da pagina.
Abaixo do Top10 de nomes, veja que começa a lista de nomes do site, em desordem alfabética(acho que inventei esse termo agora) o primeiro nome que aparece é o Davi, usando o chrome, abra a ferramenta de desenvolvedor e inspecione o objeto com o nome do Davi assim como na imagem abaixo:



Vejam a tag e o atributo do HTML onde tem o nome do davi, viu?

Ok, vou colocar aqui.

Repare, temos a tag "a" com o atributo 'class="lista-nome"', se você der um procurar na pagina, você vai ver que todos os nomes listados tem a tag e o atributo em comum, se pensarmos de maneira lógica, temos uma lista de nomes(Dãhr, o próprio nome da class já diz animal). Piadinhas a parte, muitas vezes, por mais obvia que é a questão, deixamos passar na hora de desenvolver, pensamos de forma automática e não reparamos em coisas obvias que nos ajudam a montar mentalmente o código.

Ok, let's go.

Vamos ao código agora.

Leia o código, não continue a ler esse texto, vamos fazer um teste de observação.

Diga mentalmente qual é a URL que o robô vai dar o start na busca.

.
.
.
.
.
.
.
.

Achou?
Certo, muito bom garoto(a), linha 8 do código ali de cima, certo? Que por sua vez, é o código base do robo, agora vamos mudar isso, afinal, começamos a procurar do link que passei sobre nomes masculinos não é mesmo? Ainda lembra dele? Pega ele ali em cima vai, não vou escrever de novo.

Altere a linha 9 com o link da pagina onde contem os nomes masculinos.

ficando dessa maneira:



Agora vamos a parte que interessa, vamos ao parser do "bagulho", vamos coletar os nomes.
Primeiro, vamos entender um pouco o que vamos fazer, lembra-se da tag onde contem o nome do Davi? Vamos fazer ela de base para pegar todos os nomes, vamos usar xpath para gerar uma query generica.

Vou postar o código aqui já pronto e vou explicar as linhas alteradas no próprio source "serto" galera?
[ATUALIZACAO] Galera, recebi uma dica do Lynneker Sales Santos sobre o fechamento do arquivo, eu estava abrindo e fechando no for, eu troquei isso. Vlw mano





Agora é só fazer isso para a pagina de nomes de mulheres e pronto, faça isso você mesmo para ver se entendeu, qualquer dúvida, postem aqui nos comentários que ajudo.

Aqui vai uns posts que me ajudaram com scrapy e que me tiram dúvidas até hoje.

http://www.gilenofilho.com.br/usando-o-scrapy-e-o-rethinkdb-para-capturar-e-armazenar-dados-imobiliarios-parte-i/

http://www.gilenofilho.com.br/usando-o-scrapy-e-o-rethinkdb-para-capturar-e-armazenar-dados-imobiliarios-parte-ii/


Post a base de CBJR

quinta-feira, 24 de setembro de 2015

Curso "Hacker" e a moda de "Security Learning"

Bom, com sentimento que nem eu mesmo sei explicar, vou redigir esse post.
Quero ressaltar que não estou dando indireta ou direta a ninguém, todos meus amigos sabem bem da minha opinião e sabem o quanto gosto deles, independente se eles se sintam ofendidos com o post ou não, quero que cada um vá tomar no meio do CÚ caso fique putinho, pois gosto mesmo de todos meus amigos, indiferente do que fazem.

Vamos lá, recentemente eu percebi a crescente procura por cursos de "hacker", vejo que muita "molecadinha" tem procurado diversas escolas para aprender sobre como ser hacker. Percebi que o aumento de escolas "especializadas" em cursos de segurança também tem crescido.

Porém, o que muitos não sabem e não pesquisam é, essas escolas e cursos estão de GRAÇA na internet, muitas dessas escolas VOMITAM um conteúdo que em muitas vezes está errado para seus alunos e lucram por algo que lhes rendeu 1 dia de pesquisa no google.

Cara, só no meu facebook, vejo diversas escolas propondo ensinamentos de como hackear as coisas, como ser um hacker ético ou qualquer um dos títulos sensacionalistas para lucrar, apenas isso, lucrar. Não estou dizendo que elas não ensinam, que não tem um conteúdo bom, alias, muito conteúdo dessas escolas eu não sei nem o que é, o que digo e fico indignado é a similaridade entre os cursos, antes que me perguntem, não, eu não fiz nenhum curso, tenho alguns amigos que me passam o conteúdo de aulas e faço a comparação entre elas e vejo que em 80%  dos casos, nem o texto muda.

Eu acho engraçado, eu sou a "new school", tenho apenas 23 anos, mas eu tive que correr atrás de cada conhecimento, tive que estudar dia e noite para aprender o básico do básico em um tempo onde meu pai não tinha dinheiro para me comprar um livro, apesar dele ter sido programador, ele foi demitido e nunca mais voltou para a área e minha mãe trabalhava como diarista, ou seja, passei madrugadas de domingo (onde o pulso do telefone era mais barato) baixando conteúdos em paginas como barata elétrica, cogumelo binário, fóruns, IRC a fim de tentar aprender algo, isso quando eu não estava chorando pro meu pai me trazer as revista da "CD-ROM" (rsrsrs). Ah saudade dos velhos tempos...

Hoje, com tanto conteúdo sendo produzido, com tantos meios de comunicação, será mesmo que é necessário pagar 'R$1000,00' em um curso onde o conteúdo é vomitado? Ou a geração de agora gosta de pular o processo da aprendizagem real e partir logo pro "taca-le pau nesse carrinho"?

O que quero dizer com isso, eu vejo instrutores montados no EGO, onde cada aula é uma oportunidade de vender a si mesmo se auto-afirmando "hacker" para ganhar mais alunos, OK OK, o marketing é vantajoso para os negócios. PORRA! Cade o verdadeiro espírito hacker, onde você passa horas na frente do computador lendo e-zines, lendo artigos, produzindo de fato conteúdo, aprendendo mais sobre linguagens de computador, adquirindo formas diversas de conteúdos que agreguem.

Infelizmente, é mais fácil pagar por um curso vomitado com um título sensacionalista que ensina a usar meia duzia de programas sem ao menos explicar o que se passa por trás de cada um do que focar em estudar do zero. Entendo, maldita geração fast-food!

Enfim, não quero criar guerra com quem ensina, com quem tem empresa de "security learning", mas porra, procura pelo menos ensinar direito, procura não querer usar um título sensacionalista só para faturar uma "graninha" em cima de quem quer aprender algo.

Como havia dito, muita das coisas que ensinam nesses "cursos" eu não sei, meu foco HOJE é estudar outra coisa, diferente de segurança da informação, mas isso não quer dizer que o tesão por aprender tenha deixado de queimar em meu peito, peço que essa "molecada" não seja apressada, procure aprender o básico antes de sair por ai "hackeando" a wifi alheia.

Deixo esse pequeno desabafo, esse pequeno texto, escrito sobe efeito de álcool e sono.

Quero deixar também, um conteúdo para que aqueles que querem aprender, vejam como é achar conteúdo BOM na internet e de graça. Antes, vejam esse hangout: https://www.youtube.com/watch?v=HjqjXw9EQFc

Agora, vejam esse site: http://www.securitytube.net/

Aprendam a filtrar conteúdos!!!


A tempos, atualização....vindo do brother Mercês:

[atualização] Para quem não entendeu, isso aqui em baixo é uma brincadeira, OK?!?!?!

 Por mim postava o nome das empresas e dos instrutores cuzões! Tenho algumas máximas sobre:

- quem sabe fazer faz, quem não sabe, ensina.
- vc só é um hacker se um outro o diz. E isso n eh importante, anyway.
- n dá pra aprender a ser algo. Ou é ou não é. E se nao eh, nunca serão, 02!
- vai tomar no cu todos os hackers o/
- qq curso com a palavra hacking é lixo
- qq hacker com a palavra hacker nao eh hacker
- 7% dos hacker dividido por 7% dos hacker nao da 7 hacker
- mae hacker com pai cracker da filho haxor
- pai haxor com filha hacker da 7 cracker
- amem

sábado, 18 de julho de 2015

Burlando captcha para manipular votações públicas

De boas galera?
A uns dias atrás, antes do amoço eu achei um concurso e pensei: será que é possível manipular a votação e alterar o resultado final?

A uns meses atrás, eu de brincadeira fiz um robô para votar em bandas na Lollapalooza (http://www.t4f.com.br/app/lollapalooza/escolha-lollabr2016-1/) e selecionei umas bandas nada a ver com a escolha popular para ver se dá resultado.
Como foi essa história?
O site do Lolla guardava o cookie não deixando mais votar, permitindo apenas 1 único voto, então eu escrevi um script em python usando o requests que não guardava o cookie, assim eu consegui manipular os votos, infelizmente não tinha como saber quais eram as bandas mais votadas, mas se tiver natiruts ano que vem já saberemos :)

Enfim, voltando ao concurso.
Eu comecei a brincar com o robô antes do almoço, dei uma pequena pausa para comer e voltei a brincadeira, eu fiz o robô que realiza o voto na modelo indicada (identificada por um ID) em um json.

Vou tentar explicar como eu descobri os parâmetros certos e como realizei a votação, nessa altura do campeonato, provável que ela já esteja eleita, pois só vou liberar esse post após o final do sorteio, então, como estou escrevendo antes de terminar, não sei se ela realmente vai ganhar ainda, posto um EDIT depois dizendo se ela levou o premio ou não.

[EDIT] A mina não ganhou, o robô deu um "gás" na frente da outra mas eu tinha desligado o robô uns dias antes de finalizar, liguei no ultimo dia mas não deu pra fazer a mina ganhar :( [/EDIT]

Sem mais delongas, vamos ao que interessa.

O sorteio é da "Belas da Torcida", nele modelos competem para ver quem é a mais bela da torcida. Beleza, a votação em si, é feita através de um GET em um arquivo que retorna um JSON. Abrindo a pagina de votação:

Coloquei a tarja para preservar as modelos e para não receber processo pq sou pobre
Abrindo o "ferramentas de desenvolvedor" do chrome e fazendo a votação normal, conseguimos saber o endereço que ele realiza o get e como ele faz, como podemos ver na imagem abaixo:



Maravilha, olhem ali ao lado (img abaixo)


Podemos observar que temos 4 requests em paginas iniciando com "vote?jsonp=PollVote&format", essas são as pagina que ele realiza a consulta, as duas primeiras ele me retorna o seguinte json:

GET
http://enquete.xxx.com.br:443/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO

JSONP
PollVote(
)

Beleza, sei que naquele link acima se eu fizer um get ele me retornar um jsonp com os dados do ID e a imagem do CAPTCHA, agora vamos ver o que ele me traz quando eu consulto o outro GET, os dois ultimos que iniciam com "vote?jsonp=PollVote&format"

GET
http://enquete.xxx.com.br/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO&captcha-value=e3z4&captcha-id=nB9gd3ZLsJR-UlO.uDHxtwM6ipzCKAbfGkj28qWQINXrVFcm0TyaPehE4Y57oSv1ALnaixnhp2przWsTC6n0l6kmpg34O6wc-gd0-2dyOH4TlgucU2UaO2sTlxU=

Note que nesse link acima, já temos uns valores interessantes, vou marcar abaixo os interessantes em vermelho:
http://enquete.xxx.com.br/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO&captcha-value=e3z4&captcha-id=nB9gd3ZLsJR-UlO.uDHxtwM6ipzCKAbfGkj28qWQINXrVFcm0TyaPehE4Y57oSv1ALnaixnhp2przWsTC6n0l6kmpg34O6wc-gd0-2dyOH4TlgucU2UaO2sTlxU=

Certo, captcha-value contem o texto do captcha e o captcha-id contem o ID que vimos ali em cima no primeiro get que fizemos.

Agora vem a parte interessante, como faço para burlar esse captcha e manipular as votações com robôs de automatização?

Beleza, nada de OCR, IMAGEMAGIK e a caralhada toda pra complicar, vamos buscar algo mais simples e efetivo que não nos tome tempo. Conheçam o DEATH BY CAPTCHA, maravilhoso site que explora o trabalho de indianos na resolução dos nossos captchas de cada dia, o terror de sites como a Receita Federal, Sefaz e por ai vai hu3hu3hu3BR. O melhor de tudo, é MUITO barato, resolução de 5000 captcha sai em torno de 6.29 obamas, coisa chique.

Certo, como já tenho os dados que preciso, agora é hora de integrar o sistema de votação e no de quebra de captcha, fazendo eles trabalharem juntos :)

Usaremos o Python, mas da pra ser feito em varias outras linguagens.