Chamada do sistema SELinux e chroot

3

TL; DR: Esta é uma questão sobre a etapa final, em um processo de enraizamento orientado ao desenvolvedor portátil, que funciona em todas as máquinas com Android. Não é baseado em qualquer exploração - é algo que nos é legal e moralmente permitido fazer, como desenvolvedores, para nossas próprias máquinas. Se eu obtiver uma resposta e conseguir chroot dentro do meu Debian, farei uma publicação concisa detalhando todas as etapas deste processo para todos os desenvolvedores que querem acesso root aos seus tablets - e não querem confiar em origem duvidosa "one-click-roots" que fazem Deus sabe o quê para suas máquinas (membros da botnet?) ... As únicas dependências serão as fontes do 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 pode ser baixada individualmente como uma imagem autônoma que pode ser flash.

Então, passou uma semana em que passei todo o meu tempo livre no meu novo tablet Android.

E eu consegui quase completamente - criar um processo portátil e orientado ao desenvolvedor, para conseguir o root no meu tablet Android 5.0.2.

Mas ainda falta uma coisa - não posso fazer um chroot (que eu preciso executar meu Debiandebootstrap -ed!)

O que eu fiz até agora

  1. Primeiro, eu fiz um pequeno patch nas fontes de kernel do meu tablet (fornecido pelo fabricante) e, em seguida, compilei meu próprio kernel - onde desativei as verificações para alterar o modo de imposição 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,
  1. Em seguida, alterei a /default.prop da imagem do meu initrd para conter: ro.secure=0 e ro.debuggable=1

  2. Como o initrd.img de meu fabricante estava faltando, também compilei su.c de link e colocou o binário resultante em /sbin , certificando-se de que está definido para a raiz SUID ( 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 iniciado a partir da minha própria imagem:

adb reboot boot-loader ; fastboot boot myboot.img

Então, você está root?

Sim, inicialmente pareceu ser bem sucedido:

$ 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 o root:

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 root - 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 que, finalmente, posso ler as partições brutas do meu tablet!

E o SELinux está mesmo no modo "down, dog":

root@K01E_2:/ # getenforce                                                     
Permissive

Mas ... ainda existem coisas que não consigo 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 a segunda partição formatada do EXT4-fs do meu cartão SD externo.

Eu também não posso chroot para o meu amável debootstrap -ed Debian:

root@K01E_2:/ # chroot /data/debian/ /bin/bash                             
chroot() fail
Operation not permitted

É por causa do SELinux?

Eu não sei - eu sou novo (muito novo - uma semana de idade) para o SELinux. Eu pensei que quando você colocá-lo para dormir ( getenforce relatando "permissivo") já não interfere ...

Aparentemente, eu estava errado. No buraco do coelho, vamos de novo ...

Poderia ser por causa do contexto do meu processo?

Lembre-se que id retornou ... "uid = 0 (root) gid = 0 (raiz) ... contexto = u: r: shell: s0 "

Posso mudar esse contexto? Sendo root e tudo, posso me afastar de shell ? E se sim, mudar 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

Bom. Mas qual contexto me permitirá mount e chroot ?

Lendo um pouco mais sobre o SELinux, na minha máquina principal, analiso o arquivo /sepolicy 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 que kernel one 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

Darn.

Quem diabos está me impedindo de chroot ing?

Qualquer conselho é muito bem-vindo ...

    
por ttsiodras 03.10.2015 / 12:41

1 resposta

3

Quem diabos está me impedindo de fazer chrooting?

Não foi o SELinux - foi uma perseguição selvagem ( getenforce retornar "Permissivo" significa que o SELinux não está mais na foto).

O culpado - depois de adicionar um bom número de printk na fonte do kernel para rastrear as falhas de ambos os chroot e mount - acabou sendo capacidades . Mais especificamente, o "conjunto de limites de recursos" do Android - você pode ler tudo sobre eles via man ( man 7 capabilities ) e confesso que nunca antes me preocupei em pesquisá-los - minhas tarefas diárias do UNIX dependiam delas e não fazia ideia ... tente isso na sua caixa linux para ver por si mesmo:

$ getfattr -d -m - /sbin/ping
getfattr: Removing leading '/' from absolute path names
# file: sbin/ping
security.capability=0s......

Veja? O ping não é mais o SUID root - ele usa informações armazenadas nos atributos estendidos do sistema de arquivos para saber que ele tem acesso à camada de soquetes brutos (para fazer isso ICMP -) .

De qualquer forma, eu divago - o ponto de cirurgia no meu kernel onde eu parei o "drop my capabilities set" - em um argumento discutivelmente nojento, "deixe todos marcharem" - foi isso ( security/commoncap.c ):

static long cap_prctl_drop(struct cred *new, unsigned long cap)
{
    if (!capable(CAP_SETPCAP))
        return -EPERM;
    if (!cap_valid(cap))
        return -EINVAL;

    // ttsiodras: come in, everyone, the water's fine!
    //cap_lower(new->cap_bset, cap);
    return 0;
}

Isso significa que os recursos NUNCA são descartados - uma configuração muito segura, na verdade: -)

$ adb shell

shell@K01E_2:/ $ su

root@K01E_2:/ # chroot /data/debian/ /bin/bash

root@localhost:/# export PATH=/bin:/sbin:/usr/bin:/usr/sbin:\
     /usr/local/bin:$PATH

root@localhost:/# cat /etc/issue
Debian GNU/Linux 8 \n \l

Olá, meu doce Debian: -)

Ah, e "Verificador de raiz" funciona também - eu recortei "su.c", então todos no meu tablet podem se tornar root:

int main(int argc, char **argv)
{
  struct passwd *pw;
  uid_t uid, myuid;
  gid_t gid, gids[50];

  /* Until we have something better, only root and shell can use su. */
  myuid = getuid();
  //
  // ttsiodras - Oh no, you don't :-)
  //
  //if (myuid != AID_ROOT && myuid != AID_SHELL) {
  //    fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
  //    return 1;
  //}

Agora que isso funciona, devo fazê-lo funcionar corretamente - ou seja, permitir que apenas meus usuários termux e Terminal Emulator invoquem su e chroot e não deixem todos e sua avó entrarem: -)

    
por 03.10.2015 / 16:44