miércoles, 23 de abril de 2014

Depurar malware Android con Eclipse

Sí, habéis entendido correctamente: depurar malware para Android con el IDE Eclipse. Normalmente Eclipse se usa para desarrollar aplicaciones como Android, no para depurar aplicaciones compiladas. Con el depurador/desensamblador IDA se puede ver el código Dalvik de una aplicación Android, pero no se puede depurar una aplicación a ese nivel. También existen herramientas para transformar las aplicaciones Android en jar, con dex2jar por ejemplo y luego decompilarlos. Sin embargo, la decompilación no se hace correctamente, especialmente con los bucles. Como a veces el atacante ofusca su código, la ingeniería inversa es más difícil. Entonces, necesitamos de una herramienta para depurar la aplicación ofuscada.

En un foro ruso, hemos descubierto una manera de depurar las aplicaciones Android desensamblando el código Dalvik. Usaba la herramienta apktool para desensamblar las aplicaciones Android y  el IDE Netbeans 6.8 para depurar. Esta técnica fue mejorada y adaptada para la nueva versión de Eclipse. En esta entrada del blog, me gustaría compartir ésta técnica, que consideramos merece la pena.

Como ejemplo, usaremos una aplicación que hemos desarrollado llamada SilentSMS y que tiene el nombre de paquete "com.example.silentsms". Admitimos que el usuario tiene la configuración para desarrollar aplicaciones Android con Eclipse, es decir el emulador Android, DDMS para depurar, etc.

El primer paso consiste en desensamblar el APK en código Dalvik para modificar la aplicación y hacerla depurable. Para ello, usamos la herramienta Apktool 2.0 beta. Después del desensamblado, localizamos el archivo "AndroidManifest.xml" que nos permite saber cual es la primera parte del programa interpretada y también nos permite hacer la aplicación depurable. Para ello, añadimos la bandera android:debuggable a "true" a la etiqueta "application". También, nos permite saber que la primera parte del código interpretado se encuentra en la clase "com/example/silentsms/MainActivity".










Sin embargo, haciendo la aplicación depurable no permite a la aplicación esperar a un depurador. Es decir, al ejecutar la aplicación, no podríamos depurar al comienzo. Para forzar a que la aplicación espere al depurador, añadimos la instrucción "invoke-static {}, Landroid/os/Debug;->waitForDebugger()V". Es importante no olvidar el "a = 0;//" delante de ésta instrucción.









¿Por qué añadir un código delante? La razón es que cuando vamos a importar el proyecto desensamblado en Eclipse, no podríamos depurarlo por culpa de los errores de sintaxis generados por Eclipse. Es decir, Eclipse no sabe analizar sintácticamente el código Dalvik. Para evitar esto, comentamos el código Dalvik y ponemos una instrucción. En nuestro caso, incluimos la variable "a" puesta a 0 en cada línea. En otras palabras, Eclipse verá solo las instrucciones "a = 0", mientras que nosotros veremos el código Dalvik correspondiente a esta línea. De manera más macroscópica, la clase se asemeja a:

package com.example.silentsms; class MainActivity {void a() { int a;
a = 0; //  
.
.
.
}}

En otras palabras, el código Java es correcto y no genera ningún error.

El segundo paso consiste en ensamblar de nuevo la aplicación y firmarla. Para firmar la aplicación, necesitamos una llave. Usaremos la llave del Android SDK que se encuentra en la carpeta ".android" de la carpeta home del usuario en Linux. Para ensamblar de nuevo la aplicación usamos:

java -jar apktool _2.0.0b7.jar b -d out -o debug.apk

Mientras que para firmar la aplicación empleamos:

jarsigner -verbose -digestalg SHA1 -sigalg MD5withRSA -keystore 

debug.keystore debug.apk androiddebugkey

El tercer paso consiste en importar el proyecto desensamblado y depurarlo en Eclipse. Para eso, creamos un nuevo proyecto Java e importamos el proyecto desensamblado. Después ejecutamos la aplicación Android en el emulador. Cambiando la vista en DDMS, podemos ver la lista de procesos ejecutándose así como las listas de procesos esperando un depurador indicado por el icono rojo al lado. Para añadir esos procesos, podemos conectar un depurador en remoto sobre los puertos [8609-8700]. 


