Pular para o conteúdo
Segurança Android Aplicações Web

Pipeline para análise de segurança de múltiplas aplicações Android

Lucas Ribolli Blasquez
Lucas Ribolli Blasquez
Pipeline para análise de segurança de múltiplas aplicações Android
7:08

A introdução de vulnerabilidades em um software pode ocorrer a qualquer momento, desde atualizações da própria aplicação, incluindo suas dependências, até o Sistema Operacional. Por conta disso, a análise de segurança durante todo o ciclo de vida torna-se fundamental. No caso de aplicações Android, é possível incluir uma esteira DevSecOps¹ que executa em cada mudança no código, alertando o desenvolvedor sobre problemas triviais. Entretanto, algumas vulnerabilidades só surgem após a instalação do aplicativo em um dispositivo real, exigindo uma checagem tardia.

Uma solução direta para essa questão é a inserção de uma esteira com 3 etapas:

  1. Instalação

  2. Descompilação

  3. Análise

Vale ressaltar que a fase de análise será abordada de forma sucinta neste post pois ela varia para cada cenário.


Etapa 1: Instalação

A instalação pode ocorrer de 2 formas: diretamente usando o APK final (formato de arquivo baseado em ZIP usado para distribuir e instalar aplicativos) ou por meio do serviço de distribuição, como a Play Store².

A instalação direta se resume a executar o comando "adb install"³, inserindo o nome do APK adiante. A ferramenta adb é  fundamental no ambiente Android, permitindo interações com o dispositivo após o mesmo estar conectado com a máquina.

Esse método é prático para análises ágeis, porém não garante total fidelidade com o cenário final do usuário. A segunda maneira, entretanto, requer a inserção de uma conta na lista "Beta fechado" do aplicativo no Google Play Consolee⁴
SUPERSCRIPT FOUR
Unicode: U+2074, UTF-8: E2 81 B4 publicação do mesmo antes do lançamento oficial para todos os clientes. Este passo pode ser inserido no ciclo de vida do desenvolvimento quando uma "tag" nova for inserida. Tags são criadas pelos sistemas de controle de versão, identificando uma etapa oficial do produto (testes, beta, produção, etc).

Após a publicação ter sido realizada, o aplicativo ficará disponível para ser instalado. A instalação pode ser feita por meio do Framework de automação de código aberto chamado Appium⁵. Este, opera em uma arquitetura cliente-servidor, onde um servidor Node.js recebe comandos de automação formatados em JSON do cliente e os executa em dispositivos móveis utilizando-se do UI Automator⁶.  A partir do Appium, é possível criar um script que irá abrir a Play Store e clicar no botão "Instalar" ou "Atualizar".

Um código que executa essa etapa está exemplificado abaixo:


```python
capabilities = {
    'platformName': 'Android',
    'automationName': 'uiautomator2',
    'deviceName': 'Android',
    'appPackage': 'com.android.vending',
    'noReset': True
}
driver = webdriver.Remote('http://localhost:4723', options=UiAutomator2Options().load_capabilities(capabilities))
package_name = 'your_package_name_app'
driver.execute_script('mobile:deepLink', {  
    'url': f'market://details?id={package_name}',
    'package': 'com.android.vending'
})  
driver.implicitly_wait(5)
button_name = 'Install' # 'Update'
button = driver.find_element('-android uiautomator', f'new UiSelector().text({button_name})')  
button.click()
```

A utilização de um Framework de automação, além de simular um ambiente real do usuário, facilita a instalação de aplicativos que não estão dentro da esteira mas que também precisam de checagens.

Etapa 2: Descompilação

Após os aplicativos terem sido instalados, a próxima etapa envolve transferir os APKs para a máquina e descompilá-los na sequência. Com o dispositivo ainda conectado, a transferência pode ser realizada simplesmente por meio de dois comandos adb, sendo eles "adb shell pm path", para localizar o caminho completo do arquivo no sistema, e "adb pull" para efetivar a ação.


