Виклик системи SELinux та chroot


21

TL; ДР: Це питання про завершальний крок у переносному, орієнтованому на розробників процесі вкорінення, який працює на всіх машинах Android. Він не ґрунтується на жодному подвигу - це те, що нам законодавчо і морально дозволено робити як розробники власним машинам. Якщо я отримаю відповідь і вдасться хронізувати всередині свого Debian, я зроблю стислий запис у блозі, де детально описуються всі етапи цього процесу для всіх розробників, які хочуть отримати доступ до своїх планшетів - і не хочуть довіряти сумнівному походженню "коріння в один клік", які знають, що Бог знає, що їх машини (члени ботнету?) ... Єдиними залежностями будуть джерела ядра машини (які виробник юридично зобов'язаний надати) та зображення розділів завантаження (boot.img), що становить 99% разів у оновлених оновленнях, що надаються виробником, або окремо можна завантажувати як окреме зображення, здатне спалаху.

Отже, минув тиждень, де я весь свій вільний час провів на своєму новому планшеті Android.

І я майже повністю досяг успіху - створити портативний процес, орієнтований на розробників, для досягнення root в моєму планшеті Android 5.0.2.

Але є ще одне, що ще не вистачає - я не можу зробити chroot (що мені потрібно для запуску свого debootstrap-ed Debian!)

Що я робив поки що

  1. Спочатку я зробив незначний виправлення у джерелах ядра мого планшета (передбаченого виробником), а потім скомпілював власне ядро ​​- де я відключив перевірки на зміну режиму примусового використання SELINUX . Зокрема ...

В 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. Потім я змінив своє зображення initrd, /default.propщоб містити: ro.secure=0іro.debuggable=1

  2. Оскільки мого виробника цього initrd.imgне вистачало, я також компілював su.cіз https://android.googlesource.com/platform/system/extras/+/master/su/ і помістив отриманий бінарний файл під /sbin/su, переконуючись, що він встановлений на SUID root ( chmod 04755 /sbin/su) .

Після цього я запакував нове ядро ​​та новий initrd, як я пояснив в Епізоді 2 свого попереднього допису - і завантажився із власного образу:

adb reboot boot-loader ; fastboot boot myboot.img

Отже, ти корінь?

Так, спочатку це виявилося успішним:

$ 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

І тепер я досяг кореня:

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

Я на 100% впевнений, що я корінь - не тільки тому, idщо так говорить, а тому, що я також можу робити те, що нормальні процеси точно не можуть:

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)

Ось і ось - я нарешті можу прочитати сирі розділи зі свого планшета!

І SELinux справді знаходиться в режимі "вниз, собака":

root@K01E_2:/ # getenforce                                                     
Permissive

Але ... все ще є речі, які я не можу зробити:

root@K01E_2:/ # mkdir /my_mnt

root@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mnt
mount: Operation not permitted

Тобто, я не можу змонтувати свій EXT4-fs формат 2-го розділу моєї зовнішньої SD-карти.

Я також не можу хронізувати свого прекрасного debootstrapDebian:

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

Це через SELinux?

Я не знаю - я новачок (зовсім новий - тиждень тому) у SELinux. Я подумав, що коли ти ляжеш спати ( getenforceповідомляючи "Вседозволене"), це більше не заважає ...

Мабуть, я помилився. Вниз по кролячій норі ми знову йдемо ...

Чи може це бути через мій контекст мого процесу?

Пам'ятайте, що idповернувся ... "uid = 0 (root) gid = 0 (root) ... контекст = u: r: shell: s0 "

Чи можу я змінити цей контекст? Будучи коренем і все, чи можу я відійти shell? А якщо так, перейти до чого?

Відповідь на перше питання 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

Добре. Але який контекст дозволить мені mountі chroot?

Читаючи ще трохи про SELinux, ще в своїй головній машині я розбираю /sepolicyфайл у корені 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 ...
...

Гаразд, ряд можливостей! Тим більше, що kernelце здається перспективним:

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

Дарн.

Хто чорт перешкоджає мені chroot?

Будь-які поради, які привітаються ...

Відповіді:


12

Хто чорт перешкоджає мені хронувати?

Це був не SELinux - це була погоня за дикими гусками ( getenforceповернення "Permisive" означає, що SELinux насправді більше не зображений).

Винувателем - після додавання достатньої кількості printkджерела ядра, щоб простежити збої обох chrootі mount- виявилися можливості . Більш конкретно, "набір обмежувальних можливостей" для Android - ви можете прочитати все про них за допомогою свого man( man 7 capabilities), і, зізнаюся, я ніколи раніше не турбувався заглянути в них - мої щоденні завдання UNIX залежали від них, і я не мав уявлення ... спробуйте це ваш Linux-скринька, щоб переконатися в цьому:

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

Побачити? Ping більше не є коренем SUID - він використовує інформацію, що зберігається в розширених атрибутах файлової системи, щоб знати, що він має доступ до необмеженого шару сокетів (тому він може робити це справа ICMP - на рівні IP, який є).

У будь-якому разі, я відступаю - хірургічний пункт у моєму ядрі, де я зупинив "скинути свої можливості" -, мабуть, огидно, "нехай усі вони маршують" - це було так 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;
}

Це означає, що можливості НІКОЛИ не скидаються - дійсно дуже безпечна конфігурація :-)

$ 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

Привіт, моя мила Debian :-)

О, і "Root checker" теж працює - я відірвав "su.c", тож усі в моєму планшеті можуть стати 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;
  //}

Тепер, коли він працює, я повинен змусити його працювати належним чином - тобто дозволити тільки мої termuxі Terminal Emulatorкористувачам викликати suі chroot, а не нехай все і їх бабуся в :-)


Чи не вимагає цього кореневого методу можливість прошивання власного ядра? А для цього потрібен розблокований завантажувач. Після цього ви можете просто прошивати користувальницьке відновлення та отримувати root таким чином.
1110101001

@ 1110101001 Для завантажувача: очевидно, так. Для користувальницького відновлення: у моєму планшеті такого (ще) немає - я зараз в змозі створити його ;-)
ttsiodras

1
@ 1110101001: І ще одне - ви сказали "вміння спалахнути" - я не завантажив своє завантажувальне зображення на планшет, я просто завантажуюся з нього : fastboot boot my.img. Я вважаю, що спільнота з укоріненням називає це прив’язаним вкоріненням :-) І, звичайно, я міг би спалахнути - якби хотів.
ttsiodras
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.