Para que Eclipse se conecte a nuestro proceso, necesitamos configurar el depurador. Para eso, accedemos a "Run->Debug Configurations", y luego pulsamos "Remote Java Application". Configuramos el puerto para que el depurador se conecte al proceso correcto. En nuestro caso, elegimos el puerto 8609.


Antes de pulsar el botón "Debug", necesitamos poner un "breakpoint" justo donde queremos para el depurador. En nuestro caso, queremos pararlo justo cuando llama a la función "onCreate".



Depurando el proceso,  Eclipse nos propone cambiar de perspectiva.
















Finalmente, podemos depurar la aplicación (step over, step into, etc.) como si fuera una aplicación Android desarrollada por nosotros. 




















Hemos visto como usar Eclipse para depurar aplicaciones Android a nivel de código Dalvik, lo que incluso nos permite hacer ingeniería inversa de las aplicaciones ofuscadas. Es decir: desensamblar una aplicación Android, hacerla depurable, reensamblarla, importarla en Eclipse y depurarla. Sin embargo, no podemos depurar las bibliotecas compiladas en código nativo (por procesorses ARM, Intel por ejemplo). Para eso, necesitamos usar otro depurador como IDA.

Más información:

Отладка приложений для Android без исходного кода на Java

Programering, Marzo 2014
Aptkool 2.0, 2014

Eclipse, 2014


Laurent Delosières



miércoles, 12 de marzo de 2014

Anuncios en moviles para hacer creer que estamos infectados

Dentro de las familias de malware, conocemos los "scamware" que te avisan que tu sistema esta infectado con malware y te proponen un antivirus gratuito que es en realidad un malware. Pero también se usan los anuncios en páginas legítimas con el objeto de instalarnos una aplicación maliciosa. Vamos a analizar un caso reciente que hemos encontrado para Android .

La semana pasada mirando un periódico francés muy famoso, se mostró un "popup" en mi pantalla recomendándome instalar un "cleaner" para limpiar mi móvil. La primera vez el popup estaba en inglés, tras pulsar el botón "Cancelar" se mostró el mismo popup pero esta vez en español (curiosamente no en francés).


Quizás pensaban que no entendía el ingles y que con el español tendrían más éxito. Pero no quería instalar este software. Al pulsar "Cancelar", automáticamente me redireccionó a otra pagina con una ventana que quería aparentar un mensaje de aviso de Android OS como la siguiente:


Parece que esperaba tener más éxito imitando la interfaz grafica de Android OS, para hacer creer al usuario que realmente está infectado. Al pulsar sobre cualquier parte del mensaje, redireccionaba a GooglePlay.
  

Vamos a analizar como hemos llegado a Google Play desde el periódico francés. Cuando el navegador de Android carga la pagina del periódico descarga un anuncio con la petición HTTP siguiente:

GET /ttj?
id=1028520&size=1000x300&promo_sizes=970x250,1000x90,970x90,728x90&promo_alignment=center&referrer=pagina.fr&cb=7741390030&pt1=http://ww14.smartadserver.com/call/pubj/252/82917/225/S/9665235358/origine%3Dasq? HTTP/1.1
Host: ib.adnxs.com
Referer: http://www.pagina.fr/

Vemos que recoge el anuncio del sitio web "ib.adnxs.com" para recibir el anuncio de otro servidor "http://ww14.smartadserver.com/call/pubj/252/82917/225/S/9665235358/origine%3Dasq?". El servidor responde con un código JavaScript ofuscado:

document.write('<a id=\"banner\" target=\"_blank\" href=\"http://fra1.ib.adnxs.com/click?Z2ZmZmZm2j8TYcPTK-XYPwAAAAAAAPA_E2HD0yvl2D9mZmZmZmbaP0LmHtvClCBBSI_mp8QbEgiuixlTAAAAAKixDwBIBgAAmQcAAAIAAAA9L8UA-8YCAAAAAQBVU0QARVVSANgCWgDVjlUFyYwAAgUCAQUAAIoAayUAdgAAAAA./cnd=%21aQaHPQin5MQBEL3elAYY-40LIAA./referrer=pagina.fr/clickenc=http%3A%2F%2Fsofcotrk.com%2Fmt%2Fv2b4x234d4t233s244u2u2%2F%26subid1%3Dfra1CMiemr_K-IaJCBACGMLM-9itmKWQQSINNjIuMTUuMjMwLjE2NCgBMK6X5pgF\"><img src=\"http://cdn.adnxs.com/p/b7/ed/ba/90/b7edba903816d39881e9db7acabab42b.jpeg\" border=\"0\" /></a>\r\n<scr'+'ipt type=\"text/javascript\">eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!\'\'.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return\'\\\\w+\'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp(\'\\\\b\'+e(c)+\'\\\\b\',\'g\'),k[c])}}return p}(\'5 2=[\"g\",\"f\",\"h\",\"i\"],7=j.e.c(),4=9;8(5 d=0;d<2.a;d++){3(7.b(2[d])!=-1){4=l}}3(4){3(y(\"6 u t 8 o n m 6 p!\")){q.s.r=v.x(\"k\").w}}\',35,35,\'||mobiles|if|ismobile|var|Clean|uagent|for|false|length|indexOf|toLowerCase||userAgent|ipod|iphone|ipad|android|navigator|banner|true|with|now|FREE|Master|window|location|top|Android|your|document|href|getElementById|confirm\'.split(\'|\'),0,{}));</scr'+'ipt>\r\n    ');document.write('<scr'+'ipt type="text/javascript" src="http://pixel.alephd.com/post_asq?LgDc=&L4DK=285147&rZzC=&aNVl=1&ZzpC=&Dsph=&Hsyz=440&0ZGY=12922685&Xyes=&iK5S=&b6lE=0.1385&-tgi=-1&wziz=1&vKcZ=4692914376340858434&2jSB=0.4125&-Zu8=8613&e9iH=581557833328660296&b5ho=class_1&GAa8=1028520&DH5k=62.15.230.164&8rSZ=&-Z06=0.4125"></scr'+'ipt>');document.write('<scr' + 'ipt src="http://cdn.adnxs.com/ANX_async_usersync.js"></scr'+'ipt>');

Con http://jsunpack.com/, hemos descifrado la función siguiente. Dentro de la página del anuncio, hay un código JavaScript que busca la presencia de la cadena "android" en el "user-agent". El "user-agent" forma parte de las peticiones http y permite identificar el navegador del usuario (incluyendo versión y sistema operativo) para que el servidor muestre las paginas mas adecuadas para él. El anuncio se sirve de esto mismo para comprobar si el usuario visita la pagina con un dispositivo Android. En tal caso, se muestra automáticamente un "popup" con el mensaje en ingles "Clean your Android for FREE now with Clean Master!". Si el usuario está de acuerdo, se le redirecciona a Google Play.

Mostramos el código desofuscado:

href = “http://fra1.ib.adnxs.com/click?...”
var mobiles=["iphone","ipod","ipad","android"],
uagent=navigator.userAgent.toLowerCase(),
ismobile=false;
for(var d=0;d<mobiles.length;d++){
   if(uagent.indexOf(mobiles[d])!=-1)
   {
      ismobile=true
   }
}

if(ismobile)
{
   if(confirm("Clean your Android for FREE now with Clean Master!"))
   {
      window.top.location=document.getElementById("banner").href
   }
}

En caso contrario, la página web hace una nueva petición HTTP al servidor de anuncios:

GET /ttj?
id=1028475&size=300x1050&promo_sizes=300x1000,300x900,300x600,300x250&promo_alignment=center&referrer=pagina.fr&cb=7296786274&pt1=http://ww14.smartadserver.com/call/pubj/252/82917/163/S/9665235358/origine%3Dasq? HTTP/1.1
Host: ib.adnxs.com
Referer: http://www.pagina.fr/
Accept: */*
X-Requested-With: com.android.browser
User-Agent: Mozilla/5.0 (Linux; U; Android 4.2; en-us; sdk Build/JB_MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30

Se abre la misma ventana esta vez con el mensaje en español. Al pulsar sobre "Cancelar",  la página web hace otra petición HTTP al servidor de anuncios:

GET /ttj?
id=1029172&size=300x600&promo_sizes=300x250&promo_alignment=center&referrer=pagina.fr&cb=6542638935&pt1=http://ww14.smartadserver.com/call/pubj/252/82917/828/S/9665235358/origine%3Dasq? HTTP/1.1
Host: ib.adnxs.com
Referer: http://www.----------.fr/
Accept: */*
X-Requested-With: com.android.browser
User-Agent: Mozilla/5.0 (Linux; U; Android 4.2; en-us; sdk Build/JB_MR1) AppleWebKit/534.30

