Olá a todos e bem-vindos de volta à nossa nova série, que trata da solução de alguns desafios de captura
da bandeira em conjunto.
No último vídeo, resolvemos o validador de licenças do Android, o que foi muito divertido.
E agradeço a Bernhard Müller por ter proposto esse desafio.
E nesse vídeo, talvez seja sério, porque parece que há muitas outras vulnerabilidades.
Resolveremos o Android Gold ou, pelo menos, tentaremos resolvê-lo.
Então, vamos dar uma olhada.
O Android Gold é um desafio sobre o qual não tenho a menor ideia.
Eu ainda não o instalei, portanto, ele será completamente novo para mim.
É um código aberto, vulnerável.
É uma história de código aberto.
Mais uma vez, trata-se de um aplicativo de código aberto, vulnerável e inseguro que usa Kotlin.
E isso também é muito interessante porque recebo muitos comentários sobre o Kotlin.
E veremos ou descobriremos que, na verdade, não importa se é Java ou Kotlin.
Com relação à reversão desse aplicativo.
Vamos seguir em frente.
Esse aplicativo tem uma ampla gama de vulnerabilidades relacionadas à fixação de certificados, esquemas de URL personalizados,
configurações de segurança de rede do Android, uso da Web, detecção de rotas e mais de 20 outras.
Tudo bem, parece ser muito divertido.
Hum, e neste ponto, obrigado a todos os autores por fornecerem esses aplicativos.
Então, vamos dar uma olhada.
Ele está disponível aqui.
Tudo bem.
Hum, não há liberação.
Está bem.
Um.
Download.
Muito bem.
Caso contrário, teríamos que criá-lo por conta própria, mas acho que podemos baixá-lo aqui.
Muito bem, vamos ver.
Sim.
Parece bom.
Pronto, já fizemos o download.
Não tenho certeza se precisamos de algo.
Vejamos.
Código aberto usando Kotlin e assim por diante.
Está bem, está bem.
Tudo bem.
Não tenho certeza se ele é executado em uma máquina virtual.
Se você precisar de um dispositivo real, se tiver que configurar algum servidor da Web como esse, nós resolveremos
isso juntos.
Muito bem.
Está bem.
Então, baixamos esse aplicativo e temos nossa máquina virtual em execução.
E vamos ver no código.
Vamos colocar isso em nosso CTF.
Ah, vamos renomear esse validador de licenças.
E este é Andrew Goat.
Sim.
Está bem.
Vamos instalar esse aplicativo e depois veremos.
Está bem.
Uh oh.
É aqui.
Veja!
Logotipo incrível.
E essa fonte.
Hum, esse é o autor.
Obrigado por fornecer esse aplicativo.
Está bem.
Então, tudo bem, isso está fora do readme, eu acho.
Está bem.
Ok, então acho que podemos escolher nossos desafios, o que também parece incrível.
Eu sugeriria que começássemos com a detecção de rota ou emulador.
Vamos fazer as duas coisas.
Acho que são idênticos.
Vamos ver se temos rota.
Dispositivos roteados.
Ok, já fomos pegos.
Vamos ver a detecção do emulador.
Está bem.
Ele também diz que é um emulador, portanto, estamos completamente perdidos.
Acho que fizemos besteira nesse ponto.
Portanto, vamos descobrir como podemos fazer melhor.
Tudo bem.
Começamos com a detecção da raiz.
Portanto, primeiro descompilamos esse aplicativo.
Vamos tentar a GUI do CD, caso a GUI do jcs falhe em determinados pontos, e recomendo enfaticamente o uso do Andrew Card.
O descompilador de bate-papo.
Desculpe, mas o descompilador do pai é muito melhor em alguns casos.
Vejamos.
Hum, sim, vamos fazer isso desafio por desafio, eu acho.
Mas se eu voltar atrás, esses não são 20 desafios.
Portanto, acho que teremos que descobrir o restante mais tarde, navegando por esse aplicativo.
Vamos dar uma olhada rápida no manifesto do Android para ter uma visão geral do que está acontecendo.
Podemos ver que ele usa a permissão de direito da Internet e lê o armazenamento externo.
Muito interessante.
Temos que descobrir o que está acontecendo no armazenamento externo aqui.
Em seguida, temos nossa atividade principal, que é a atividade de entrada, que é a atividade inicial.
Aqui temos o principal.
Aqui temos a detecção da raiz.
Portanto, vamos nos concentrar nesse caso.
Temos registro inseguro de XSS, injeção de SQL.
Está bem.
O que é esse aqui?
Atividade de controle de acesso.
É interessante porque é exportado.
E aqui podemos ver que ele está usando o filtro de intenção com dados de categoria de ação.
Portanto, isso pode estar relacionado a deep links ou links da Web, nesse caso, porque temos um esquema e um host que não me incomodam.
Mas os provedores de conteúdo também são incríveis.
Então, sim, eu sugeriria que esse parece ser um começo incrível.
Portanto, vamos dar uma olhada na atividade de detecção de rota, ok, vamos começar por aqui.
E podemos ver que isso vem do Kotlin.
Mas simplesmente ignore isso.
Portanto, não estamos vendo isso.
E podemos simplesmente seguir em frente.
Hum, ok.
E aqui temos nosso método Oncreate.
Então, podemos ver que temos um botão conectado.
Esse pode ser o botão raiz do nosso layout.
Talvez.
Vamos colocar os dados lado a lado.
Portanto, se você for para a detecção de raiz, verifique a possibilidade de raiz, então poderemos ver a atividade de detecção de raiz com um clique.
Este é um dispositivo com root.
Este dispositivo não tem root, ok.
Vamos ver a detecção de raiz.
Isso está enraizado.
Se você entrar nessa.
Ah, essa era a atividade.
Existe um método.
Este é o que estou procurando.
Está bem.
Podemos ver o padrão familiar.
Ele procura o apk bin do superusuário como se fosse algo assim.
Começamos com falso.
E se esse arquivo existir.
Obtemos o resultado.
Se o resultado for positivo, retornaremos um booleano que é verdadeiro.
E então sabemos que está bem enraizado e aqui estamos executando no comando.
Estamos executando o comando rescue e, em seguida, os dados do LHS.
Dados se recebermos dados de volta.
Ou, se ele não lançar uma exceção, também saberemos que está enraizado.
Portanto, o que precisamos fazer é corrigir os dois valores de retorno aqui.
Também podemos ajustar sua raiz aqui.
Não importa, mas eu gosto de corrigir as detecções iniciais de roteamento porque, se elas
forem usadas de outra forma no aplicativo, podemos ter certeza de que não serão detectadas como
roteadas também em outras funções.
Muito bem.
Está bem.
Portanto, vamos fazer isso.
Um.
Precisamos descompilar esse aplicativo.
Quer dizer, podemos usar a Frieda, podemos usar o smiley patching.
Gosto de usar o smiley, eu acho.
Sim, porque se tivermos alguma detecção de manipulação em tempo de execução mais tarde, poderemos lidar com elas separadamente.
Muito bem.
Um.
Vejamos.
O apktool o decodifica.
A propósito, atualize sua ferramenta APK porque ela tem uma vulnerabilidade.
Que.
Leva à execução remota de código se você descompilar um aplicativo malicioso.
Portanto, a versão corrigida é a 2. 2.
Desculpe, 2. 9. 2.
Sim.
A versão vulnerável era a 2. 9. 1, eu acho.
Podemos também fazer um vídeo separado sobre isso, mas agora estamos aqui para resolver alguns desafios.
Tudo bem.
Então, aqui está.
O que precisamos fazer, pessoal.
Podemos ver que temos o diretório smiley.
Vamos abri-lo com o Visual Studio Code.
Ok, então vamos dar uma olhada rápida.
Hum, sim, eu confio no autor.
Estamos dentro.
OWASp, S. A. T. , r atividade de detecção de raiz de cabra.
Ok, OWASp, srt goat.
Está bem.
E depois a detecção de raiz.
Onde o temos?
Aqui.
Ok, escolhemos Java.
Está bem.
E podemos ver.
Sim, parece um pouco mais bagunçado com todos esses caracteres Unicode, mas não nos preocupamos com
isso.
Esses são apenas metadados.
Nós ignoramos isso.
Está bem.
Qual é a função?
A função was está enraizada.
Muito bem, vamos ver.
Hum, vamos lá.
Ah, tudo bem.
É aqui.
Já reconheci esses padrões, portanto, podemos ver que se trata de um conjunto de retornos enraizados.
O caminho mais curto, eu acho, é excluir todo esse código e simplesmente ir até o valor de retorno e substituí-lo.
Portanto, não vamos torná-lo mais complexo ou tentar flexibilizá-lo de uma determinada maneira.
Vamos simplesmente manter as coisas fáceis.
Certo, então acho que temos que excluir esse código e vamos ver como podemos, hum.
Sim, é isso que estamos procurando.
Const slash v e, em seguida, o registro e zero.
Está bem.
Portanto, vamos nos livrar desse também.
Const.
Quero dizer, se você não está fornecendo algo, então sabemos que é essa largura de bit.
Então, vamos escolher simplesmente para um, porque precisamos apenas de um bit.
Não importa.
E então nós um e 0X0 ok.
O mesmo padrão.
Ou seja, também podemos escolher a v0.
Isso realmente não importa.
Temos muitos registros locais, portanto, isso não importa.
Aqui temos um enraizado.
Esse é o comando?
Sim, esse é o comando.
Então, simplesmente fazemos o mesmo aqui.
Tudo bem.
E acho que é isso.
Portanto, essa é a nossa solução.
Vejamos.
Nós o salvamos e agora voltamos e o construímos.
É bom ser.
Até o momento, não há erros, o que é bom.
E vamos dar uma olhada na distância.
Agora precisamos sibilar.
Portanto, esse é o nosso bode Andrew.
Está bem.
E agora precisamos assiná-lo com o assinador de APK.
Está bem.
E agora precisamos desinstalar.
E, em seguida, reinstale-o.
Então, tudo bem.
Vejamos.
O aplicativo parece começar a funcionar.
E a detecção de raiz verifica a exceção de raiz.
Nenhum dispositivo não tem root.
Fácil, não é?
Vamos fazer a mesma abordagem para o emulador.
Detecção de emulador.
Então, vamos simplesmente abrir o Visual Studio Code mais uma vez.
E.
Ah, desculpe.
Talvez tenhamos que descobrir isso, mas acho que é o mesmo padrão.
Mas, mesmo assim.
Vejamos.
Detecção de emulador.
Aqui.
Está bem.
Sim.
Temos esse emulador.
Podemos ver se essa função retorna verdadeiro.
Em seguida, ele é um emulador e executa algumas compilações, impressões digitais do dispositivo, marca do modelo e assim por diante.
E então, hum, string zero.
Para todos os retornos, a string contém utilitários de compilação e assim por diante.
Tudo bem.
Portanto, mais uma vez, o booleano é emulador verdadeiro ou falso, dependendo de determinadas verificações.
Podemos ver essas verificações aqui.
X86 e chaves de teste.
Peixe dourado.
Sim.
Tudo bem.
Portanto, eu sugeriria que fizéssemos a mesma abordagem.
Está bem.
Hum, emulador.
Detecção.
E agora podemos ver que temos aqui duas atividades.
Quero dizer, temos a mesma atividade, mas aqui temos o oncreate.
Porque esse é o caso.
Se tivermos uma classe interna, o que é interessante.
Hum, appcompat.
Está bem.
Oncreate.
Certo, então nosso código pode estar no original deste aqui.
E o oncreate parece ser terceirizado aqui.
Um.
Não tenho 100% de certeza de por que terceirizamos o onClick.
E também o método Oncreate.
Aqui está a parte.
O emulador é verdadeiro?
Desculpe.
Vamos ativar o Java.
Sim, mas essa é apenas a chamada da função.
Hum, não é isso que nos interessa.
Estamos interessados nessa parte.
Então, vamos dar uma olhada.
Está bem.
O emulador está funcionando bem?
Isso deveria ser.
Essa função aqui é um emulador booleano ok.
E sim, vamos fazer a mesma abordagem.
Então, removemos tudo.
Seu VBox Genymotion x86.
Também podemos corrigir essas chaves.
Mas nós simplesmente removemos tudo.
Renomeamos isso para zero.
Fazemos isso dessa forma e, em seguida, dizemos "devolva-me zero" e também excluímos o restante.
A abordagem de exclusão é, na minha opinião, a mais fácil e funciona se não estivermos criando algo aqui.
Portanto, se esse for o caso, basta entrar nessa função, realizar algumas verificações e sair.
Então, podemos simplesmente excluí-lo, caso tenhamos algo como entrar nessa função, criar alguns objetos e
usá-los mais tarde, então não poderemos excluí-los.
Temos que corrigir a lógica que está retornando sempre falso e coisas desse tipo.
Muito bem.
Está bem.
Então, voltando a este, este emulador.
Isso também deve ser bom.
Então vamos ver.
Nós voltamos.
Está bem.
Apktool B we build it.
Está bem.
Em seguida, vamos para o diretório do disco.
Removemos os antigos, sibilamos, assinamos e agora podemos reinstalá-lo porque o aplicativo existente foi assinado
com o mesmo certificado.
Portanto, podemos simplesmente sobrescrevê-lo.
E agora devemos ter resolvido a segunda parte.
Vejamos.
Verificação da detecção do emulador.
Não se trata de um emulador.
Perfeito.
Parece bom.
Hum, então o que queremos usar?
Validação de entrada, armazenamento inseguro de dados, aplicativo desprotegido, componentes do Android.
Parece tudo muito incrível.
Mas, no momento, estamos usando patches binários.
Portanto, eu sugeriria que fizéssemos a correção binária.
Obter acesso à funcionalidade de administrador.
Desculpe, mas você não tem acesso a esse recurso.
Isso é algo que também encontrei em um aplicativo do mundo real.
Não se tratava de um recurso de administrador, mas de um recurso de depuração.
E ao definir ou não o sinalizador de depuração, o usuário tem essas opções ou não.
Na compilação de produção, esse sinalizador de depuração não foi definido, mas, ao defini-lo, você passou
a ter acesso a ele e a certas chamadas de API ainda novas, o que foi incrível.
Então, sim, esse é um bom exemplo.
Está bem.
Vejamos.
Aplicação de patches binários.
Temos isso aqui?
Acho que esta visão geral é a mais fácil de encontrar todos esses desafios.
E então temos que descobrir como alcançar o restante.
Não tenho certeza sobre isso.
E o cache de teclado também é incrível, mas vamos ver.
Aplicação de patches binários.
Está bem.
Podemos ver que se trata de um administrador.
Está bem.
Retorna esse booleano de administrador.
Get is admin.
Essa função é mesmo chamada aqui?
Acho que não.
Encontrar uso.
Não, não está sendo chamado de "ok".
Portanto, temos que definir isso por nós mesmos.
Certo, precisamos corrigir esse problema no início, caso contrário.
Sim.
Se essa função não estiver sendo chamada, simplesmente a alteramos.
Sim.
Também podemos alterar essa instrução if aqui, ok.
Portanto, mais uma vez, muitas funções.
Desculpe-me, são muitas possibilidades.
Quando estou concentrado, às vezes me deparo com coisas estranhas.
Então, por favor, tenha paciência comigo.
Um, patching binário.
Está bem.
Java.
Um.
Vejamos.
É administrador.
Quer dizer, podemos remendar isso aqui para retornar.
É verdade, mas isso não importa.
Porque se isso não estiver sendo usado, então.
Sim.
Uh.
Vamos verificar isso.
Ele está sendo usado.
Eu já havia perdido isso antes.
Eu sinto muito.
Erro meu.
Não, essa não é a função.
Está bem.
Então vamos voltar.
O que acontece aqui?
Estamos buscando o campo de instância.
Sim, é P0, então estamos buscando o campo de instância de P0 é admin.
Não é a chamada de função, é o campo de instância.
Este aqui.
E depois.
Ops, desculpe.
E então verificamos.
Se esse for o mesmo que V0.
Se não for igual, passamos para a condição zero, o que significa.
Estamos aqui.
E este aqui é.
O botão de administração.
Ok, mais uma vez, vamos limpar isso e voltar.
Tudo bem.
Temos o método Oncreate.
Temos essa estranha constante na versão 0.
Em seguida, invocamos o virtual com isso.
Está bem.
Essa é a visualização do conteúdo, ok.
Agora temos o I get boolean.
Buscamos isso em V0 e temos v1, que é codificado por hardware.
Então, isso significa.
Dependendo de qual é o administrador.
Sim, se este for um deles.
Está bem.
Mais uma vez, nós.
Isso também ainda me confunde.
Se v um não for igual a v zero, saltamos para a condição zero.
E isso é algo que não queremos ter.
Portanto, v0 e v1 precisam ser iguais, o que significa que precisamos retornar um.
Sim, a lógica faz sentido, o que significa que v0 precisa ser um e v0 é simplesmente.
É interessante.
É um valor estranho.
Portanto, não vamos entrar nesse assunto agora.
Está bem.
Portanto, temos algumas possibilidades.
O mais estranho seria usar este.
Não tenho certeza se isso funcionaria, mas, pela lógica atual, talvez funcione.
Portanto, o registro foi usado para uma visualização de referência inteira.
E se for exatamente o mesmo valor, ignoraremos essa verificação de administração, que é algum tipo de otimização
do compilador, porque essa função aqui nunca foi usada.
Uh.
Aqui.
Espero não estar confundindo-o neste momento.
Portanto, vamos simplificar isso.
Eles precisam ser os mesmos.
E nós somos um só.
Portanto, vamos simplesmente substituir nosso V0 aqui também por um.
Então, ambos são iguais.
E aqui estamos sobrescrevendo.
E zeramos mais uma vez.
Portanto, não importa se já o substituímos diretamente antes, então estamos substituindo-o aqui de qualquer forma.
Portanto, podemos escolher o que quisermos aqui.
Esta é a minha abordagem no momento.
Você também pode inverter a lógica da instrução if aqui, o que significa que, se não for igual, precisa ser se for igual,
sempre entraríamos nessa parte e, somente se tivermos acesso de administrador, entraríamos no caminho errado.
Portanto, isso inverteria a lógica.
E, sim, também podemos remover essa instrução if.
Essa também pode ser uma abordagem fácil.
Assim, teríamos acesso direto a esse código aqui, ok, ok.
Portanto, esta é a solução para mim no momento.
Você pode brincar com isso.
Mas acho que isso deve funcionar dessa forma.
Muito bem, vamos ver.
E vamos voltar.
Vamos criar esse aplicativo.
Em seguida, remova o restante e, então, vamos ver.
Alinhar o sinal e instalar.
Certo, vamos começar e ver.
Aplicação de patches binários.
O Batman agora e o Batman Seeds parecem estar ativos.
Vamos clicar.
Ok, acho que não há nada que aconteça depois, mas podemos ver que resolvemos esse desafio com
sucesso também.
Muito bem, já temos três.
Talvez.
Vamos examinar o problema do código rígido.
Se for relacionado à aplicação de patches, então vamos usar este vídeo.
Caso contrário, sugiro que cortemos a série aqui, chamemos esse patch binário e continuemos em outro vídeo.
Muito bem, perfeito.
Portanto, descubra como nosso código promocional Pro é codificado e nosso código promocional para obter a produção abaixo de graça.
Ok, este não é um patch binário.
Esse é um desafio inverso.
Portanto, eu sugeriria.
Sim.
Cortamos esse vídeo aqui.
Nomeie a primeira como correção binária e, em seguida, passe para a análise secreta, algo assim.
Muito bem.
Está bem.
Portanto, estou ansioso para vê-lo na próxima parte.