Post Board parte 1

“Cowsay: Code Review is coming… “

Introdução

Esta é uma resolução do desafio do Mobile Hacking Lab
onde descobri recentemente que eles estão oferecendo treinamento e laboratórios gratuitos para explorar e praticar suas habilidades de hacking mobile. Então, decidi fazer o curso e praticar os laboratórios.

Objetivo

Sua missão é navegar no webview e suas complexidades a ponto de utilizar um XSS para conseguir um RCE.



Recon

Primeiro começamos olhando o arquivo AndroidManifest.xml:

<activity  
	android:name="com.mobilehackinglab.postboard.MainActivity"  
	android:exported="true">  
	<intent-filter>  
		<action android:name="android.intent.action.MAIN"/>  
		<category android:name="android.intent.category.LAUNCHER"/>  
	</intent-filter>  
	<intent-filter>  
		<action android:name="android.intent.action.VIEW"/>  
		<category android:name="android.intent.category.DEFAULT"/>  
		<category android:name="android.intent.category.BROWSABLE"/>  
		<data  
			android:scheme="postboard"  
			android:host="postmessage"/>  
	</intent-filter>  
</activity>

Após a análise conseguimos informações importantes que são:

  1. Activity exportada == com.mobilehackinglab.postboard.MainActivity
  2. URI == postboard://postmessage

Code Review

Para entender tudo o que o App está fazendo, é necessário realizar o code review. Essa é uma das grandes vantagens de se analisar uma aplicação mobile, pois todo o código está em sua posse!

Webview & javascript

Analisando a MainActivity nos deparamos com algumas funcionalidades muito interessantes. A primeira é a definição de uma webview.

private final void setupWebView(WebView webView) {  
	webView.getSettings().setJavaScriptEnabled(true);  
	webView.setWebChromeClient(new WebAppChromeClient());  
	webView.addJavascriptInterface(new WebAppInterface(), "WebAppInterface");  
	webView.loadUrl("file:///android_asset/index.html");


Além da criação da webview, outra informação importante aqui é o nome da Interface javascript. webAppInterface e saber que o javascript está habilitado. Seguindo nossa análise, exite uma função que valida uma Intent.

private final void handleIntent() {  
	Intent intent = getIntent();  
	String action = intent.getAction();  
	Uri data = intent.getData();  
	if (!Intrinsics.areEqual("android.intent.action.VIEW", action) || data == null || !Intrinsics.areEqual(data.getScheme(), "postboard") || !Intrinsics.areEqual(data.getHost(), "postmessage")) {  
		return;


Aqui é possível entender que o formato que a URI do deep link é valido. Mesmo formato que foi visto no arquivo manifest. Porém é necessário definir a ação quando for chamar essa activity utilizando o deep link.

Vai anotando essas informações de cada análise! Pois serão muito úteis para realizar a exploração e entender o porque.


No trecho abaixo podemos perceber que a aplicação pega o valor que está vindo do “Path”. Esse valor é o mesmo que vem do deep link, depois é feito um decode em base64.


PoC javascript

Agora que muito código foi analisado, podemos validar se nosso entendimento do código está correto. Primeiro validar a execução do javascript uma vez que essa config está habilitada no código.

Payload: <img src=x onerror="alert(1337)">


O payload que consegui utilizar foi carregando o alert dentro de uma tag html de imagem.

Agora irei seguir todos os passos que foram analisados para construir meu payload. Uma vez que temos a action.VIEW definida, a MainActivity que está exportada e o deep link que está seguindo os padrões de validação. Podemos enviar nossa mensagem em Base64 no “Path”.

adb shell am start -a android.intent.action.VIEW -n com.mobile
hackinglab.postboard/.MainActivity -d "postboard://postmessage/b2kK"


RCE

Parte 2 continuação…