El servidor responde con el siguiente contenido:

document.write('<iframe frameborder="0" width="300" height="250" marginheight="0" marginwidth="0" target="_blank" scrolling="no" src="http://pureads.com-trckr.co/c2/300_46555/"> </iframe>');
document.write('<scr'+'ipt type="text/javascript" src="http://pixel.alephd.com/post_asq?LgDc=&L4DK=285145&rZzC=&aNVl=1&ZzpC=&Dsph=&Hsyz=440&0ZGY=11836032&Xyes=&iK5S=&b6lE=0.1385&-tgi=-1&wziz=1.236&vKcZ=4241021722314788001&2jSB=0.181413&-Zu8=8613&e9iH=581557833328660296&b5ho=class_1&GAa8=1029172&DH5k=62.15.230.164&8rSZ=&-Z06=0.181413"></scr'+'ipt>');document.write('<scr' + 'ipt src="http://cdn.adnxs.com/ANX_async_usersync.js"></scr'+'ipt>');

Abriendo un iframe, el navegador carga la pagina alojada en "http://pureads.com-trckr.co/c2/300_46555/". Tenemos otro código en JavaScript que comprueba de nuevo si el usuario usa un dispositivo móvil. En cuyo caso, le redirecciona a la pagina "http://k5lme.trackvoluum.com/2d9c041a-48b3-44d8-b601-0c8cabafd377". Que a su vez, redirecciona a "http://mobilesecurity.com-trckr.co/warning/...". Mostramos el código del iframe:

<a id="banner" target="_blank" href="http://k5lme.trackvoluum.com/2d9c041a-48b3-44d8-b601-0c8cabafd377"><img src="https://pureads.com-trckr.co/im/300s.jpg" border="0" /></a>

<script type="text/javascript">
var mobiles = ['android'];
var uagent = navigator.userAgent.toLowerCase();
var ismobile = false;
for (var d=0;d<mobiles.length;d++) {
  if (uagent.indexOf(mobiles[d]) != -1) {
    ismobile = true;
  }
}
if (ismobile) {
     window.top.location = document.getElementById('banner').href;
}

Han creado un dominio que se llama "http://mobilesecurity.com-trckr.co" para aparentar venir de una entidad de seguridad. Al pulsar sobre la imagen, redirecciona finalmente a Google Play. Es muy importante hacer notar que la pagina "http://k5lme.trackvoluum.com/2d9c041a-48b3-44d8-b601-0c8cabafd377" (el servidor de publicidad) devuelve páginas diferentes (distintos anuncios) según el momento del día.

Hemos visto un anuncio que se parece a un ataque. El problema es que los sitios web (o las aplicaciones) contratan servicios de terceros para la publicidad, pero no tienen ningún control sobre los métodos usados para ofrecer los anuncios. Lo que puede afectar a la imagen directa del sitio web, como en este caso el periódico francés. Pensamos que los atacantes pueden aprovecharse de esos terceros servicios para infectar los dispositivos móviles. Ademas con los anuncios que cambia cada x minutos, seria muy difícil de encontrar la fuente de infección.

Desde luego no es la primera vez que encontramos como una página legítima intenta infectarnos a través del servidor de anuncios. Ya en el 2005 nos encontramos como "Dilbert intentaba infectarnos" En aquella ocasión, al visitar la (muy recomendable) tira cómica diaria de Dilbert aparecía una ventana emergente donde se informaba de errores de registro o del sistema de archivos. Obviamente era falsa, pues (en aquella ocasión) aparecía el mismo aviso independientemente del sistema operativo con que se visitara.


Laurent Delosières
ldelosieres@hispasec.com