tko-subs
Esta ferramenta permite:
-
Verificar se um subdomínio pode ser assumido porque tem:
- um CNAME pendente apontando para um provedor CMS (Heroku, Github, Shopify, Amazon S3, Amazon CloudFront, etc.) que pode ser assumido.
- um CNAME pendente apontando para um nome de domínio inexistente
- um ou mais registos NS errados/com erros de digitação apontando para um servidor de nomes que pode ser assumido por um atacante para ganhar controle dos registos DNS do subdomínio
-
Para realmente assumir esses subdomínios fornecendo uma flag -takeover. Atualmente, a assunção é suportada apenas para Github Pages e Heroku Apps e, por padrão, a funcionalidade de assunção está desativada.
-
Para especificar seus próprios provedores CMS e verificá-los através do arquivo providers-data.csv. Nesse arquivo, você mencionaria o nome do CMS, seu valor CNAME, a string que deseja procurar e se funciona apenas via HTTP ou não. Confira alguns exemplos.
Aviso: NÃO SEJA UM IDIOTA!
Desnecessário dizer, por favor use esta ferramenta com muito cuidado. Os autores não serão responsáveis por quaisquer consequências.
Por padrão, esta ferramenta não permite a assunção de subdomínios. Se quiser fazê-lo, basta especificar a flag -takeover.
Pré-requisitos
Precisamos do GO instalado. Depois de ter o GO, digite go get github.com/anshumanbh/tko-subs para baixar a ferramenta.
Depois de baixar a ferramenta, digite tko-subs -h.
O próximo passo é obter as seguintes informações:
- Token de Acesso Pessoal do Github - Certifique-se de que este token tem permissão para criar repositórios, referências, conteúdos, etc. Você pode criar este token aqui - https://github.com/settings/tokens
- Nome de usuário e chave de API do Heroku
- Nome do app Heroku - Você pode criar um app estático no Heroku com o que quiser que seja exibido na sua página inicial seguindo as instruções aqui - https://gist.github.com/wh1tney/2ad13aa5fbdd83f6a489. Depois de criar esse app, use o nome desse app na flag (veja abaixo). Usaremos esse app para assumir o domínio (com o CNAME pendente para outro app Heroku).
NOTA - Você só precisa desses valores se quiser assumir subdomínios. Por padrão, não é necessário.
Pacotes Go necessários para compilar.
go get github.com/bgentry/heroku-go
go get github.com/gocarina/gocsv
go get github.com/google/go-github/github
go get github.com/olekukonko/tablewriter
go get golang.org/x/net/publicsuffix
go get golang.org/x/oauth2
go get github.com/miekg/dns
Como executar?
Depois de ter tudo instalado, cd para o diretório e digite:
tko-subs -domains=domains.txt -data=providers-data.csv -output=output.csv
Se quiser também assumir, o comando seria:
tko-subs -domains=domains.txt -data=providers-data.csv -output=output.csv -takeover -githubtoken=<github-token> -herokuusername=<heroku-username> -herokuapikey=<heroku-api-key> -herokuappname=<heroku-app-name>
Se quiser apenas verificar um único domínio, digite:
tko-subs -domain <domain-name>
Se quiser verificar vários domínios, digite:
tko-subs -domain <domain-name-1>,<domain-name-2>
Por padrão:
- a flag
domains está definida como domains.txt
- a flag
data está definida como providers-data.csv
- a flag
output está definida como output.csv
- a flag
takeover não está definida, então nenhuma assunção por padrão
- a flag
domain NÃO está definida, então sempre verificará todos os domínios mencionados no arquivo domains.txt. Se a flag domain for mencionada, verificará apenas aquele domínio e ignorará o arquivo domains.txt, mesmo que presente
- a flag
threads está definida como 5
Então, simplesmente executar tko-subs rodará com os valores padrão mencionados acima.
name,cname,string,http
- name: O nome do provedor (ex: github)
- cname: O CNAME usado para mapear um site para o conteúdo do provedor (ex: github.io)
- string: A mensagem de erro retornada para um subdomínio não reivindicado (ex: "There isn't a GitHub Pages site here")
- http: Se deve usar http (não https, que é o padrão) para conectar ao site (true/false)
Domain,CNAME,Provider,IsVulnerable,IsTakenOver,Response
- Domain: O domínio verificado
- CNAME: O CNAME do domínio
- Provider: O provedor que o domínio estava usando
- IsVulnerable: Se o domínio foi considerado vulnerável ou não (true/false)
- IsTakenOver: Se o domínio foi assumido ou não (true/false)
- Response: A mensagem contra a qual o subdomínio foi verificado
Se um registo DNS morto for encontrado, Provider fica vazio.
Se um servidor de nomes com mau comportamento for encontrado, Provider e CNAME ficam vazios
O que está acontecendo por baixo dos panos?
Isso irá iterar sobre todos os domínios (concorrentemente usando GoRoutines) no arquivo subdomains.txt e:
- Verifica se eles têm um servidor de nomes autoritativo com mau comportamento; se sim, marcamos esse domínio como vulnerável.
- Verifica se eles têm registos CNAME pendentes, também conhecidos como registos DNS mortos; se sim, marcamos esse domínio como vulnerável.
- Se um subdomínio passar nesses dois testes, tenta fazer curl para obter uma resposta e então tenta ver se essa resposta corresponde a alguma das strings de provedor de dados mencionadas no arquivo providers-data.csv.
- Se a resposta corresponder, marcamos esse domínio como vulnerável.
- Em seguida, dependendo se a flag
takeover é mencionada ou não, tentará assumir esse subdomínio vulnerável.
- Por exemplo, para assumir uma Github Page, o código irá:
- Criar um repositório
- Criar um branch
gh-pages nesse repositório
- Enviar
CNAME e index.html para o branch gh-pages nesse repositório. Aqui, CNAME contém o domínio que precisa ser assumido. index.html contém o texto This domain is temporarily suspended que será exibido assim que o domínio for assumido.
- Da mesma forma, para apps Heroku, o código irá:
- Adicionar o domínio pendente ao seu app Heroku (cujo nome você fornecerá no arquivo .env)
- E é isso!
Trabalhos Futuros
Pegar nome do CMS e regex do usuário ou arquivo .env e então automaticamente conectá-los à ferramenta para ser capaz de encontrá-lo. FEITO
- Adicionar assunções para mais CMS
- Adicionar mais provedores CMS
Créditos
- Agradecimentos a Luke Young (@TheBoredEng) por me ajudar com a biblioteca go-github.
- Agradecimentos a Frans Rosen (@fransrosen) por me ajudar a entender os detalhes técnicos necessários para algumas das assunções.
- Agradecimentos a Mohammed Diaa (@mhmdiaa) por dedicar tempo para implementar a funcionalidade de dados do provedor e dar andamento ao código.
- Agradecimentos a high-stakes por uma atualização de código muito necessária.
Registro de Alterações
5/27
- Adicionado novo Dockerfile reduzindo o tamanho da imagem
- Adicionado arquivo domains.txt de exemplo para testar
- mhmdiaa adicionou a lógica para assunções de DNS mortos. Documentação atualizada. Muito obrigado!
11/6
- high-stakes emitiu um PR com um monte de novo código que corrige alguns bugs e torna o código mais limpo
9/22
- Adicionada uma flag opcional para verificar um único domínio
- Tornou mais fácil instalar e executar
6/25
- Tornou o código muito mais rápido implementando goroutines
- Em vez de verificar usando a função LookupCNAME dos pacotes net do Golang, fez com que usasse apenas dig, já que isso também fornece registos DNS mortos. Mais superfície de ataque!!