```sh
adb shell pm path "you_package_name_app"
adb pull "full_path" "your_package_name_app.apk"
```

Com o APK localizado na máquina, é possível realizar a descompilação por meio da ferramenta de código aberto jadx[7]. Esta é voltada para a engenharia reversa, que permite a descompilação de arquivos DEX e APK do Android em código-fonte Java, facilitando a leitura. Com a instalação do jadx, basta executá-lo inserindo o caminho do APK e da pasta a qual conterá os arquivos.


```sh
jadx -d "output_folder_path" your_package_name_app.apk
```

Duas pastas serão criadas: "sources" e "resources". A primeira possui o código Java do aplicativo (e suas dependências[8]) que estará ofuscado, sendo consideravelmente diferente do código original. Já a segunda possui o código estático da aplicação, como os assets e o arquivo "AndroidManifest.xml", sendo este muito importante para o escopo de segurança.

Com o manifesto em mãos, já torna-se possível iniciar uma análise estática de segurança.


Etapa 3: Análise

A última etapa baseia-se na criação e aplicação de regras de segurança no arquivo AndroidManifest.xml. Elas são inúmeras e devem ser customizadas para o escopo do projeto.


Um exemplo é a ativação da propriedade "debuggable"[9], tornando o aplicativo vulnerável a remoções das barreiras de proteção do estado interno, ferindo a integridade do sistema.

A verificação de propriedades como essa é simples. Com a classe ElementTree do Python, basta apontá-la para o manifesto e iterar sobre os elementos dele, verificando se o elemento atual está dentro da tag "application".


```python
from xml.etree import ElementTree as ET

manifest_path_current = 'AndroidManifest.xml'
try:  
    tree = ET.parse(manifest_path_current)  
    root = tree.getroot()  

    for elem in root.iter():  
        tag = elem.tag  
        attribs = elem.attrib  
        if tag != 'application' or not attribs.get('{http://schemas.android.com/apk/res/android}debuggable'):  
            continue  
        if attribs['{http://schemas.android.com/apk/res/android}debuggable'] == 'true':  
            print(f'{manifest_path_current} has debuggable flag!')

except ET.ParseError:  
    print(f'XML Parse Error in {manifest_path_current}')  
```

A vantagem dessa etapa é poder ser acoplada no ciclo de desenvolvimento, checando falhas durante a revisão de código.


Conclusão


O pipeline apresentado oferece uma abordagem estruturada e automatizada para a análise de segurança de aplicações Android, integrando-se de forma flexível ao ciclo de vida de desenvolvimento de software. Através das três etapas é possível identificar vulnerabilidades tanto em aplicações desenvolvidas internamente quanto em aplicações de terceiros, ampliando significativamente o escopo da verificação de segurança.

A combinação de ferramentas de código aberto, como Appium e jadx, com scripts personalizados de análise estática, permite que equipes de segurança mantenham um controle contínuo sobre potenciais riscos, como a exposição indevida da flag "debuggable" e outras configurações sensíveis no AndroidManifest.xml. Dessa forma, a solução contribui para o fortalecimento da postura de segurança das aplicações Android, sendo uma adição valiosa tanto para esteiras DevSecOps quanto para auditorias de segurança pontuais.


¹O que é DevSecOps?: https://www.ibm.com/br-pt/think/topics/devsecops
²Como funciona o Google Play: https://google.play/intl/pt_pt/howplayworks/
³Android Debug Bridge (adb): https://developer.android.com/tools/adb?hl=pt-br
Google Play Console: https://developer.android.com/distribute/console?hl=pt-br
Appium: https://appium.io/docs/en/latest/
Criar testes automatizados com o UI Automator: https://developer.android.com/training/testing/other-components/ui-automator?hl=pt-br
Dex to Java decompiler: https://github.com/skylot/jadx
Adicionar dependências de compilação: https://developer.android.com/build/dependencies?hl=pt-br
android:debuggable: https://developer.android.com/privacy-and-security/risks/android-debuggable?hl=pt-br

Compartilhar este post