Buscando malware en aplicaciones Android

· October 1, 2011

Después de la estupenda charla de ayer de AppInBilling en el GTUG-Barcelona, me motive a hacer el pequeño experimento narrado a continuación . No tenía muy claro que esperaba conseguir, pero quería probar un vector de testing bastante interesante.

La idea consiste en automatizar un mismo proceso sobre muchos elementos diferentes, obteniendo así mucha información en la que poder grep ear y llevarte sorpresas. En este escenario, los elementos son las aplicaciones APK y el proceso es la herramienta apktool.

Etapa 1. Descargando aplicaciones

El sitio más usual para descargar APKs sería el propio Market oficial, pero también hay sitios comohttp://www.malwaredump.com/ que pueden resultar muy interesantes para este experimento.

Yo encontré freewarelovers.com con Google, y aún sin saber muy bien que tipo de aplicaciones me encontraría, decidí apostar por él. Saqué el patrón para descargar todas sus aplicaciones automáticamente y, aunque hay que hacer 3 peticiones por aplicación, la base de datos son sólo unas 1.670 aplicaciones. El script os lo dejo a continuación:

<?php

ini_set('max_execution_time', 60*60 ); // 1 hora

mkdir('apk');

$pid = pcntl_fork();

if ($pid == -1)
{
die('could not fork');
}
else if ($pid)                        // padre
{
pcntl_wait($status);             //Protect against Zombie children
}
else                                 // hijo
{
$ch = curl_init();
$dl = strtolower(implode('|', glob("apk/*")));

$defaults = array(
CURLOPT_HEADER            => FALSE,
CURLOPT_NOBODY            => FALSE,
CURLOPT_RETURNTRANSFER    => TRUE,
CURLOPT_AUTOREFERER        => TRUE,
CURLOPT_USERAGENT        => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.1) Gecko/20100101 Firefox/6.0.1',
CURLOPT_FOLLOWLOCATION    => TRUE,
CURLOPT_MAXREDIRS        =>  5,
CURLOPT_CONNECTTIMEOUT    => 30,
CURLOPT_TIMEOUT            => 30,
CURLOPT_SSL_VERIFYPEER    => FALSE,
CURLOPT_SSL_VERIFYHOST    => FALSE,
CURLOPT_COOKIEJAR        => tmpfile(),
CURLOPT_VERBOSE            => FALSE,
CURLOPT_CUSTOMREQUEST    => 'GET',
);

$cats = array(
'/communications',
'/entertainment',
'/finance',
'/games',
'/health',
'/multimedia',
'/news',
'/productivity',
'/reference',
'/shopping',
'/sports',
'/system',
'/travel' );

foreach($cats as $cat) {

// descargar lista unica de aplicaciones por categoria
$defaults[CURLOPT_URL] = 'http://www.freewarelovers.com/android/category'.$cat;
curl_setopt_array($ch, $defaults);
$body = curl_exec($ch);

preg_match_all('|"/android/app/([\w\|-]+)"|', $body, $matches);

$apps = array_unique($matches[1]);

foreach($apps as $app) {

if (trim($app)=='') continue;
if (strpos($dl, strtolower($app))) continue;

// consultar el enlace de descripcion de la aplicacion
$defaults[CURLOPT_URL] = 'http://www.freewarelovers.com/android/app/'.$app;
curl_setopt_array($ch, $defaults);
$body = curl_exec($ch);

preg_match_all('|"/android/download/temp/(.*).apk"|', $body, $matches);
$nameApp = substr($matches[1][0],11);
if (trim($nameApp)=='') continue;
if (file_exists('apk/'.$nameApp.'.apk')) continue;

// conseguir el enlace directo a la aplicacion (no-hot-link)
$defaults[CURLOPT_URL] = 'http://www.freewarelovers.com/android/download/temp/'.$matches[1][0].'.apk';
curl_setopt_array($ch, $defaults);
$body = curl_exec($ch);

preg_match_all('|http://www.freewarelovers.com/hotlinkmenot/(.*)\.apk|', $body, $matches);
if (trim($matches[0][0])=='') continue;

// descargar la aplicacion
$defaults[CURLOPT_URL] = $matches[0][0];
curl_setopt_array($ch, $defaults);
$body = curl_exec($ch);

file_put_contents('apk/'.$nameApp.'.apk', $body);
}
}
}
?>

Etapa 2. Decompilar aplicaciones

Una vez todas descargadas, fue cuestión de pasar otro script que las decompilara. Se puede sustituir por cualquier otro proceso como, por ejemplo, “unzip”, “dex2jar”, “jad” y “understand”. Yo decidí hacerlo facilito y usar directamente la herramienta “apktool”.

#!/bin/bash

cd apk2

for f in $( ls ../apk ); do
if [ ! -d "../apk2/${f//.apk}/" ]
then
java -jar ../apktool.jar decode "../apk/$f"
fi
done

Etapa 3. Buscando sorpresas

La parte costosa ya ha terminado, obteniendo así tantos directorios como aplicaciones procesadas. Ahora es momento de buscar patrones “curiosos”, “delicados” y “repetitivos”, como, por ejemplo, aquellas aplicaciones que tienen admob u otra librería.

Centrándonos en “malware”, he realizado la siguiente búsqueda:

grep 'const-string v[0-9], "http[s]*://.*"' * -r

Muchos webservices… muchos dominios rusos… muchos logins… os dejo un dump de la consulta anterior para que os recreéis.

http://dl.dropbox.com/u/7186726/dumpGrep.txt

Etapa 4. AndroidRisk

Visto que hay miga en esto, decidí terminar el experimento con la aplicación AndroidRisk del paquete AndroidGuard. Esta aplicación permite buscar en un directorio de ficheros APKs aquellos que potencialmente se parecen mucho a uno de los últimos virus/troyanos detectados para Android (por ejemplo, DroidDream).

Es lanzar el siguiente comando:

./androrisk.py -d ../apk/

Os dejo el dump también.

http://dl.dropbox.com/u/7186726/dumpRisk.txt

No sé hasta que punto fiarme de los resultados, pero todo apunta a que muchas de estas aplicaciones “tienen sorpresita”. (A más alto el número, más afinidad de ser maligno.)

Etapa 5. Fuzzing

¿Y sí cogemos todas las direcciones que se han extraido y se lanza una herramienta automatizada de intrusión web MUY básica? (Sql Injections, Path Traversal, Remote File Inclusion, Local File Inclusion, … ) Se puede montar una bonita botnet con la tontería… y no sólo eso… sino que cada webservice debe llevar asociada una base de datos de usuarios.

Despedida

Y esto sólo con ~1500 aplicaciones … :-)

Sed buenos y cualquier duda ya sabéis donde estoy.

Twitter, Facebook