Android Para Hackers Reales pt.1

El titulo de esta publicación seguramente será muy polémico y causará muchas criticas, pero crear este “manual” y poner esta clase de títulos tienen sus razones, para comenzar las publicaciones de  “Android para hackers” normalmente no pasan de una lista de apps para instalar y que harán todo el trabajo, pero sin duda alguna es complicado encontrar algo que valga la pena y que no esté regado por todo internet, además de que todo eso es negocio de scriptkiddies no de “hackers” como sugiere el título, por esta sencilla razón me daré a la labor de armar un manual de como convertir esto:


 23rk9wz

 

En esto:

qoej6b

Y finalmente esto:

fperl

Todo completamente desde 0. Vamos a hacer Ing. Inversa, vamos a compilar kernels, vamos a montarlos en dispositivos android (este manual estará más que nada enfocado a tabletas, aunque puede servir en celulares también) y vamos a hacer hacks reales.

Comenzamos!

Para este primer post vamos con una introducción al kernel de android, las herramientas que vamos a necesitar son: Android rooteado (hay muchos manuales además de que este proceso puede variar según el dispositivo que se tenga, por lo que no entraré en detalles respecto a esto), adb (se instala con el Android SDK o pueden usar “adb lite” que pueden encontrar buscando en google :P), abootimg (http://gitorious.org/ac100/abootimg) y binwalk (sería igual utilizar un editor hexadecimal en lugar de esta herramienta, pero para acelerar un poco las cosas, lo usaremos esta vez :P).

En esta primera parte trabajaré con un celular android, debido a que la tableta que tengo a la mano para trabajar (Sony Tablet S)  lleva un proceso diferente (del cual hablaré en el siguiente post), pero este proceso se aplica a una gran cantidad de tabletas android.

Para las personas que no estén familiarizadas con compilar kernels tal vez se les complique un poco entender los términos que se utilizarán a lo largo de este post, pero intentaré hacerlo lo más claro posible.
 # mount | grep /system

/dev/block/mmcblk0p14 /system ext4 rw,relatime,barrier=1,data=ordered 0 0

Lo primero es identificar las particiones que utiliza el dispositivo, para detectar las que faltan y buscar en ellas el tan deseado kernel.
 # mount | grep /dev/block/mmcblk0p

/dev/block/mmcblk0p14 /system ext4 rw,relatime,barrier=1,data=ordered 0 0

/dev/block/mmcblk0p21 /data ext4 rw,nosuid,nodev,noatime,errors=continue,barrier=1,data=ordered 0 0

/dev/block/mmcblk0p15 /persist ext4 rw,nosuid,nodev,relatime,barrier=1,data=ordered 0 0

/dev/block/mmcblk0p16 /cache ext4 rw,nosuid,nodev,relatime,barrier=1,data=ordered 0 0

/dev/block/mmcblk0p18 /drm ext4 rw,nosuid,nodev,relatime,barrier=1,data=ordered 0 0

/dev/block/mmcblk0p22 /mpt ext4 rw,nosuid,nodev,relatime,barrier=1,data=ordered 0 0

Ya tenemos la 14,21, 15, 16, 18 y 22 identificadas.
 # ls -l /dev/block/mmcblk0p*

brw------- root     root     179,   1 2013-01-04 00:13 mmcblk0p1

brw------- root     root     179,  10 2013-01-13 20:06 mmcblk0p10

brw------- root     root     179,  11 2013-01-13 19:48 mmcblk0p11

brw------- root     root     179,  12 2013-01-04 00:13 mmcblk0p12

brw------- root     root     179,  13 2013-01-04 00:13 mmcblk0p13

brw------- root     root     179,  14 2013-01-04 00:13 mmcblk0p14

brw------- root     root     179,  15 2013-01-04 00:13 mmcblk0p15

brw------- root     root     179,  16 2013-01-04 00:13 mmcblk0p16

brw-rw---- system   system   179,  17 2013-01-04 00:13 mmcblk0p17

brw-rw---- system   system   179,  18 2013-01-04 00:13 mmcblk0p18

brw------- root     root     179,  19 2013-01-04 00:13 mmcblk0p19

brw------- root     root     179,   2 2013-01-04 00:13 mmcblk0p2

brw------- root     root     179,  20 2013-01-04 00:13 mmcblk0p20

brw------- root     root     179,  21 2013-01-04 00:13 mmcblk0p21

brw------- root     root     179,  22 2013-01-04 00:13 mmcblk0p22

brw------- root     root     179,  23 2013-01-04 00:13 mmcblk0p23

brw------- root     root     179,   3 2013-01-04 00:13 mmcblk0p3

brw------- root     root     179,   4 2013-01-04 00:13 mmcblk0p4

brw------- root     root     179,   5 2013-01-04 00:13 mmcblk0p5

brwxrwx--- root     radio    179,   6 2013-01-04 00:13 mmcblk0p6

brw------- root     root     179,   7 2013-01-04 00:13 mmcblk0p7

brwxrwx--- root     system   179,   8 2013-01-04 00:13 mmcblk0p8

brw------- root     root     179,   9 2013-01-04 00:13 mmcblk0p9

Lamentablemente nos faltan algunas por identificar.

Una ayuda bastante útil es cuando /proc/mtd está activo:
 # cat /proc/mtd

dev:    size   erasesize  name

mtd0: 00500000 00020000 "boot"

mtd1: 00500000 00020000 "recovery"

mtd2: 00140000 00020000 "misc"

mtd3: 00060000 00020000 "splash"

mtd4: 0aa00000 00020000 "system"

mtd5: 04600000 00020000 "cache"

mtd6: 0bda0000 00020000 "userdata"

mtd7: 01400000 00020000 "userdata2"

Lamentablemente esto no es en la mayoría de los dispositivos:
# cat /proc/mtd

/proc/mtd: No such file or directory

Por lo que se requiere realizar un poco de Ing. Inversa.
 # dd if=/dev/block/mmcblk0p1 of=/sdcard/mmcblk0p1

40+0 records in

40+0 records out

20480 bytes transferred in 0.004 secs (5120000 bytes/sec)

Copiamos cada partición a la SDCard y luego las bajamos a la pc:
 Zer0-null:/home/xianur0 # adb pull /sdcard/mmcblk0p1 mmcblk0p1

236 KB/s (20480 bytes in 0.084s)

Y vamos analizando una por una con binwalk:
 Zer0-null:/home/xianur0 # binwalk mmcblk0p1

 

DECIMAL     HEX               DESCRIPTION

-------------------------------------------------------------------------------------------------------

En muchos casos incluso binwalk no puede detectar de que es la partición, entonces nos toca hacerlo manualmente con un editor hexadecimal.
 Zer0-null:/home/xianur0/L3-back # binwalk mmcblk0p9

 

DECIMAL     HEX               DESCRIPTION

-------------------------------------------------------------------------------------------------------

20010              0x4E2A          gzip compressed data, from Unix, last modified: Thu Jul 26 05:55:33 2012, max compression

[…]

 

Bingo! Eso suena interesante, veamos si es:

 
Zer0-null:/home/xianur0/L3-back # perl -e 'my $tmp="";open FILE,"<mmcblk0p9"; read FILE,$tmp,8; print $tmp;'

ANDROID!

 

El encabezado “ANDROID!” indica que esta partición es... boot!, en esta es donde se encuentra el kernel :P.
 

Zer0-null:/home/xianur0/L3-back # abootimg -i mmcblk0p9

 

Android Boot Image Info:

 
* file name = mmcblk0p9

 

* image size = 8388608 bytes (8.00 MB)

page size  = 4096 bytes

 

* Boot Name = ""

 

* kernel size       = 3312024 bytes (3.16 MB)

ramdisk size      = 490986 bytes (0.47 MB)

 

* load addresses:

kernel:       0x00208000

ramdisk:      0x01300000

tags:         0x00200100

 

* cmdline = androidboot.hardware=e0

 

  • id = 0x099380a2 0xe8c73d9d 0x7ec0b3eb 0xb7d342d1 0xfda995b2 0x00000000 0x00000000 0x00000000


 

Ya tenemos los valores que vamos a utilizar luego, pero por ahora vamos a extraer esta partición:

 
Zer0-null:/home/xianur0/L3-back # abootimg -x mmcblk0p9

writing boot image config in bootimg.cfg

extracting kernel in zImage

extracting ramdisk in initrd.img

 

 

Primero que nada: zImage sería el kernel, y initrd.img el ramdisk, esencialmente el ramdisk es algo así como la partición raíz (“/”) en linux, siendo esta montada como solo lectura (a que no se habían dado cuenta de que todo lo que ponen en “/” se borra :P).

 

Un punto importante es que no en todos los dispositivos es tan fácil conseguir el kernel, en muchos casos viene bloqueado de fábrica, de modo que ni siquiera lo pueden ver como partición, pero tenemos el siguiente truco que puede ayudar en muchos casos:

 

Zer0-null:/home/xianur0 # fastboot oem unlock

 

Pero no profundizaré mucho sobre ese tema en este post.

 

Podemos editar el ramdisk de la siguiente forma:

 
Zer0-null:/home/xianur0/L3-back # mkdir ramdisk && cd ramdisk && gzip -dc ../initrd.img | cpio -i

2074 blocks

 

Zer0-null:/home/xianur0/L3-back/ramdisk # ls

chargerimages  dev         init.goldfish.rc  init.rc         lgdms.fota_update.rc  sbin    ueventd.goldfish.rc

data           init        init.qcom.rc      init.target.rc  lgsecurity.rc         sys     ueventd.rc

default.prop   init.e0.rc  init.qcom.sh      lgdms.fota.rc   proc                  system

 

ya tenemos el ramdisk extraído, podemos cambiar las cosas que necesitemos y volver a empaquetarlo:

 
Zer0-null:/home/xianur0/L3-back/ramdisk # find . | cpio -o -H newc | gzip > ../new-initrd.img

2074 blocks

 

Después con el mismo abootimg:

 
Zer0-null:/home/xianur0/L3-back # cp mmcblk0p9 mmcblk0p9.new && abootimg -u mmcblk0p9.new -r new-initrd.img

reading ramdisk from new-initrd.img

Writing Boot Image mmcblk0p9.new

 

y listo, tenemos la partición como nueva.

 

Podemos subirla de muchas formas al dispositivo, una es con el mismo dd:

 
Zer0-null:/home/xianur0/L3-back # adb push  mmcblk0p9.new /sdcard/

 

Y en el dispositivo:

 
# dd if=/sdcard/mmcblk0p9.new of=/mmcblk0p9

 

 

O también se puede realizar con fastboot:

 

Fastboot es uno de los modos que tiene android, similar a adb, la diferencia es que fastboot corre en pre-os es decir se ejecuta antes que android como tal y es muy similar a PXE (Entorno de ejecución de prearranque).

 

Para entrar a fastboot se tiene que apagar el dispositivo y con una combinación especifica de botones (varían de dispositivo a dispositivo) presionados, encender el dispositivo, para reconocer que un dispositivo está en fastboot basta con ver que no pasa de la primera pantalla (normalmente el logo del fabricante).

 
Zer0-null:/home/xianur0/L3-back # fastboot flash boot mmcblk0p9.new

 

Por cierto, sabían que fastboot permite ejecutar un kernel sin necesitar de flashearlo al dispositivo?

 
Zer0-null:/home/xianur0/L3-back # fastboot boot mmcblk0p9.new

 

o

 
Zer0-null:/home/xianur0/L3-back # fastboot boot zImage initrd.img

 

Es algo así como un “live-kernel”, esto nos puede ser de mucha utilidad cuando puede haber riesgo de “brickear” el dispositivo si se escribe un kernel/ramdisk defectuoso, de modo que podemos probarlo antes de flashearlo al dispositivo.

 

Por ahora nos hemos extendido un poco, así que terminemos por ahora este post, no sin antes dar un adelanto de lo que veremos en el siguiente:

 

* Cross-Compilar un kernel de android.

* Compilar driver RTL8187 en Sony Tablet S para levantar una antena wifi Alfa Networks.
#!/usr/bin/perl -w
require Digest::MD5;
my $base = $ARGV[0];
my $arg1 = $ARGV[1] || die(("\t"x3)."Deb2Droid v0.1 by Xianur0\n\nUse: ./export.pl [pool dir] [deb]\n");
my @packages = ($arg1);
our @extraidos = ();
our @depsinstaladas = ();
my $install = 1;
system("mkdir var && mkdir var/lib && mkdir var/lib/dpkg && mkdir var/lib/dpkg/info");
open STATUS,">>var/lib/dpkg/status";
sub copiar {
my ($origen,$destino) = @_;
open(FILES,"<".$origen) || return 0;
my $contenido = "";
binmode FILES;
while(<FILES>) {
$contenido .=$_;
}
close(FILES);
open FILED,">".$destino;
binmode FILED;
print FILED $contenido;
close(FILED);
}
sub locatedep {
my ($dir,$dep) = @_;
$dir .= "/" if($dir !~ /\/$/);
my @files = <$dir*>;
foreach my $file (@files) {
my $tmpfile = $file;
$tmpfile =~ s/^.+\///g;
if(-d $file) {
if($file !~ /^\.+$/){
return 1 if(locatedep($file,$dep));
}
}
elsif(-f $file && $dep eq substr($tmpfile,0,length($dep)) && $file =~ /u?deb$/) {
print "[-] Posible paquete encontrado: ".$dep." ? ".$file."\n";
print "ar x ".$file." && (tar -xzvf data.tar.gz > archivos.list) && tar -xzvf control.tar.gz 2>&1\n";
if($install == 1){
print "[-] Extrayendo paquete...\n";
return 1 if(extract($file,$dep));
}
}
}
return 0;
}
sub in_array
{
my ($arr,$search_for) = @_;
my %items = map {$_ => 1} @$arr; # create a hash out of the array values
return (exists($items{$search_for}))?1:0;
}

sub finddeps {
my $searchpackagename = "";
$searchpackagename = $_[0] if($#_ >= 0);
$searchpackagename = "" unless defined $searchpackagename;
open CONTROL,"<control" || return;
open MD5,"<md5sums";
open CONFFILES,"<conffiles";
my $control = "";
my $md5 = "";
my $conffiles = "";
return unless(fileno(MD5));
while(<CONTROL>) {
$control.=$_;
}
close(CONTROL);
my $packagename = "";
$packagename = $1 if($control =~ /Package: ([^\r\n]+)/);
print "Paquete: ".$searchpackagename."=? ".$packagename."\n";
if($searchpackagename ne "" && $searchpackagename ne $packagename) {
return 0;
}
if(fileno(MD5)){
while(<MD5>) {
$md5.=$_;
}
close(MD5);
}
my $status = "Status: install ok not-installed";
if(fileno(CONFFILES)) {
while(<CONFFILES>) {
my $f = $_;
$f =~ s/[\r\n]+//g;
open F, ".".$f;
my $cf = "";
while(<F>){
$cf .= $_;
}
$conffiles.=" ".$f." ".Digest::MD5::md5_hex($cf)."\n";
}
close(CONFFILES);
$control =~ s/(Description:\s+)/Conffiles:\n$conffiles$1/;
$status = "Status: install reinstreq half-configured";
}
checkmd5($md5);
my $depsstring = "";
$depsstring = $1 if($control =~ /Depends: ([^\r\n]+)/);
copiar("archivos.list","var/lib/dpkg/info/".$packagename.".list");
copiar("postinst","var/lib/dpkg/info/".$packagename.".postinst");
copiar("preinst","var/lib/dpkg/info/".$packagename.".preinst");
copiar("postrm","var/lib/dpkg/info/".$packagename.".postrm");
copiar("prerm","var/lib/dpkg/info/".$packagename.".prerm");
open MD5OUT,">>var/lib/dpkg/info/".$packagename.".md5sums";
print MD5OUT $md5;
$md5 = "";
if($depsstring eq ""){
print "[-] Sin dependencias... continuando...\n";
return 1;
}
my @deps = ($depsstring =~ /[^\,]+/g);
my $i = 0;
for $dep (@deps) {
$dep =~ s/^\s+//g;
my $version = $dep;
$version =~ s/(.+\()//g;
$version =~ s/\)//g;
my $condicion = "";
if($version=~/^(>|>=|<=|==|<)\s+([\:\.\d]+)$/){
($condicion,$version) = ($1,$2);
} else {$version="";}
$dep =~ s/\s+.+$//g;
$deps[$i] = $dep;
$i++;
}
print "[-]Instalando dependencias....\n\n";
for $dep (@deps) {
my $cdep = $#deps;
if(!in_array(\@depsinstaladas,$dep)){
push(@depsinstaladas,$dep);
print "[-] Buscando paquete: ".$dep."...\n";
if(!locatedep($base,$dep)) {
die("\n[!] No se pudo resolver la dependencia: ".$dep."\n");
}
}
}
print "[-] Agregando a status...\n";
$control =~s/^Package\:([^\r\n]+)/Package:$1\n$status/;
print $control."\n";
print STATUS $control."\n\n";
print "[-] Instaladas!\n";
return 1;
}
sub extract {
my ($p,$packname) = @_;
if(in_array(\@extraidos,$p)){
return 1;
}
push(@extraidos,$p);
my $descarte = "";
system("ar x ".$p." && (tar -xzvf data.tar.gz > archivos.list) && tar -xzvf control.tar.gz 2>&1");
my $estado = finddeps($packname);
system("rm md5sums 2>&1 | rm control 2>&1 | rm archivos.list 2>&1 | rm debian 2>&1 | rm debian-binary 2>&1 | rm conffiles 2>&1 | rm postinst 2>&1 | rm preinst 2>&1 | rm postrm 2>&1 | rm prerm 2>&1 | rm data.tar.gz 2>&1 | rm control.tar.gz 2>&1 | echo ");
return $estado;
}
sub checkmd5 {
my $md5 = $_[0];
my @lineas = split(/[\r\n]/,$md5);
for $linea (@lineas) {
my ($md5,$objeto) = ($linea =~ /^([\w\d]+)\s+(.+)$/);
open OBJETO,"<".$objeto;
binmode OBJETO;
my $bin = "";
while(<OBJETO>){
$bin .=$_;
}
my $md5real = Digest::MD5::md5_hex($bin);
unless($md5 eq $md5real) {
die("\n[!] MD5 incorrecto: ".$md5."!=".$md5real." en: ${objeto}\n");
} else {
print "\r[-] Probando MD5: ${md5} ${md5real} ${objeto}\r";
}
}
print "\n[-] MD5's correctos!\n";
}
for $package (@packages){
extract($base.$package);
}
print "[-] Paquete y dependencias extraidos correctamente!\n";

By Xianur0

Penulis : Megabyte ~ Sebuah blog yang menyediakan berbagai macam informasi

Artikel Android Para Hackers Reales pt.1 ini dipublish oleh Megabyte pada hari miércoles, 23 de enero de 2013. Semoga artikel ini dapat bermanfaat.Terimakasih atas kunjungan Anda silahkan tinggalkan komentar.sudah ada 1comentarios: di postingan Android Para Hackers Reales pt.1
 

1 comentarios: