domingo, 11 de dezembro de 2016

0 ch0r0 3h l1vr3

A pedido de um amigo, segue um texto que fala sobre a "comunidade".

Disclaimer: Tudo que escrevo aqui são opiniões minhas, e não refletem a opinião dos organizadores da H2HC de forma individual ou como organização.

Nos últimos dias acabei por ler um blog post feito pelo Carlos Cabral e outro feito pelo Anchises sobre um incidente ocorrido na H2HC deste ano (2016), onde uma pessoa foi hackeada e aparentemente teve seus dados de celular apagados e suas contas em redes sociais comprometidas. Os posts são antigos (feitos logo depois da H2HC), mas só agora eu vi e fiquei sabendo do ocorrido.

Estes posts tentam relacionar o que acontece na comunidade hacking com a comunidade de segurança no Brasil, coisas que obviamente são completamente distintas. Diferente do que o Anchises pinta sobre como deveria ser uma comunidade, a comunidade hacking tem suas próprias regras no Brasil ou em qualquer parte do mundo, e se você vai a conferencias do tipo esteja preparado para conviver com tais regras.

No geral ambientes do tipo são bastante hostis. Durante o tempo em que convivi em meio a esta comunidade eu já muita confusão acontecer. Das que eu me lembro agora posso citar coisas como:

- Por volta de 1996/97 o pessoal da Axur05 (http://www.bertochi.com.br/zines/axur05/) teve uma treta com a zine Barata Elétrica (ou Merdeval e Bezouro Elétrico como eles chamaram na época - http://barataeletrica.blogspot.com.au/). O motivo seria que a zine do Barata nunca foi técnica, era mais algo jornalístico sobre a comunidade, e a zine da Axur05 era de pwnage de verdade. Os caras liberavam senhas de provedores, códigos pra acessar internet sem pagar e em 1996/97 lançaram um packer pra binários do MS-DOS (eh mano brother, um packer feito por um Brasileiro naquela época - foda!).
- Depois disso tiveram varias zines como a TDK e a F3 (Fatal 3rror), e outras, e sempre rolava treta. Algumas delas fugiram do mundo virtual e terminou em briga de rua (e esses caras hoje achando que o coruja ter apanhado é algo novo).
- Também sei que os caras da Sekure.org (famosos hoje no mercado de segurança - por desenvolver ferramentas e conteúdo de qualidade) tiveram uma confusão com um cara que tinha o nick de psaux (rolando comprometimento de maquina e tudo mais).
- Teve uma galera do Rio que era famosa na época (tinham ganhado o campeonato da Argus Putbull usando 0day e tudo mais) que também tiveram confusão do tipo. Os caras tiveram seus servidores comprometidos, e acabaram comprometendo o outro cara de uma forma muito inusitada (usando uma backdoor que tinha no client do rootkit do cara).
- Entre 2000-2002 o FISL no sul também foi recheado de confusão deste tipo (com pwnage), com várias máquinas de profissionais de renome da área de segurança sendo comprometidas.
- A Brasnet era um paraíso de tretas do tipo. Quem aí desta época não se lembra das guerras de IRC pra dar takeover em canal? Na época vários servidores da Brasnet foram comprometidos onde instalaram interessantes backdoors. Era possível entrar invisível em canal, e inclusive sniffar conversas individuais.
- Dessa mesma época da Brasnet, quem não se lembra do Movimento Só Tem Hax0r (http://www.geocities.ws/sohtemhaxor/)?
- Ainda nessa mesma época, varias tretas na lista da Unsekurity. É interessante notar que varias dessas pessoas hoje são profissionais de renome e contribuem muito para a tal comunidade de segurança.
- Depois disso veio o tempo da Front The Scene / Clube dos Mercenarios e Motd. Listas distintas recheadas de confusão e pwnage de maquinas (me lembro que o Server da motd foi comprometido e deram disclosure). Me lembro que eu e um amigo de São Paulo (estado) cuidávamos dos servidores da FTS e CdM, e por causa de uma confusão dessas eu tive que viajar 1000km pra ajudar a analisar nosso server pois não tínhamos certeza se tínhamos sido comprometidos ou não (nossa conclusão na época foi de que não, mas houveram vários ataques).
- Depois disso veio a H2HC (2004) com tretas constantes. Pra vc ter uma ideia, na primeira H2HC rolou até spray de pimenta no hotel.
- Dai vieram os project mayhem internacional (sim, isso começou lá fora - na comunidade hacking internacional) e depois o nacional, onde o objetivo dos caras eram pwnar profissionais de destaque da área de segurança. E falando em comunidade internacional, quem não se lembra da GOBBLES? Vcs se lembram onde era hospedado o site dos caras? Era sub-dir do site de uma empresa muito famosa onde os caras atualmente contribuem (e sempre contribuíram) muito com a comunidade (varias tools, debuggers, etc).
- E mais recentemente veio a lista Brasil Underground com as tretas com o coruja e luiz vieira, fora outras.

Muitos destes acontecimentos eu vi de perto, outros fiquei sabendo por meio dos envolvidos. Portanto, querer dizer que viver em comunidade "significa saber respeitar o próximo e as diferenças entre todos, e estar disposto a acolher e ajudar a todos" é um erro. Cada comunidade escolhe suas regras, e as do meio hacking são bem hostis. Dizer que esse tipo de coisa é novo é ignorar ou desconhecer o passado. Isso sempre aconteceu no meio hacking, SEMPRE, e não vai deixar de acontecer NUNCA, pois o problema(?) está no tipo de pessoas que esta comunidade atrai. Briga de egos tem aos montes, tretas infinitas, mas também tem amizade verdadeira e muita troca de informação (muita mesmo).

Outro ponto discutido nos posts feitos pelo Cabral e Anchises é dizer que pessoas envolvidas neste tipo de confusão não contribuem para a comunidade. Como não contribuem se vcs nem sabem quem são? Vários envolvidos nas tretas que citei acima eu conheço pessoalmente de longa data, e posso garantir que são bastante ativos na comunidade (hacking e) de segurança, produzindo artigos de qualidade e ferramentas que vcs, profissionais de segurança, usam.

Dizer que esta característica da comunidade hacking afasta os novatos é desconhecer como as coisas funcionam. Hostilidade atrai ainda mais esse tipo de pessoa, pois o que eles mais gostam é de quebrar paradigmas, é de provar que o outro está errado. Se vc fala pra esse tipo de pessoa que uma exploração não é trivial achando que ele vai desistir, está completamente enganado. Este tipo de informação é muito mais um atrativo do que um incentivo à desistência. Dai só porque a ISS (X-Force) fala que a exploração de um of-by-one no bind 8 (frame pointer overflow) não é trivial, o cara vai lá e lança o primeiro exploit que explora esta técnica, primeiro exploit que faz connect-back e ainda me mete uma backdoor no shellcode. É desse tipo de gente que estamos falando aqui.

Vcs dizerem que os novatos não estão contribuindo é outro erro, posso citar vários aqui que surgiram na comunidade nos últimos 5 anos e já tem contribuído bastante com artigos, tools, palestras ou mesmo com um papo de boteco.

O texto do Cabral vai alem e critica o pessoal que vai nessas conferencias e "fica no bar" ao invés de assistir as apresentações, fazendo crer que assistir apresentações é a mesma coisa que aprender a técnica em questão. A maioria das palestras da H2HC (conferencia em questão nos dois posts) são altamente técnicas e muitas vezes requerem um pesado conhecimento prévio apenas para compreender o conteúdo apresentado. Outro ponto é que estudar != assistir uma apresentação/entender determinado conteúdo. Estudar tem muito mais haver com sentar a bunda na cadeira, ler, consultar referencias, replicar os testes, modificar as provas de conceito do que apenas assistir uma apresentação.

Pra mim a melhor coisa dessas conferencias é rever os amigos, bater papo sobre nossas pesquisas e a pesquisa dos amigos do que ficar assistindo apresentações. Até hoje só faltei 1 H2HC e sempre fui da "galera do buteco". Se assisti 5 apresentações no total foi muito. As vezes que me interessei pelo assunto de alguma palestra, peguei o material depois e estudei, ou mesmo fui até o palestrante (que estava bebendo umas no bar) e perguntei sobre minhas dúvidas. Mesmo minhas perguntas sendo humildes, nunca recebi uma patada como o Cabral disse. TODAS as vezes o cara teve paciência de explicar, e muitas vezes eles compartilharam códigos pessoais (não públicos) com o único objetivo de me ajudar. Pra mim o importante dessas conferencias é justamente criar a atmosfera propícia para este tipo de interação. E em conferencias como H2HC ou Null Byte é muito mais legal que uma Defcon, pois são menores o que facilita o acesso a essas pessoas.

Como reflexão final, acredito que no Brasil temos eventos de segurança e eventos de hacking. Não vá achando que uma H2HC ou Null Byte (nem estou citando a Alligator) tem a mesma pegada que o Roadsec. O Roadsec e a Silver Bullet/YSTS são eventos de segurança, feito por profissionais de segurança para o mercado de segurança. Eventos como H2HC, Null Byte, Ekoparty, Infiltrate e Defcon são conferencias de hacking e muito hostis por natureza. É um lugar que vc deve ir preparado e tomar cuidado com seu comportamento durante todo o evento, senão vc pode ser pwnado. É um lugar que vc não vai faltar com o respeito com a metade da conferencia (como disseram que aconteceu), usar a wifi publica e ainda assim achar que vai sair ileso. É um lugar que vc só vai fazer deauth nos participantes do CTF se for no melhor estilo Mr. Robot (não ser pego), do contrário esteja preparado para as devidas consequências.

Não se trata só de não acessar a wifi do evento, mas sim de desligar a wifi do seu celular e ficar atento com possíveis equipamentos estranhos no evento (me lembro que teve uma Defcon que os caras meteram um ATM falso dentro de um hotel cassino, pwnaram muita gente e depois publicaram as infos).

Os posts do Cabral e Anchises são estes aqui:


Just my 2 cents.

dmr.

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

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.