TL; DR: Esta é uma pergunta sobre a etapa final, em um processo de root portátil, orientado ao desenvolvedor, que funciona em todas as máquinas Android. Não se baseia em nenhuma exploração - é algo que nos é permitido legal e moralmente, como desenvolvedores, em nossas próprias máquinas. Se eu receber uma resposta e conseguir fazer um chroot dentro do meu Debian, farei um post conciso no blog detalhando todas as etapas deste processo para todos os colegas desenvolvedores que desejam acesso root aos seus tablets - e não querem confiar na origem duvidosa "raízes de um clique" que Deus sabe o que faz com suas máquinas (membros de botnet?) ... As únicas dependências serão as fontes de kernel da máquina (que o fabricante é legalmente obrigado a fornecer) e a imagem da partição de inicialização (boot.img
), que é 99% das vezes dentro das atualizações over-the-air fornecidas pelo fabricante ou que podem ser baixadas individualmente como uma imagem autônoma com capacidade de flash.
Então, passou uma semana em que passei todo o meu tempo livre no meu novo tablet Android.
E quase consegui - criando um processo portátil, orientado ao desenvolvedor, para obter raiz no meu tablet Android 5.0.2.
Mas há uma coisa que falta ainda - eu não posso fazer um chroot (que eu preciso para rodar meu debootstrap
Debian!)
O que eu fiz até agora
- Primeiro, fiz um pequeno patch nas fontes de kernel do meu tablet (fornecidas pelo fabricante) e compilei meu próprio kernel - onde desabilitei as verificações para alterar o modo de imposição do SELINUX . Especificamente...
Em security/selinux/selinuxfs.c
:
...
if (new_value != selinux_enforcing) {
/* Commented out by ttsiodras.
length = task_has_security(current, SECURITY__SETENFORCE);
if (length)
goto out;
*/
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
"enforcing=%d old_enforcing=%d auid=%u ses=%u",
new_value, selinux_enforcing,
Eu então mudei minha imagem initrd
/default.prop
para conter:ro.secure=0
ero.debuggable=1
Como o meu fabricante
initrd.img
estava ausente, eu também compileisu.c
em https://android.googlesource.com/platform/system/extras/+/master/su/ e coloquei o binário resultante em baixo/sbin/su
, certificando-me de que ele esteja definido como SUID root (chmod 04755 /sbin/su
) .
Depois disso, empacotei o novo kernel e o novo initrd, como expliquei no episódio 2 do meu post anterior - e inicializei a partir da minha própria imagem:
adb reboot boot-loader ; fastboot boot myboot.img
Então, você é root?
Sim, inicialmente parecia ter sucesso:
$ adb shell
shell@K01E_2:/ $ id
uid=2000(shell) gid=2000(shell) groups=1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),
3003(inet),3006(net_bw_stats)
context=u:r:shell:s0
shell@K01E_2:/ $ ls -l /sbin/su /sbin/_su
-rwxr-xr-x root root 131 2015-10-03 10:44 su
-rwsr-xr-x root root 9420 2015-10-03 01:31 _su
(the _su is the binary I compiled, set to SUID root, and "su" is
a script I wrote to tell "su" to add me to all these groups...)
shell@K01E_2:/ $ cat /sbin/su
#!/system/bin/sh
export PATH=/system/bin:$PATH
exec /sbin/_su 0,0,1000,1028,2000,2001,1004,1007,1011,1015,\
1028,3001,3002,3003,3006
E agora consegui raiz:
shell@K01E_2:/ $ su
root@K01E_2:/ # id
uid=0(root) gid=0(root)
groups=1000(system),1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),1028(sdcard_r),2000(shell),2001(cache),
3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats)
context=u:r:shell:s0
Tenho 100% de certeza de que sou raiz - não apenas porque id
diz isso, mas porque também posso fazer coisas que processos normais definitivamente não podem:
root@K01E_2:/ # ls -l /dev/block/platform/msm_sdcc.1/by-name/boot
lrwxrwxrwx root root 2015-10-03 10:47 boot -> /dev/block/mmcblk0p16
root@K01E_2:/ # dd if=/dev/block/mmcblk0p16 of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes transferred in 0.569 secs (29485441 bytes/sec)
Eis aqui - finalmente posso ler partições brutas no meu tablet!
E o SELinux está realmente no modo "baixo, cachorro":
root@K01E_2:/ # getenforce
Permissive
Mas ... ainda há coisas que não posso fazer:
root@K01E_2:/ # mkdir /my_mnt
root@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mnt
mount: Operation not permitted
Ou seja, não consigo montar minha segunda partição no formato EXT4-fs do meu cartão SD externo.
Eu também não posso chroot para o meu adorável debootstrap
Debian:
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
É por causa do SELinux?
Não sei - sou novo (muito novo - uma semana) no SELinux. Eu pensei que quando você colocá-lo para dormir ( getenforce
relatando "Permissivo"), ele não interfere mais ...
Aparentemente, eu estava errado. Abaixo da toca do coelho, vamos novamente ...
Poderia ser por causa do meu contexto de processo?
Lembre-se que id
retornou ... "uid = 0 (root) gid = 0 (root) ... contexto = u: r: shell: s0 "
Posso mudar esse contexto? Sendo raiz e tudo, posso me afastar shell
? E se sim, vá para o que?
A resposta para a primeira pergunta é runcon
:
shell@K01E_2:/ $ runcon u:r:debuggerd:s0 /sbin/su
root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:debuggerd:s0
Boa. Mas que contexto me permitirá mount
e chroot
?
Lendo um pouco mais sobre o SELinux, de volta à minha máquina principal, analiso o /sepolicy
arquivo na raiz do initrd.img
:
linuxbox$ $ sesearch -A sepolicy | grep chroot
allow init_shell init_shell : capability { chown sys_chroot ...
allow init init : capability { chown dac_read_search sys_chroot ...
allow kernel kernel : capability { chown dac_override sys_chroot ...
allow asus-dbug-d asus-dbug-d : capability { chown sys_chroot ...
...
OK, várias possibilidades! Especialmente esse kernel
parece promissor:
shell@K01E_2:/ $ runcon u:r:kernel:s0 /sbin/su
root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:kernel:s0
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
Droga.
Quem diabos está me impedindo de chroot
ing?
Qualquer conselho muito bem-vindo ...