Você está na página 1de 25

Traduzido do Inglês para o Português - www.onlinedoctranslator.

com

Figura 4-4:Algumas das permissões solicitadas pelo aplicativo de destino

Análise estática

oanálise estáticaA fase envolve a análise de código e dados no aplicativo (e


componentes de suporte) sem executar diretamente o aplicativo. No início, isso
envolve a identificação de strings interessantes, como URIs codificados, credenciais
ou chaves. Depois disso, você executa análises adicionais para construir gráficos de
chamadas, verificar a lógica e o fluxo do aplicativo e descobrir possíveis problemas
de segurança.
Embora o Android SDK forneça ferramentas úteis comodexdumpdesmontar
classes.dex,você pode encontrar outras informações úteis em outros arquivos no
APK. A maioria desses arquivos está em vários formatos, como XML binário e
94 Capítulo 4-Revisando a segurança do aplicativo

pode ser difícil de ler com ferramentas comuns comogrep.Usandoapktool, que


pode ser encontrado emhttps://code.google.com/p/android-apktool/,você pode con-
converter esses recursos em texto simples e também desmontar o bytecode executável
Dalvik em um formato intermediário conhecido comopequeno(um formato que você verá
mais tarde).
Correapktool dcom o arquivo APK como parâmetro para decodificar o conteúdo do APK e
colocar os arquivos em um diretório com o nome do APK:

~$ apktool d ygib-1.apk I:
Baksmaling...
I: Carregando tabela de recursos... . . .

I: Decodificando valores */* XMLs... I:


Pronto.
I: Copiando assets e libs...

Agora você podegreppara strings interessantes como URLs neste aplicativo, o que
pode ajudar a entender as comunicações entre esse aplicativo e um serviço da web.
Você também usagrepignorar quaisquer referências aesquemas.android . com,uma
string de namespace XML comum:
~$ grep -Eir "https?://" ygib-1 | grep -v "esquemas.android.com"

ygib-1/smali/com/yougetitback/androidapplication/settings/xml/ XmlOperator.smali:

const-string v2, "http://cs1.ucc.ie/~yx2/upload/upload.php" ygib-1/res/layout/main.xml:


xmlns:ygib="http://www.ywlx. net/apk/res/ com.yougetitback.androidapplication.cpw.mobile">

ygib-1/res/values/strings.xml: <string name="mustenteremail">Por favor, insira um endereço de e-mail


anterior se você já tiver uma conta em
https://virgin.yougetitback.com ou um novo endereço de e-mail
se você deseja ter uma nova conta para controlar este dispositivo.</string> ygib-1/res/
values/strings.xml: <string name="serverUrl"> https://virgin.yougetitback.com</string>

ygib-1/res/values/strings.xml:Crie uma conta em https://


virgin.yougetitback.com
antes de ativar este dispositivo"</string> ygib-1/res/values/strings.xml: <string
name="showsalocation"> http://virgin.yougetitback.com/showSALocation?cellid=</
string> ygib-1 /res/values/strings.xml: <string name="termsofuse"> https://
virgin.yougetitback.com/terms_of_use</string> ygib-1/res/values/strings.xml: <string
name="eula "

> https://virgin.yougetitback.com/eula</string> ygib-1/res/values/strings.xml:


<string name="privacy"> https://virgin.yougetitback.com/privacy_policy</
string > ygib-1/res/values/strings.xml:

<string name="registration_succeed_text"> Registro de conta bem-


sucedido, agora você pode usar o
endereço de e-mail e senha inseridos para fazer login em seu cofre pessoal em http://
virgin.yougetitback.com</string>
Capítulo 4-Revisando a segurança do aplicativo 95

ygib-1/res/values/strings.xml:
<string name="registrationerror5">ERRO: criando conta de usuário. Por favor, vá
para http://virgin.yougetitback.com/forgot_password onde você pode redefinir sua
senha, alternativamente digite uma nova
email e senha nesta tela e criaremos uma nova conta para você. Obrigado.</string>

ygib-1/res/values/strings.xml: Parabéns, você se


<string
registrou
name="registrationssuccessful">
com
sucesso. Agora você pode usar este e-mail e senha fornecidos para

faça login no seu cofre personalizado em http://virgin.yougetitback.com </string>

ygib-1/res/values/strings.xml: https://virgin.yougetitback.com/vault</string>
<string name="link_accessvault">
ygib-1/
res/values/strings.xml: <string name="text_help"> Acesse seu site vault ou altere sua
senha em <a> https://virgin.yougetitback.com/forgot_password</a></string>

Emboraapktoole utilitários comuns do UNIX ajudam em uma pitada, você precisa de


algo um pouco mais poderoso. Nesse caso, chame a estrutura de análise e engenharia
reversa baseada em PythonAndroguarda. Embora o Androguard inclua utilitários
adequados para tarefas específicas, este capítulo se concentra naandróliseferramenta no
modo interativo, que fornece um shell IPython. Para começar, basta usar o
Analisar APKmétodo para criar objetos apropriados representando o APK e seus recursos; o
próprio código Dex; e também adicionar uma opção para usar oPapaidescompilador, para que
você possa converter de volta para a pseudo-fonte Java:

~$ androlyze.py –s
Em [1]: a,d,dx = AnalyzeAPK("/home/ahh/ygib-1.apk",decompiler="dad")

Em seguida, reúna algumas informações superficiais adicionais sobre o aplicativo, ou


seja, para confirmar o que você viu durante a criação de perfil. Isso inclui coisas como
quais permissões o aplicativo usa, atividades com as quais o usuário provavelmente irá
interagir, serviços que o aplicativo executa e outros receptores de intent. Confira as
permissões primeiro, chamandopermissões:

Em [23]: a. permissões
Fora[23]:
['android.permission.CAMERA',
'android.permission.CALL_PHONE',
'android.permission.PROCESS_OUTGOING_CALLS',
...
'android.permission.RECEIVE_SMS',
'android.permission.ACCESS_GPS',
'android.permission.SEND_SMS',
'android.permission.READ_SMS',
'android.permission.WRITE_SMS',
...

Essas permissões estão de acordo com o que você viu ao visualizar este aplicativo no
Google Play. Você pode dar um passo adiante com o Androguard e descobrir quais
96 Capítulo 4-Revisando a segurança do aplicativo

classes e métodos no aplicativo realmente usam essas permissões, o que pode


ajudá-lo a restringir sua análise a componentes interessantes:
Em [28]: show_Permissions(dx)
ACCESS_NETWORK_STATE :
1 Lcom/yougetitback/androidapplication/PingService;->deviceOnline()Z (0x22) ---> Landroid/
net/ConnectivityManager;-
> getAllNetworkInfo()[Landroid/net/NetworkInfo;
1 Lcom/yougetitback/androidapplication/PingService;->wifiAvailable()Z (0x12) ---> Landroid/
net/ConnectivityManager;-
> getActiveNetworkInfo()Landroid/net/NetworkInfo;
...
ENVIAR SMS :
1 Lcom/yougetitback/androidapplication/ActivateScreen;-
> sendActivationRequestMessage(Landroid/content/Context; Ljava/lang/String;)V (0x2)
---> Landroid/telephony/SmsManager;-
> getDefault()Landroid/telefonia/SmsManager;
1 Lcom/yougetitback/androidapplication/ActivateScreen;
- > sendActivationRequestMessage(Landroid/conteúdo/Contexto;
...
INTERNET:
1 Lcom/yougetitback/androidapplication/ActivationAcknowledgeService;-
> doPost(Ljava/lang/String; Ljava/lang/String;)Z (0xe)
- - - > Ljava/net/URL;->openConnection()Ljava/net/URLConnection; 1 Lcom/yougetitback/
androidapplication/ConfirmPinScreen;->doPost( Ljava/lang/String; Ljava/lang/String;)Z
(0xe)
- - - > Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
...

Embora a saída tenha sido detalhada, este trecho reduzido mostra alguns
métodos interessantes, como odo Postmétodo noConfirmPinScreenclasse, que deve
abrir um socket em algum momento enquanto exercitaandroid.permission .
INTERNET.Você pode ir em frente e desmontar este método para entender o que
está acontecendo chamandomostrarno método de destino emandrólise:
Em [38]: d.CLASS_Lcom_yougetitback_androidapplication_ConfirmPinScreen.
METHOD_doPost.show()
# # # # # # # # # # Informações do método Lcom/yougetitback/
androidapplication/ConfirmPinScreen;-
> doPost(Ljava/lang/String; Ljava/lang/String;)Z
[access_flags=private]
# # # # # # # # # # Parâmetros

- registros locais: v0...v10


- v11:java.lang.String
- v12:java.lang.String
- return:boolean
###################
*******************************************************************
* * doPost-BB@0x0 :
0 (00000000) const/4 v6, 0
1 (00000002) const/4 v5, 1 [ doPost-BB@0x4 ]

doPost-BB@0x4 :
2 (00000004) nova instância v3, Ljava/net/URL;
Capítulo 4-Revisando a segurança do aplicativo 97

3 (00000008) invocar-direto (Ljava/ v3, v11, Ljava/net/URL;-><init>


lang/String;)V
4 (0000000e) invocar-virtual v3, Ljava/net/URL;-
> openConnection()
Ljava/net/URLConnection;
5 (00000014) move-result-object v4
6 (00000016) check-cast v4, Ljava/net/HttpURLConnection; v4, v10,
7 (0000001a) objeto-iput Lcom/yougetitback/
androidapplication/ConfirmPinScreen;->con Ljava/net/HttpURLConnection;
8 (0000001e) objeto-iget v4, v10, Lcom/yougetitback/
androidapplication/ConfirmPinScreen;->con Ljava/net/HttpURLConnection;
9 (00000022) const-string 10 v7, 'POST'
(00000026) chamar-virtual v4, v7, Ljava/net/HttpURLCConnect-
ção;
- > setRequestMethod(Ljava/lang/String;)V 11
(0000002c) iget-object v4, v10, Lcom/yougetitback/
androidapplication/ConfirmPinScreen;->con Ljava/net/HttpURLConnection;
12 (00000030) const-string 13 v7, 'Tipo de conteúdo'
(00000034) const-string x-www- v8, 'aplicativo/
form-urlencoded'
14 (00000038) invocar-virtual HttpURLConnection;->setRequestProperty(Ljava/lang/String;
v4, v7, v8, Ljava/net/
Ljava/lang/String;) V

15 (0000003e) iget-object androidapplication/ConfirmPinScreen;->con


v4, v10, Lcom/yougetitback/
Ljava/net/
HttpURLConnection; . . .

31 (00000084) const-string 32 v7, 'Agente do usuário'


(00000088) const-string v8, 'Cliente Android'
...
49 (000000d4) iget-object androidapplication/ConfirmPinScreen;->con
v4, v10, Lcom/yougetitback/
Ljava/net/
HttpURLConnection;
50 (000000d8) const/4 v7, 1
51 (000000da) invocar-virtual v4, v7, Ljava/net/
HttpURLConnection;
- > setDoInput(Z)V
52 (000000e0) iget-object androidapplication/ConfirmPinScreen;->con
v4, v10, Lcom/yougetitback/
Ljava/net/
HttpURLConnection;
53 (000000e4) invocar-virtual v4, Ljava/net/HttpURLConnection;
- > conectar()V

Primeiro você vê algumas informações básicas sobre como a Dalvik VM deve lidar com
a alocação de objetos para este método, juntamente com alguns identificadores para o
próprio método. Na desmontagem real que se segue, a instanciação de objetos como
java.net.HttpURLConnectione invocação desse objetoconectarmétodo
confirme o uso doINTERNETpermissão.
Você pode obter uma versão mais legível desse método descompilando-o, que retorna
uma saída que efetivamente se assemelha à fonte Java, chamandofontenesse mesmo
método de destino:

Em [39]: d.CLASS_Lcom_yougetitback_androidapplication_ConfirmPinScreen.
METHOD_doPost.source()
private boolean doPost(String p11, String p12)
{
98 Capítulo 4-Revisando a segurança do aplicativo

this.con = new java.net.URL(p11).openConnection();


this.con.setRequestMethod("POST");
this.con.setRequestProperty("Content-type", "application/
x-www-form-urlencoded");
this.con.setRequestProperty("Content-Length", new
StringBuilder().append(p12.length()).toString());
this.con.setRequestProperty("Conexão", "manter ativo");
this.con.setRequestProperty("User-Agent", "Cliente Android");
this.con.setRequestProperty("aceitar", "*/*");
this.con.setRequestProperty("Versão HTTP", "HTTP/1.1");
this.con.setRequestProperty("Idiomas de conteúdo", "pt-PT");
this.con.setDoOutput(1);
this.con.setDoInput(1);
this.con.connect();
v2 = this.con.getOutputStream();
v2.write(p12.getBytes("UTF8")); v2.flush();

android.util.Log.d("Teste YGIB", new


StringBuilder("con.getResponseCode()—
> ").append(this.con.getResponseCode()).toString()); android.util.Log.d("YGIB
Test", new StringBuilder( "urlString-->").append(p11).toString ());

android.util.Log.d("Teste YGIB", new StringBuilder("content-->").


append(p12).toString());
...

NOTAObserve que a descompilação não é perfeita, em parte devido às diferenças entre a


Dalvik Virtual Machine e a Java Virtual Machine. A representação de controle e fluxo de
dados em cada um afeta a conversão de bytecode Dalvik para pseudo-fonte Java.

Você vê chamadas paraandroid.util.Log.d,um método que grava uma mensagem no


logger com a prioridade de depuração. Nesse caso, o aplicativo parece estar registrando
detalhes da solicitação HTTP, o que pode ser um vazamento de informações interessante.
Você verá os detalhes do log em ação um pouco mais tarde. Por enquanto, veja quais
endpoints IPC podem existir neste aplicativo, começando pelas atividades. Por esta,
ligarget_atividades:
Em [87]: a.get_activities() Out[87]:

['com.yougetitback.androidapplication.ReportSplashScreen',
'com.yougetitback.androidapplication.SecurityQuestionScreen',
'com.yougetitback.androidapplication.SplashScreen',
'com.yougetitback.androidapplication.MenuScreen',
...
'com.yougetitback.androidapplication.settings.setting.Setting',
'com.yougetitback.androidapplication.ModifyPinScreen',
'com.yougetitback.androidapplication.ConfirmPinScreen',
Capítulo 4-Revisando a segurança do aplicativo 99

'com.yougetitback.androidapplication.EnterRegistrationCodeScreen',
...

Em [88]: a.get_main_activity()
Out[88]: u'com.yougetitback.androidapplication.ActivateSplashScreen'

Sem surpresa, este aplicativo tem inúmeras atividades, incluindo oConfirmPinScreen


você acabou de analisar. Em seguida, verifique os Serviços ligando paraget_services:

Em [113]: a.get_services()
Fora[113]:
['com.yougetitback.androidapplication.DeleteSmsService',
'com.yougetitback.androidapplication.FindLocationService',
'com.yougetitback.androidapplication.PostLocationService', . . .

'com.yougetitback.androidapplication.LockAcknowledgeService',
'com.yougetitback.androidapplication.ContactBackupService',
'com.yougetitback.androidapplication.ContactRestoreService',
'com.yougetitback.androidapplication.UnlockService',
'com.yougetitback.androidapplication.PingService',
'com.yougetitback.androidapplication.UnlockAcknowledgeService', . . .

'com.yougetitback.androidapplication.wipe.MyService', . . .

Com base na convenção de nomenclatura de alguns desses Serviços (por exemplo,


Serviço de desbloqueioelimpar),eles provavelmente receberão e processarão comandos de outros
componentes do aplicativo quando determinados eventos forem acionados. Em seguida, veja
BroadcastReceivers no aplicativo, usandoget_receivers:

Em [115]: a.get_receivers()
Fora[115]:
['com.yougetitback.androidapplication.settings.main.Entrance$MyAdmin',
'com.yougetitback.androidapplication.MyStartupIntentReceiver',
'com.yougetitback.androidapplication.SmsIntentReceiver',
'com.yougetitback.androidapplication.IdleTimeout',
'com.yougetitback.androidapplication.PingTimeout',
'com.yougetitback.androidapplication.RestTimeout',
'com.yougetitback.androidapplication.SplashTimeout',
'com.yougetitback.androidapplication.EmergencyTimeout',
'com.yougetitback.androidapplication.OutgoingCallReceiver',
'com.yougetitback.androidapplication.IncomingCallReceiver',
'com.yougetitback.androidapplication.IncomingCallReceiver',
'com.yougetitback.androidapplication.NetworkStateChangedReceiver',
'com.yougetitback.androidapplication.C2DMReceiver']

Com certeza, você encontra um Broadcast Receiver que parece estar relacionado ao
processamento de mensagens SMS, provavelmente para comunicações fora de banda, como bloqueio
100 Capítulo 4-Revisando a segurança do aplicativo

e limpando o aparelho. Como o aplicativo solicita oREAD_SMSpermissão, e você vê um


receptor de transmissão curiosamente chamado,SmsIntentReceiver, as chances são
boas de que o manifesto do aplicativo contenha um filtro Intent para o
SMS_RECEIVEDtransmissão. Você pode visualizar o conteúdo deAndroidManifest.xml
dentroandrólisecom apenas algumas linhas de Python:

Em [77]: for e em x.getElementsByTagName("receptor"):


imprimir e.toxml()
....:
...
<receiver android:enabled="true" android:exported="true" android:name=
"com.yougetitback.androidapplication.SmsIntentReceiver"> <intent-filter
android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"> </action>

</intent-filter>
</receptor>
...

NOTAVocê também pode despejar o conteúdo deAndroidManifest.xmlcom um


comando usando o Androguardandroaxml.py.

Entre outros, há umreceptorElemento XML especificamente para o


com.yougetitback.androidapplication.SmsIntentReceiverclasse. Este parti-
A definição de receptor lar inclui umfiltro de intençãoElemento XML com um explícito
android: prioridadeelemento de999,visando oSMS_RECEIVEDação do
android.provider.Telephonyclasse. Ao especificar este atributo de prioridade, o
aplicativo garante que obterá oSMS_RECEIVEDdifundir primeiro e, assim, acessar as
mensagens SMS antes do aplicativo de mensagens padrão.
Conheça os métodos disponíveis emSmsIntentReceiverligando
get_methodsnaquela classe. Use um Python rápidoporloop para percorrer cada
método retornado, chamandoshow_infocada vez:
Em [178]: para metanfetamina em d.CLASS_Lcom_yougetitback_androidapplication_
SmsIntentReceiver.get_methods():
meth.show_info()
.....:
# # # # # # # # # # Informações do Método Lcom/yougetitback/androidapplication/
SmsIntentReceiver;-><init>()V [access_flags=public constructor]

# # # # # # # # # # Informações do Método Lcom/yougetitback/


androidapplication/SmsIntentReceiver;-
> foregroundUI(Landroid/content/Context;)V [access_flags=private]
# # # # # # # # # # Informações do Método Lcom/yougetitback/
androidapplication/SmsIntentReceiver;-
> getAction(Ljava/lang/String;)Ljava/lang/String; [access_flags=privado]
# # # # # # # # # # Informações do Método Lcom/yougetitback/
androidapplication/SmsIntentReceiver;-
Capítulo 4-Revisando a segurança do aplicativo 101

> getMessagesFromIntent(Landroid/content/Intent;) [Landroid/telefonia/


SmsMessage; [access_flags=private] Lcom/yougetitback/androidapplication/
SmsIntentReceiver;-
> processBackupMsg(Landroid/content/Context; Ljava/util/
Vector;)V [access_flags=private]
# # # # # # # # # # Informações do método Lcom/yougetitback/androidapplication/
SmsIntentReceiver;->onReceive (Landroid/content/Context; Landroid/content/Intent;)V
[access_flags=public] . . .

Para receptores de transmissão, oao receberserve como um ponto de entrada, para que você
possa procurar referências cruzadas ourefexpara resumir, a partir desse método para ter uma
ideia do fluxo de controle. Primeiro crie as refexs comd.create_xrefe depois ligue
show_xrefno objeto que representa oao recebermétodo:
Em [206]: d.create_xref()

Em [207]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver.
METHOD_onReceive.show_xref()
# # # # # # # # # # XREF
T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; isValidMessage (Ljava/lang/String;
Landroid/content/Context;)Z 6c T: Lcom/yougetitback/androidapplication/SmsIntentReceiver;
processContent (Landroid/content/Context; Ljava/lang/String;)V 78 T: Lcom/yougetitback/
androidapplication/SmsIntentReceiver; triggerAppLaunch (Landroid/conteúdo/Contexto; Landroid/
telefonia/SmsMessage;) V 9a

T: Lcom/yougetitback/androidapplication/SmsIntentReceiver;
getMessagesFromIntent (Landroid/content/Intent;) [Landroid/telefonia/
SmsMessage; 2a
T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; isPinLock (Ljava/lang/String;
Landroid/content/Context;)Z 8a
###################

Você viu issoao receberchama alguns outros métodos, incluindo aqueles que
parecem validar a mensagem SMS e analisar o conteúdo. Descompile e investigue
alguns deles, começando comgetMessageFromIntent:
Em [213]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver.
METHOD_getMessagesFromIntent.source()
private android.telephony.SmsMessage[]
getMessagesFromIntent(android.content.Intent p9)
{
v6 = 0;
v0 = p9.getExtras();
if (v0 != 0) {
v4 = v0.get("pdus");
v5 = new android.telephony.SmsMessage[v4.length]; v3 = 0;

while (v3 < v4.comprimento) {


v5[v3] = android.telephony.SmsMessage.createFromPdu(v4[v3]);
v3++;
102 Capítulo 4-Revisando a segurança do aplicativo

}
v6 = v5;
}
retornar v6;
}

Este é um código bastante típico para extrair um SMS Protocol Data Unit (PDU) de
um Intent. Você vê que o parâmetrop9para este método contém o objeto Intent.v0é
preenchido com o resultado dep9.getExtras,que inclui todos os objetos extras no
Intent. Próximo,v0.get("pdus")é chamado para extrair apenas a matriz de bytes da PDU,
que é colocada emv4. O método então cria umMensagem SMSobjeto dev4, atribui av5,
e faz um loop enquanto preenche membros dev5. Finalmente, no que pode parecer
uma abordagem estranha (provavelmente devido ao processo de descompilação),v6
também é atribuído comoMensagem SMSobjetov5, e retornou ao chamador.
Descompilando oao recebermétodo, você vê que antes de chamar
getMessagesFromIntent,um arquivo de preferências compartilhadas,SuperheroPrefsFile,é
carregado. Neste caso, op8objeto, representando o aplicativoContextoou estado,
temgetSharedPreferencesinvocado. Depois disso, alguns métodos adicionais são
chamados para garantir que a mensagem SMS seja válida (isValidMessage),e,
finalmente, o conteúdo da mensagem é processado (processoConteúdo),todos
parecem receber op8objeto como parâmetro. É provável queSuperheroPrefsFile
contém algo relevante para as operações a seguir, como uma chave ou PIN:
Em [3]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver.
METHOD_onReceive.source()
public void onReceive(android.content.Context p8,
android.content.Intent p9)
{
p8.getSharedPreferences("SuperheroPrefsFile", 0); if
(p9.getAction().equals("
android.provider.Telephony.SMS_RECEIVED") != 0) {
this.getMessagesFromIntent(p9); if (isto !=
0) {
v1 = 0;
while (v1 < this.length) {
if (this[v1] != 0) {
v2 = this[v1].getDisplayMessageBody(); if ((v2 != 0)
&& (v2.length() > 0)) {
android.util.Log.i("MessageListener:", v2);
this.isValidMessage(v2, p8);
if (isto == 0) {
this.isPinLock(v2, p8); if (isto !=
0) {
this.triggerAppLaunch(p8, this[v1]);
this.abortBroadcast();
}
} senão {
this.processContent(p8, v2);
this.abortBroadcast();
...
Capítulo 4-Revisando a segurança do aplicativo 103

Supondo que você queira construir uma mensagem SMS válida para ser processada
por este aplicativo, você provavelmente gostaria de dar uma olhada emisValidMessage,que
você vê no código anterior recebe uma string extraída da mensagem SMS via
getDisplayMessageBody,junto com o contexto atual do aplicativo. Descompilando
isValidMessagedá-lhe um pouco mais de visão sobre este aplicativo:
private boolean isValidMessage(String p12, android.content.Context p13)
{
v5 = p13.getString(1.82104701918e+38); v0 =
p13.getString(1,821047222e+38); v4 =
p13.getString(1.82104742483e+38); v3 =
p13.getString(1.82104762765e+38); v7 =
p13.getString(1.82104783048e+38); v1 =
p13.getString(1.8210480333e+38); v2 =
p13.getString(1.82104823612e+38); v6 =
p13.getString(1.82104864177e+38); v8 =
p13.getString(1.82104843895e+38);
this.getAction(p12);
if ((este.equals(v5) == 0) && ((este.equals(v4) == 0) && ((este.equals(v3) == 0)
&&
((this.equals(v0) == 0) && ((this.equals(v7) == 0) && ((this.equals(v6) == 0) &&
((this.equals(v2)) == 0) ) && ((este.igual(v8) == 0) && (este.igual(v1) == 0))))))))) {

v10 = 0;
} senão {
v10 = 1;
}
retornar v10;
}

Você vê muitas chamadas paragetStringque, agindo no contexto atual do aplicativo, recupera


o valor textual para o ID do recurso fornecido da tabela de strings do aplicativo, como os
encontrados emvalores/strings.xml.Observe, no entanto, que os IDs de recursos passados para
getStringparecer um pouco estranho. Este é um artefato dos problemas de propagação de tipo
de alguns descompiladores, com os quais você lidará momentaneamente. O método descrito
anteriormente é recuperar essas strings da tabela strings, comparando-as com a string emp12.
O método retorna1E sep12é correspondido, e
0se não for. De voltaao Receber,o resultado disso então determina seisPinLocké
chamado, ou seprocessContenté chamado. Dê uma olhadaisPinLock:
Em [173]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver.
METHOD_isPinLock.source()
booleano privado isPinLock(String p6, android.content.Context p7)
{
v2 = 0;
v0 = p7.getSharedPreferences("SuperheroPrefsFile", 0).getString ("pin", "");

if ((v0.compareTo("") != 0) && (p6.compareTo(v0) == 0)) {


v2 = 1;
}
retornar v2;
}
104 Capítulo 4-Revisando a segurança do aplicativo

A-há! O arquivo Shared Preferences aparece novamente. Este pequeno método chama
getStringpara obter o valor doalfineteentrada emSuperheroPrefsFile,e depois
compara isso comp6e retorna se a comparação foi verdadeira ou falsa. Se a
comparação fosse verdadeira,ao receberchamadastriggerAppLaunch.Descompilar
esse método pode aproximá-lo da compreensão de todo esse fluxo:
private void triggerAppLaunch(android.content.Context p9,
android.telephony.SmsMessage p10)
{
this.currentContext = p9;
v4 = p9.getSharedPreferences("SuperheroPrefsFile", 0); if
(v4.getBoolean("Ativado", 0) != 0) {
v1 = v4.edit();
v1.putBoolean("lockState", 1);
v1.putBoolean("smspinlock", 1);
v1.commit();
this.foregroundUI(p9);
v0 = p10.getOriginatingAddress();
v2 = new android.content.Intent("com.yougetitback.
androidapplication.FOREGROUND");
v2.setClass(p9, com.yougetitback.androidapplication.
FindLocationService);
v2.putExtra("LockSmsOriginator", v0);
p9.startService(v2);
this.startSiren(p9);
v3 = new android.content.Intent("com.yougetitback.
androidapplicationn.FOREGROUND");
v3.setClass(this.currentContext, com.yougetitback.
androidapplication.LockAcknowledgeService);
this.currentContext.startService(v3);
}

Aqui, as edições são feitas paraSuperheroPrefsFile,definindo alguns valores


booleanos para as teclas indicando se a tela está bloqueada e se isso foi feito via
SMS. Por fim, novos intents são criados para iniciar o aplicativoFindLocationServicee
LockAcknowledgeServiceserviços, ambos os quais você viu anteriormente ao listar
serviços. Você pode deixar de analisar esses serviços, pois pode fazer algumas
suposições sobre seus propósitos. Você ainda tem a questão de entender
a chamada paraprocessContentde voltaemReceber:
Em [613]: f = d.CLASS_Lcom_yougetitback_androidapplication_
SmsIntentReceiver.METHOD_processContent.source()
private void processContent(android.content.Context p16, String p17)
{
v6 = p16.getString(1.82104701918e+38); v1 =
p16.getString(1.821047222e+38); v5 =
p16.getString(1.82104742483e+38); v4 =
p16.getString(1.82104762765e+38); v8 =
p16.getString(1.82104783048e+38);
...
Capítulo 4-Revisando a segurança do aplicativo 105

v11 = this.split(p17);
v10 = v11.elementAt(0);
if (p16.getSharedPreferences("SuperheroPrefsFile",
0).getBoolean("Ativado", 0) == 0) {
if (v10.igual(v5) != 0) {
this.processActivationMsg(p16, v11);
}
} senão {
if ((v10.igual(v6) == 0) && ((v10.igual(v5) == 0) &&
((v10.equals(v4) == 0) && ((v10.equals(v8) == 0) && ((v10.equals(v7) ==
0) && ((v10.equals(v3)) == 0 ) && (v10.igual(v1) == 0))))))) {

v10.igual(v2);
}
if (v10.igual(v6) == 0) {
if (v10.igual(v9) == 0) {
if (v10.igual(v5) == 0) {
if (v10.igual(v4) == 0) {
if (v10.igual(v1) == 0) { if
(v10.igual(v8) == 0) {
if (v10.igual(v7) == 0) {
if (v10.igual(v3) == 0) {
if (v10.igual(v2) != 0) {
this.processDeactivateMsg(p16,
v11);
}
} senão {
this.processFindMsg(p16, v11); }

} senão {
this.processResyncMsg(p16, v11);
}
} senão {
this.processUnLockMsg(p16, v11);
}
...

Você vê chamadas semelhantes paragetStringcomo você fez emisValidMessage,


juntamente com uma série deE seinstruções que testam ainda mais o conteúdo do corpo
do SMS para determinar quais métodos chamar depois. De particular interesse é descobrir
o que é necessário para alcançarprocessUnLockMsg,que presumivelmente desbloqueia o
dispositivo. Antes disso, porém, há algunsdividirmétodo que é chamadop17, a string do
corpo da mensagem:

Em [1017]: d.CLASS_Lcom_yougetitback_androidapplication_
SmsIntentReceiver.METHOD_split.source()
java.util.Vector split(String p6)
{
v3 = new java.util.Vector(); v2 = 0;

Faz {
v1 = p6.indexOf(" ", v2);
106 Capítulo 4-Revisando a segurança do aplicativo

if (v1 < 0) {
v0 = p6.substring(v2);
} senão {
v0 = p6.substring(v2, v1);
}
v3.addElement(v0);
v2 = (v1 + 1);
} while(v1 != -1); retornar
v3;
}

Esse método bastante simples pega a mensagem e a divide em um Vector


(semelhante a um array) e retorna isso. De voltaprocessConteúdo,capinando através do
ninho deE sedeclarações, parece que o que está emv8é importante. No entanto, ainda
há o problema dos IDs de recursos. Tente desmontá-lo para ver se você tem mais
sorte:
Em [920]:
d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver.METHOD_processContent.show()
...
**********************************************************************
...
12 (00000036) const v13, 2131296282
13 (0000003c) move-object/from16 v0, v16
14 (00000040) invocar-virtual v0, v13,
Landroid/content/Context;->getString(I)Ljava/lang/String;
15 (00000046) mover-resultado-objeto v4
16 (00000048) const v13, 2131296283
17 (0000004e) move-object/from16 v0, v16
18 (00000052) invocar-virtual v0, v13,
Landroid/content/Context;->getString(I)Ljava/lang/String;
19 (00000058) mover-resultado-objeto v8
...

Você tem IDs de recursos numéricos agora. O inteiro2131296283corresponde a algo


entrando em seu registro de interesse,v8. Claro, você ainda precisa saber qual é o
valor textual real para esses IDs de recursos. Para encontrar esses valores, empregue
um pouco mais de Python dentroandróliseanalisando os recursos do APK:
aobj = a.get_android_resources() resid =
2131296283
pkg = aobj.packages.keys()[0] reskey =
aobj.get_id(pkg,resid)[1]
aobj.get_string(pkg,reskey)

O código Python primeiro cria umARSCParserobjeto,aobj, representando todos os recursos de


suporte para o APK, como strings, layouts de interface do usuário e assim por diante. Próximo,residir
contém o ID numérico do recurso no qual você está interessado. Em seguida, ele busca uma lista com
o nome/identificador do pacote usandoaobj.packages.keys,armazená-lo empacote. A chave de recurso
textual é então armazenada emredefinirligandoaobj.get_id,passandopacotee
residir.Finalmente, o valor da string deredefiniré resolvido usandoaobj.get_string.
Capítulo 4-Revisando a segurança do aplicativo 107

Por fim, esse snippet gera a string verdadeira queprocessContentresolvido-


YGIB: U.Por uma questão de brevidade, faça isso em uma linha, conforme mostrado aqui:

Em [25]: aobj.get_string(aobj.packages.keys()[0],aobj.get_id(aobj. packages.keys()


[0],2131296283)[1])

Fora[25]: [u'YGIB_UNLOCK', u'YGIB:U']

Neste momento, sabemos que a mensagem SMS precisará conter “YGIB:U” para
potencialmente alcançarprocessUnLockMsg.Olhe para esse método para ver se há mais
alguma coisa que você precisa:

Em [1015]: d.CLASS_Lcom_yougetitback_androidapplication_
SmsIntentReceiver.METHOD_processUnLockMsg.source() private void
processUnLockMsg(android.content.Context p16, java.util.Vector p17)

{
...
v9 = p16.getSharedPreferences("SuperheroPrefsFile", 0); if (p17.size() >= 2) {

v1 = p17.elementAt(1);
if (v9.getString("tagcode", "") == 0) {
android.util.Log.v("SWIPEWIPE",
"mensagem de desbloqueio recebida");
com.yougetitback.androidapplication.wipe.WipeController.
stopWipeService(p16);
v7 = new android.content.Intent("com.yougetitback.
aplicativo android.FUNDO");
v7.setClass(p16, com.yougetitback.androidapplication.
Serviço de Primeiro Plano);
p16.stopService(v7);
v10 = new android.content.Intent("com.yougetitback.
aplicativo android.FUNDO");
v10.setClass(p16, com.yougetitback.androidapplication.
SirenService);
p16.stopService(v10);
v9.editar();
v6 = v9.edit();
v6.putBoolean("lockState", 0);
v6.putString("lockid", ""); v6.commit();

v5 = new android.content.Intent("com.yougetitback.
androidapplication.FOREGROUND");
v5.setClass(p16, com.yougetitback.androidapplication.
UnlockAcknowledgeService);
p16.startService(v5);
}
}
Retorna;
}
108 Capítulo 4-Revisando a segurança do aplicativo

Desta vez você vê que uma chave chamadacódigo de etiquetaé puxado doSuperheroPrefsFile
arquivo e, em seguida, uma série de serviços é interrompida (e outra iniciada), que você pode
assumir que desbloqueia o telefone. Isso não parece certo, pois implicaria que, desde que essa
chave existisse no arquivo de preferências compartilhadas, ela seria avaliada como verdadeira -
provavelmente é um erro do descompilador, então vamos verificar a desmontagem com
bonito_show:

Em [1025]: d.CLASS_Lcom_yougetitback_androidapplication_
SmsIntentReceiver.METHOD_processUnLockMsg.pretty_show() . . .

12 (00000036) const-string v13, 'SuperheroPrefsFile' v14, 0


13 (0000003a) const/4
14 (0000003c) move-object/from16 v0, v16
15 (00000040) invocar-virtual v0, v13, v14,
Landroid/content/Context;->getSharedPreferences (Ljava/lang/String;
I)Landroid/content/SharedPreferences;
16 (00000046) mover-resultado-objeto v9
17 (00000048) const-string v1, ''
18 (0000004c) const-string v8, ''
19 (00000050) invocar-virtual/rangev17, Ljava/util/Vector;->
tamanho()I
20 (00000056) mover-resultado v13
21 (00000058) const/4 v14, 2
22 (0000005a) if-lt v13, v14, 122
[ processUnLockMsg-BB@0x5e processUnLockMsg-BB@0x14e ]

processUnLockMsg-BB@0x5e :
23 (0000005e) const/4 v13, 1
24 (00000060) move-object/from16 v0, v17
25 (00000064) invocar-virtual v0, v13,
Ljava/util/Vector;->elementAt(I)Ljava/lang/Object;
26 (0000006a) mover-resultado-objeto v1
27 (0000006c) check-cast v1, Ljava/lang/String;
28 (00000070) const-string v13, 'tagcode'
29 (00000074) const-string v14, ''
30 (00000078) interface de invocação v9, v13, v14,
Landroid/content/SharedPreferences;->getString( Ljava/lang/
String; Ljava/lang/String;) Ljava/lang/String;

31 (0000007e) mover-resultado-objeto v13


32 (00000080) invocar-virtual v15, v1,
Lcom/yougetitback/androidapplication/
SmsIntentReceiver;->EvaluateToken( Ljava/lang/
String;)Ljava/lang/String;
33 (00000086) mover-resultado-objeto v14
34 (00000088) invocar-virtual v13, v14, Ljava/lang/String;-
> compareTo(Ljava/lang/String;)I 35
(0000008e) move-result 36 v13
(00000090) if-nez v13, 95 [ processUnLockMsg-BB@
0x94 processUnLockMsg-BB@0x14e ]
Capítulo 4-Revisando a segurança do aplicativo 109

processUnLockMsg-BB@0x94 :
37 (00000094) const-string 38 v13, 'SWIPEWIPE'
(00000098) const-string 39 v14, 'mensagem de desbloqueio
(0000009c) invocar-estático recebida' v13, v14, Landroid/util/Log;-
> v(Ljava/lang/String; Ljava/lang/String;)I 40 (000000a2) invoke-static/range
v16, Lcom/yougetitback/androidapplication/wipe/WipeController;

- > stopWipeService(Landroid/content/Context;)V
[ processUnLockMsg-BB@0xa8 ]
...

Isso esclarece - o valor do segundo elemento do vetor passado é passado para


AvaliarToken,e então o valor de retorno é comparado ao valor docódigo de etiquetakey no
arquivo de preferências compartilhadas. Se esses dois valores corresponderem, o método
continuará como você viu anteriormente. Com isso, você deve perceber que sua
mensagem SMS precisará ser efetivamente algo comoYGIB:Useguido por um espaço e o
código de etiquetavalor. Em um dispositivo com root, recuperar esse código de tag seria
bastante fácil, pois você poderia apenas ler oSuperheroPrefsFilediretamente do sistema de
arquivos. No entanto, tente fazer algumas abordagens dinâmicas e veja se você consegue
mais alguma coisa.

Análise dinâmica
A análise dinâmica envolve a execução do aplicativo, normalmente de forma instrumentada ou
monitorada, para obter informações mais concretas sobre seu comportamento. Isso
geralmente envolve tarefas como verificar os artefatos que o aplicativo deixa no sistema de
arquivos, observar o tráfego de rede, monitorar o comportamento do processo... todas as
coisas que ocorrem durante a execução. A análise dinâmica é ótima para verificar suposições ou
testar hipóteses.
As primeiras coisas a serem abordadas de um ponto de vista dinâmico são entender
como um usuário interagiria com o aplicativo. Qual é o fluxo de trabalho? Quais menus,
telas e painéis de configurações existem? Muito disso pode ser descoberto por meio de
análise estática – por exemplo, as atividades são facilmente identificáveis. No entanto,
entrar nos detalhes de sua funcionalidade pode ser demorado. Muitas vezes, é mais fácil
interagir diretamente com o aplicativo em execução.
Se você acenderlogcatao iniciar o aplicativo, você vê alguns nomes de atividades
familiares à medida que o ActivityManager gira o aplicativo:
I/ActivityManager( 245): START {act=android.intent.action.MAIN
cat=[android.intent.category.LAUNCHER] flg=0x10200000
cmp=com.yougetitback.androidapplication.virgin.mobile/ com.yougetitback.androidapplication.
ActivateSplashScreen u=0} do pid 449 I/ActivityManager( 245): Iniciar proc

com.yougetitback.androidapplication.virgin.mobile para atividade


com.yougetitback.androidapplication.virgin.mobile/
com.yougetitback.androidapplication.ActivateSplashScreen: pid=2252 uid=10080
gids={1006, 3003, 1015, 1028}
110 Capítulo 4-Revisando a segurança do aplicativo

Primeiro você ateSplashScreen),como observado através


Androguarda Você vê a tela principal na Figura 4-5.

Figura 4-5:Tela inicial/atividade principal

Movendo-se um pouco mais pelo aplicativo, você verá prompts para um PIN e uma pergunta de
segurança, conforme mostrado na Figura 4-6. Depois de fornecer essas informações, você verá uma
saída notável emlogcat.
Teste D/YGIB (2252): Contexto de—
> com.yougetitback.androidapplication.virgin.mobile I/
RequestConfigurationService( 2252): RequestConfigurationService criado!!!

D/REQUESTCONFIGURATIONSERVICE( 2252): onStartCommand I/


ActivationAcknowledgeService( 2252): RequestConfigurationService criado!!!

I/RequestConfigurationService( 2252): RequestConfigurationService parado!!!

I/PingService( 2252): PingService criado!!! D/PINGSERVICE( 2252): onStartCommand I/


ActivationAcknowledgeService( 2252): RequestConfigurationService parado!!!

I/PingService( 2252): RequestEtagService parou!!! D/C2DMReceiver( 2252): A ação é


com.google.android.c2dm.intent. CADASTRO

I/intent dizendo algo (2252): == null ===null === Intent


{ act=com.google.android.c2dm.intent.REGISTRATION flg=0x10
pkg=com.yougetitback.androidapplication.virgin.mobile
Capítulo 4-Revisando a segurança do aplicativo 111

cmp=com.yougetitback.androidapp
lication.virgin.mobile/
com.yougetitback.androidapplication.C2DMReceiver (tem extras) } I/Activity

{cmp=com.y on.virgin.mobile/
com.youget difyPinScreen u=0} do pid 2252
...

Figura 4-6:Tela de entrada de PIN e perguntas de segurança

Com certeza, há chamadas sendo registradas para iniciar e interromper alguns dos serviços
observados anteriormente, juntamente com nomes de atividades familiares. Mais abaixo no log, no
entanto, você vê um vazamento de informações interessante:

D/atualizar ( 2252): serverUrl-->https://virgin.yougetitback.com/ ( 2252): settingsUrl--


D/atualizar >vaultUpdateSettings?
D/atualizar (2252): senha-->3f679195148a1960f66913d09e76fca8dd31dc96 (2252): tagCode--
D/atualizar >137223048617183
D/atualizar ( 2252): codificadoXmlData—
>
%3c%3fxml%20version%3d'1.0'%20encoding%3d'UTF-8'%3f%3e%3cConfig%3e%3cSettings%3e%3cPin%3e1234%3c
%2fPin%3e%3c%2fSettings%3e% 3c%2fConfig%3e
...
Teste D/YGIB( 2252): con.getResponseCode()-->200 Teste D/
YGIB( 2252): urlString—
> https://virgin.yougetitback.com/vaultUpdateSettings?pword=
3f679195148a1960f66913d09e76fca8dd31dc96&tagid=137223048617183&type=S
112 Capítulo 4-Revisando a segurança do aplicativo

Teste D/YGIB( 2512): conteúdo-->%3c%3fxml%20version%3d'1.0'%20encoding%3d'


UTF-8'%3f%3e%3cConfig%3e%3cSettings%3e%3cPin%3e1234%3c %2fPin
%3e%3c%2fSettings%3e%3c%2fConfig%3e

Mesmo nas primeiras etapas do fluxo de trabalho deste aplicativo, ele já


vaza dados de sessão e configuração, incluindo o que poderia ser o
código de etiquetavocê
estava olhando durante a análise estática. Brincar e salvar as
configurações no aplicativo também produz uma saída semelhantemente detalhada
no buffer de log:
D/atualizar ( 2252): serverUrl-->https://virgin.yougetitback.com/ ( 2252): settingsUrl--
D/atualizar >vaultUpdateSettings?
D/atualizar (2252): senha-->3f679195148a1960f66913d09e76fca8dd31dc96 (2252): tagCode--
D/atualizar >137223048617183
D/atualizar ( 2252): codificadoXmlData—
>
%3c%3fxml%20version%3d'1.0'%20encoding%3d'UTF-8'%3f%3e%3cConfig%3e%3cSettings%3e%3cServerNo%3e+447781482187%3c%2fServerNo%3e%
3cServerURL%3ehttps: %2f%2fvirgin.yougetitback.com%2f%3c%2fServerURL%3e%3cURL de
backup%3eContatosSalvar%3f%3c%2fURL de
backup%3e%3cMessageURL%3ecallMainETagUSA%3f%3c%2f
MessageURL%3e%3cFindURL%3eFind%3f%3c%2fFindURL%3e%3cExtBackupURL% 3eextContactsS
ave%3f%3c%2fExtBackupURL%3e%3cRestoreURL%3erestorecontacts%3f%3c%2fRestoreURL%3
e%3cCallCentre%3e+442033222955%3c%2fCallCentre%3e%3cCountryCode%3eGB%3c%2fCount
ryCode%3e%3cPin %3c%2fPin%3e%3cURLPassword%3e3f679195148a1960f66913d09e76
fca8dd31dc96%3c%2fURLPassword%3e%3cRoamingLock%3eoff%3c%2fRoamingLock%3e%3cSimL
ock%3eon%3c%2fSimLock%3e%3cOfflineLock%3eoff%3c%2fOfflineLock%3e%3cAutolock
%20interval%3d%220%22%3eoff%3c%2fAutolock%3e%3cCallPatternLock%20OutsideCalls%3d%22
6%22%20Numcalls%3d%226%22%3eon%3c%2fCallPatternLock%3e%3cCountryLock%3eoff%3c %2
fPaísBloqueio%3e%3c%2fConfigurações%3e%3cPaísPrefixo%3e%3cPrefixo%3e+44%3c%2fPrefixo%3e%3c%2fCountryPrefix%3e%3cIntPrefix%3e%3cInter

Conforme mencionado anteriormente, essas informações seriam acessíveis por um


aplicativo com oREAD_LOGSpermissão (antes do Android 4.1). Embora esse vazamento específico
possa ser suficiente para atingir o objetivo de criar o SMS especial, você deve obter um pouco
mais de informações sobre como esse aplicativo é executado. Para isso você usa um depurador
chamadoAndBug.
O AndBug se conecta a terminais Java Debug Wire Protocol (JDWP), que o Android
Debugging Bridge (ADB) expõe para processos de aplicativos marcados explicitamente
comandroid:depurável=trueem seu manifesto ou para todos os processos do aplicativo se o
ro.depurávelpropriedade está definida para1 (normalmente definido para0em dispositivos
de produção). Além de verificar o manifesto, executaradb jdwpmostrar PIDs depuráveis.
Supondo que o aplicativo de destino seja depurável, você verá a saída da seguinte forma:

$ adb jdwp
2252

Usandogreppara procurar esses mapas PID de acordo com nosso processo de destino (também
visto nos logs mostrados anteriormente):

$ adb shell ps | grep 2252


u0_a79 2252 88 289584 36284 ffffffff 00000000 S
com.yougetitback.androidapplication.virgin.mobile
Capítulo 4-Revisando a segurança do aplicativo 113

Depois de obter essas informações, você pode anexar o AndBug ao dispositivo de


destino e processar e obter um shell interativo. Use oConchacomando e especifique o PID
de destino:

$ e shell de bug -p 2252

# # AndBug (C) 2011 Scott W. Dunlop < swdunlop@gmail.com >


>>

Usando oAulascomando, junto com um nome de classe parcial, você pode ver quais
classes existem nocom.yougetitbacknamespace. Em seguida, usando ométodos
comando, descubra os métodos em uma determinada classe:

> > classes com.yougetitback


# # Aulas Carregadas
- - com.yougetitback.androidaapplication.
PinDisplayScreen$XMLParserHandler
- - com.yougetitback.androidapplication.settings.main.Entrance$1
...
- - com.yougetitback.androidaapplication.
PinDisplayScreen$PinDisplayScreenTransmissão
- - com.yougetitback.androidapplication.SmsIntentReceiver
- - com.yougetitback.androidapplication.C2DMReceiver
- - com.yougetitback.androidapplication.settings.setting.Setting
...
> > métodos com.yougetitback.androidapplication.SmsIntentReceiver
# # Métodos Lcom/yougetitback/androidapplication/SmsIntentReceiver;
- - com.yougetitback.androidapplication.SmsIntentReceiver.<init>()V
- - com.yougetitback.androidapplication.SmsIntentReceiver.
foregroundUI(Landroid/content/Context;)V
- - com.yougetitback.androidapplication.SmsIntentReceiver.
getAction(Ljava/lang/String;)Ljava/lang/String;
- - com.yougetitback.androidapplication.SmsIntentReceiver.
getMessagesFromIntent(Landroid/content/Intent;)[Landroid/telefonia/SmsMessage;

- - com.yougetitback.androidapplication.SmsIntentReceiver.
isPinLock(Ljava/lang/String;Landroid/content/Context;)Z
- - com.yougetitback.androidapplication.SmsIntentReceiver.
isValidMessage(Ljava/lang/String;Landroid/content/Context;)Z . . .

- - com.yougetitback.androidapplication.SmsIntentReceiver.
processUnLockMsg(Landroid/content/Context;Ljava/util/Vector;)V

No código anterior, você vê a classe que estava analisando e revertendo estaticamente


anteriormente:SmsIntentReceiver,juntamente com os métodos de interesse. Agora você
pode rastrear métodos e seus argumentos e dados. Comece traçando o
SmsIntentReceiverclasse, usando orastreamento de classecomando no AndBug e, em seguida,
enviar ao dispositivo uma mensagem SMS de teste com o textoMensagem de teste:

> > class-trace com.yougetitback.androidapplication.SmsIntentReceiver


# # Configurando Ganchos
- - Hooked com.yougetitback.androidapplication.SmsIntentReceiver
...
114 Capítulo 4-Revisando a segurança do aplicativo

com.yougetitback.androidapplication.SmsIntentReceiver

> > # # trace thread <1> main (corrida suspensa)


- - com.yougetitback.androidapplication.SmsIntentReceiver.<init>()V:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830009571568>
...
# # trace thread <1> main (corrida suspensa)
- - com.yougetitback.androidapplication.SmsIntentReceiver.onReceive(
Landroid/conteúdo/Contexto;Landroid/conteúdo/Intenção;)V:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830009571568>
- - intenção=Landroid/conteúdo/Intenção; <830009581024>
...
# # trace thread <1> main (corrida suspensa)
- - com.yougetitback.androidapplication.SmsIntentReceiver.
getMessagesFromIntent(Landroid/content/Intent;) [Landroid/
telefonia/SmsMessage;:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830009571568>
- - intenção=Landroid/conteúdo/Intenção; <830009581024>
...
- - com.yougetitback.androidapplication.SmsIntentReceiver.
isValidMessage(Ljava/lang/String;Landroid/content/Context;)Z:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830009571568>
- - msg=Mensagem de teste
- - context=Landroid/app/ReceiverRestrictedContext; <830007895400>
...

Assim que a mensagem SMS chega, transmitida do subsistema de telefonia, seu


gancho é acionado e você começa a rastrear a partir doao recebermétodo e além. Você vê a
mensagem de intenção que foi passada paraao Receber,bem como as mensagens
subsequentes e familiares chamadas posteriormente. Há também omensagemvariável em
isValidMessage,contendo nosso texto SMS. À parte, olhando para trás,logcat
output, você também vê o corpo da mensagem sendo registrado:

I/MessageListener:( 2252): Mensagem de teste

Um pouco mais abaixo no rastreamento de classe, você vê uma chamada paraisValidMessage,


incluindo umContextoobjeto sendo passado como um argumento - e um conjunto de campos
nesse objeto que, neste caso, mapeia para recursos e strings extraídos da tabela de strings (que
você resolveu manualmente anteriormente). Entre eles está oYGIB:Uvalor que você viu
anteriormente e uma chave correspondenteYGIBUNLOCK.Relembrando sua análise estática desse
método, o corpo da mensagem SMS está sendo verificado quanto a esses valores, chamando
isPinLockse eles não estiverem presentes, como mostrado aqui:

# # trace thread <1> main (corrida suspensa)


- - com.yougetitback.androidapplication.SmsIntentReceiver.getAction(
Ljava/lang/String;)Ljava/lang/String;:0
Capítulo 4-Revisando a segurança do aplicativo 115

- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830007979232>
- - mensagem=Foobarbaz
- - com.yougetitback.androidapplication.SmsIntentReceiver.
isValidMessage(Ljava/lang/String;Landroid/content/Context;)Z:63
- - YGIBDEACTIVATE=YGIB:D
- - YGIBFIND=YGIB:F
- - context=Landroid/app/ReceiverRestrictedContext; <830007987072>
- - YGIBUNLOCK=YGIB:U
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830007979232>
- - YGIBBACKUP=YGIB:B
- - YGIBRESYNC=YGIB:RS
- - YGIBLOCK=YGIB:L
- - YGIBWIPE=YGIB:W
- - YGIBRESTORE=YGIB:E
- - msg=Foobarbaz
- - YGIBREGFROM=YGIB:T
...
# # trace thread <1> main (corrida suspensa)
- - com.yougetitback.androidapplication.SmsIntentReceiver.isPinLock(
Ljava/lang/String;Landroid/content/Context;)Z:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830007979232>
- - msg=Foobarbaz
- - context=Landroid/app/ReceiverRestrictedContext; <830007987072>
...

Nesse casoisPinLockentão avalia a mensagem, mas a mensagem SMS não contém o


PIN nem uma dessas strings (comoYGIB: U).O aplicativo não faz nada com este SMS e,
em vez disso, o repassa para o próximo Broadcast Receiver registrado na cadeia. Se
você enviar uma mensagem SMS com oYGIB:Uvalor, você provavelmente verá um
comportamento diferente:
# # trace thread <1> main (corrida suspensa)
- - com.yougetitback.androidapplication.SmsIntentReceiver.
processContent(Landroid/conteúdo/Contexto;Ljava/lang/String;)V:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830008303000>
- - m=YGIB:U
- - context=Landroid/app/ReceiverRestrictedContext; <830007987072>
...
# # trace thread <1> main (corrida suspensa)
- - com.yougetitback.androidapplication.SmsIntentReceiver.
processUnLockMsg(Landroid/content/Context;Ljava/util/Vector;)V:0
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830008303000>
- - smsTokens=Ljava/util/Vector; <830008239000>
- - context=Landroid/app/ReceiverRestrictedContext; <830007987072>
- - com.yougetitback.androidapplication.SmsIntentReceiver.
116 Capítulo 4-Revisando a segurança do aplicativo

processContent(Landroid/conteúdo/Contexto;Ljava/lang/String;)V:232
- - YGIBDEACTIVATE=YGIB:D
- - YGIBFIND=YGIB:F
- - context=Landroid/app/ReceiverRestrictedContext; <830007987072>
- - YGIBUNLOCK=YGIB:U
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830008303000>
- - configurações=Landroid/app/ContextImpl$SharedPreferencesImpl;
<830007888144>
- - m=YGIB:U
- - YGIBBACKUP=YGIB:B
- - YGIBRESYNC=YGIB:RS
- - YGIBLOCK=YGIB:L
- - messageTokens=Ljava/util/Vector; <830008239000>
- - YGIBWIPE=YGIB:W
- - YGIBRESTORE=YGIB:E
- - comando=YGIB:U
- - YGIBREGFROM=YGIB:T

Desta vez, você acabou acertando tanto oprocessContentmétodo e, posteriormente, o


processUnLockMsgmétodo, como você queria. Você pode definir um ponto de interrupção
noprocessUnLockMsgmétodo, dando a oportunidade de inspecioná-lo um pouco mais
detalhadamente. Você faz isso usando o AndBug'spararcomando e passe a classe e o
nome do método como argumentos:
> > break com.yougetitback.androidapplication.SmsIntentReceiver
processUnLockMsg
# # Configurando Ganchos
- - Hooked <536870913> com.yougetitback.androidapplication.
SmsIntentReceiver.processUnLockMsg(Landroid/content/Context; Ljava/util/
Vector;)V:0 <class 'andbug.vm.Location'>
> > # # Ponto de interrupção atingido no thread <1> principal (execução suspensa), processo
suspenso.
- - com.yougetitback.androidapplication.SmsIntentReceiver.
processUnLockMsg(Landroid/content/Context;Ljava/util/Vector;)V:0
- - com.yougetitback.androidapplication.SmsIntentReceiver.
processContent(Landroid/conteúdo/Contexto;Ljava/lang/String;)V:232
- - com.yougetitback.androidapplication.SmsIntentReceiver.
onReceive(Landroid/conteúdo/Contexto;Landroid/conteúdo/Intenção;)V:60
--
...

Você sabe pela análise anterior quegetStringserá chamado para recuperar algum
valor do arquivo Shared Preferences, então adicione umrastreamento de classeno
android.content.SharedPreferencesclasse. Em seguida, retome o processo com
aretomarcomando:
> > ct android.content.SharedPreferences
# # Configurando Ganchos
- - android.content.SharedPreferences enganchado
> > currículo
Capítulo 4-Revisando a segurança do aplicativo 117

NOTAExecutar um rastreamento de método ou definir um ponto de interrupção diretamente em determinados


métodos pode resultar em bloqueio e morte do processo, por isso você está apenas rastreando a classe inteira.

Além disso, oretomarcomando pode precisar ser executado duas vezes.

Depois que o processo for retomado, a saída será bastante detalhada (como
antes). Percorrendo mais uma vez a pilha de chamadas, você acabará chegando ao
getStringmétodo:

# # Processo retomado
> > # # trace thread <1> main (corrida suspensa)
...
# # trace thread <1> main (corrida suspensa)
- - android.app.SharedPreferencesImpl.getString(Ljava/lang/String;
Ljava/lang/String;)Ljava/lang/String;:0
- - this=Landroid/app/SharedPreferencesImpl; <830042611544>
- - defValue=
- - key=tagcode
- - com.yougetitback.androidapplication.SmsIntentReceiver.
processUnLockMsg(Landroid/content/Context;Ljava/util/Vector;)V:60
- - smsTokens=Ljava/util/Vector; <830042967248>
- - configurações=Landroid/app/SharedPreferencesImpl; <830042611544>
- - this=Lcom/yougetitback/androidapplication/SmsIntentReceiver;
<830042981888>
- - TIPOLOCO=L
- - YGIBTAG=TAG:
- - TAG=AAAA
- - YGIBTYPE=TYPE:
- - context=Landroid/app/ReceiverRestrictedContext; <830042704872>
- - configuração=
...

E aí está, a chave de Preferências Compartilhadas que você estava procurando:código de etiqueta,


confirmando ainda mais o que você identificou estaticamente. Isso também corresponde a parte de
uma mensagem de log que vazou anteriormente, em quecódigo da etiquetafoi seguido por uma string
numérica. De posse dessas informações, você sabe que nossa mensagem SMS, na verdade, precisa
conterYGIB:Useguido por um espaço e umcódigo de etiqueta
valor, ou neste caso,YGIB: U 137223048617183.

Ataque

Embora você pudesse simplesmente enviar sua mensagem SMS especialmente criada
para o dispositivo de destino, você ainda estaria sem sorte em simplesmente saber o
código de etiquetavalor se for diferente para algum outro dispositivo, talvez arbitrário (o que
é praticamente garantido). Para esse fim, você deseja aproveitar o valor vazado no log,
que pode ser obtido em seu aplicativo de prova de conceito solicitando o
READ_LOGSpermissão.

Você também pode gostar