UnCrackable L1 Parte 1
“1 desafio 1001 maneiras de ser resolvido…”
O que é?
Segundo a própria OWASP, esse é um de uma série de desafios envolvendo mobile.
E que podem ser resolvidos utilizando o MASTG.
Introdução
Esse desafio é o primeiro de uma série de aplicações mobile que irei demonstrar como explorar. Apesar desse tipo de aplicação nunca ter sido meu maior motivador, estou bem facinado em como esse sistema faz você subverter todo seu pensamento onde antes você tinha que atacar um backend no qual você “teoricamente” não tem acesso. E agora todo código está embutido em um dispositivo onde você tem total acesso.
Engenharia Reversa (Rev)
Assim que o App é executado, é exibido um poupup de erro dizendo que o aparelho está Rootado e com isso não pode executar a aplicação!
Dito isso, o primeiro passo é fazer o Rev da aplicação e entender
como essa proteção está sendo feita. Utilizando o jadx-gui
abra o
arquivo AndroidManifest.xml
Como essa é uma aplicação simples para testes, esse XML é bem pequeno e fácil de ser interpretado. Esse arquivo contém as principais informações do aplicativo, como nome, versão, algumas configurações e o LAUNCHER.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="owasp.mstg.uncrackable1">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/>
<application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="true">
<activity android:label="@string/app_name" android:name="sg.vantagepoint.uncrackable1.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
No AndroidManifest a action.MAIN e o category.LAUNCHER dentro da tag <application>
diz para o App qual é a classe que vai inicializar o aplicativo.
Neste caso o XML está dizendo que o sg.vantagepoint.uncrackable1.MainActivity
é a primeira classe que será
chamada no App e isso pode nos dar um bom rumo de por onde começar uma análise.
Patch - (system exit & anti root)
Nesse processo de exploração, iremos realizar dois tipos diferentes de bypass.
O primeiro será fazendo o patch diretamente no código smali para que a aplicação
não consiga forçar o fechamento do App. Para entender melhor como essa proteção
funciona, iremos olhar a comparação entre Java e smali no jadx-gui
É nesse trecho de código que o App nos retorna a mensagem de erro avisando que
não podemos executar a aplicação. Porém é na linha 25 do código java que é setado como false
o cancelamento daquele alerta. Então se modificarmos para true
podemos simplesmente ignorar o
alerta e continuar no App.
Decompile o APK usando:
apktool d UnCrackable-Level1.apk
Em seguida abra com o editor:
vim UnCrackable-Level1/smali/sg/vantagepoint/uncrackable1/MainActivity.smali
Foi alterada a linha 41 do código de 0x0
que significa false para 0x1
que significa true.
Anti Root
Para fazer com que a aplicação não detecte que estamos utilizando um dispositivo com root, podemos realizar as alterações também diretamente no código para evitar que o APK consiga detectar e nos bloquear.
Se alterarmos as strings para coisas inexistentes a condição sempre retornará false
.
Agora basta compilar novamente e assinar o App e testar o bypass.
Nesse exemplo o uber-apk-signer
já faz todo o trabalho de forma automatizada, porém
em um próximo post eu mostro um pouco mais dos conceitos básicos e o que realmente
acontece por trás desse programinha.
Agora devemos ter um novo APK chamado: UnCrackable-Level1-patched-aligned-debugSigned.apk
basta instalar e ver a mágica acontecer.
Frida - (system exit & anti-root & flag)
Aqui vai a exploração com o frida…
Bypass do System.exit:
Assim a aplicação não consegue fechar o app mesmo detectando o root.
console.log("Script loaded successfully ");
Java.perform(function (){
var system = Java.use("java.lang.System");
system.exit.implementation = function(){
send("System exit bypassed!");
}
});
Bypass Root check:
Agora a aplicação não identifica nosso dispositivo com o binário su
, não irá identificar a aplicação como debuggable
e nem vai conseguir validar se o alguns caminhos padrões de binários utilizados por celulares rootados.
console.log("Script loaded successfully ");
Java.perform(function (){
var root = Java.use("sg.vantagepoint.a.c");
root.a.overload().implementation = function(){
console.log("Su check bypass!");
return false;
}
var tags = Java.use("sg.vantagepoint.a.c");
tags.b.overload().implementation = function(){
console.log("Build tags bypass!");
return false;
}
var path = Java.use("sg.vantagepoint.a.c");
path.c.overload().implementation = function(){
console.log("BYpass path validation!");
return false;
}
});
Bypass Flag:
No mesmo script vamos chamar a função que retorna a flag utilizando a própria função de decript do código.
console.log("Script loaded successfully ");
Java.perform(function (){
//Cracking the flag
var key = Java.use("sg.vantagepoint.uncrackable1.a");
var cipher = Java.use("sg.vantagepoint.a.a");
var b64_func = Java.use("android.util.Base64");
key = key.b("8d127684cbc37c17616d806cf50473cc")
var secret = b64_func.decode("5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc=", 0)
var flag = cipher.a(key, secret)
console.log("inside crypto func");
var result = "";
console.log(flag);
for (var i=0; i<flag.length; ++i){
result+= (String.fromCharCode(flag[i]));
}
console.log(result);
});
Esse é o resultado após a execução do script mostrado acima.
Em breve teremos um blog post sobre o
frida
.
Posts:
- Post Board parte 2
- Post Board parte 1
- Guess Me Parte 2
- Guess Me Parte 1
- Food Store
- IOT Connect
- UnCrackable L1 Parte 2
- UnCrackable L1 Parte 1
- CVE-2022-26352
- DCA php
- Docker Code Analyzer
- Vulnado Parte 3
- Vulnado Parte 2
- Vulnado Parte 1
- Damm Vulnerable WebSocket
- OWASP ZAP Zed Attack Proxy
- Estratégias de um code review
- O que é code review?