Linux: царь^w root ненастоящий!
От: IID Россия  
Дата: 13.08.16 17:25
Оценка:
Кто тут утверждал что линукс это дружественная система ? Не верю! (ц)

Написал утилитку, запускающую /system/bin/sh из-под рута. Столкнулся с тем, что в запущенном шелле не получается примонтировать /system на rw. Тогда как в su от KingRoot все отлично монтируется.
Подскажите, куда копать ?

Вводные:
— Linux: 3.10.49
— Android 5.1.1
— файл утилиты лежит в /system/xbin (ссылка из /system/bin), имеет chown 0.0 и chmod 06755
— root получается вызовами seteuid(0) + setresgid(0,0,0) + setresuid(0,0,0) (вызовы подсмотрел в опенсорсной SuperUser от Koushi, это отдельный ппц, ИМХО, наворотили этих uid-ов)
— для красоты еще setgroups(0, 0) + setenv("USER", "root", 1)
— в запущенном шелле команда "mount -o remount,rw /system" возвращает "mount: Operation not permitted"

Грешил на SELinux, но он не причём: переключил его в Permissive через setenforce 0 и даже перезапустил утилиту через "runcon u:r:init:s0" — теперь контексты, возвращаемые командой "id", у меня и у стороннего su сопадают. Но он может монтировать раздел, а я нет. Вызов printenv показывает одинаковые переменные окружения.

ИМХО тут больше спецов по линуксу, чем в профильном форуме.

UPD: китайский su это стаб для демона, который (скорее всего) запускается в ходе init. НО! Это же Linux! Тем более root! Должен быть способ наделить свой процесс аналогичными свойствами! (Еще бы понять, какие они...)
kalsarikännit
Отредактировано 13.08.2016 18:19 IID . Предыдущая версия . Еще …
Отредактировано 13.08.2016 17:52 IID . Предыдущая версия .
Re: Linux: царь^w root ненастоящий!
От: CreatorCray  
Дата: 13.08.16 17:29
Оценка: +5 :))) :)))
Здравствуйте, IID, Вы писали:

IID>ИМХО тут больше спецов по линуксу, чем в профильном форуме.

В политику надо было постить!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Linux: царь^w root ненастоящий!
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 13.08.16 18:00
Оценка: 1 (1) :)
Здравствуйте, IID, Вы писали:

IID>Кто тут утверждал что линукс это дружественная система ? Не верю! (ц)

IID>- Android 5.1.1

Ричард Столлман проанализировал насколько свободна платформа Android

Единственной составляющей ОС Android, что объединяет её с GNU/Linux, это ядро, сам Linux. Те, кто думает, что слово "Linux" относится ко всей комбинации GNU/Linux, запутывают сами себя и делают парадоксальные выводы о том, что "Android содержит Linux, но это не Linux". Если избежать этого недопонимания, то смысл становится понятным: Android содержит Linux (он остаётся отдельной программой в её составе, под лицензией GPLv2.), но не GNU, и таким образом, Android и GNU/Linux не имеют почти ничего общего.

Re[2]: Linux: царь^w root ненастоящий!
От: IID Россия  
Дата: 13.08.16 18:16
Оценка:
Здравствуйте, velkin, Вы писали:

V>Ричард Столлман проанализировал насколько свободна платформа Android


Слышал позицию "Linux это только ядро". Так что всё сходится У меня вопрос по POSIX API ядра в-основном... Без особенностей Java наслоений андроида.
kalsarikännit
Re: Linux: царь^w root ненастоящий!
От: m2l  
Дата: 13.08.16 20:15
Оценка:
Здравствуйте, IID, Вы писали:

IID>Кто тут утверждал что линукс это дружественная система ? Не верю! (ц)

А это больше замуты гугла/андроида, а не линукса.

IID>Написал утилитку, запускающую /system/bin/sh из-под рута. Столкнулся с тем, что в запущенном шелле не получается примонтировать /system на rw. Тогда как в su от KingRoot все отлично монтируется.

IID>Подскажите, куда копать ?
NAND lock / Temporary Root / Shell Root / Full Root. Гуглить с ключевым словом android.

IID>Грешил на SELinux, но он не причём: переключил его в Permissive через setenforce 0 и даже перезапустил утилиту через "runcon u:r:init:s0" — теперь контексты, возвращаемые командой "id", у меня и у стороннего su сопадают. Но он может монтировать раздел, а я нет. Вызов printenv показывает одинаковые переменные окружения.


Помимо SELinux и (x)id есть всё описанное здесь: https://www.kernel.org/doc/Documentation/security/credentials.txt.
Я андроидом особо не занимался, но он вроде как использует из описанного TYPES OF CREDENTIALS > (2) Capabilities (http://linux.die.net/man/2/capset).

IID>UPD: китайский su это стаб для демона, который (скорее всего) запускается в ходе init. НО! Это же Linux! Тем более root! Должен быть способ наделить свой процесс аналогичными свойствами! (Еще бы понять, какие они...)

В Linux есть способы ограничить права root (как раз Capabilities) необратимым способом.
Отредактировано 13.08.2016 20:20 m2l . Предыдущая версия . Еще …
Отредактировано 13.08.2016 20:16 m2l . Предыдущая версия .
Re: Linux: царь^w root ненастоящий!
От: andrey.desman  
Дата: 17.08.16 14:36
Оценка:
Здравствуйте, IID, Вы писали:

IID>- файл утилиты лежит в /system/xbin (ссылка из /system/bin), имеет chown 0.0 и chmod 06755


Вроде же /system монтируется с опцией nosuid, не? Ты в своей утилите логировал результаты вызова всех этих seteuid/getuid? А тулза делает fork/exec или просто exec?
Re[2]: Linux: царь^w root ненастоящий!
От: IID Россия  
Дата: 17.08.16 19:35
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, IID, Вы писали:


IID>>- файл утилиты лежит в /system/xbin (ссылка из /system/bin), имеет chown 0.0 и chmod 06755


AD>Вроде же /system монтируется с опцией nosuid, не?


хз
rr — моя тулза
su — китайская

shell@T01:/ $ mount | grep /system
/dev/block/bootdevice/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0
shell@T01:/ $ rr
root@T01:/ # mount -o remount,rw /system
mount: Operation not permitted
255|root@T01:/ # exit
255|shell@T01:/ $ su
root@T01:/ # mount -o remount,rw /system
root@T01:/ # exit
shell@T01:/ $ mount | grep /system
/dev/block/bootdevice/by-name/system /system ext4 rw,seclabel,relatime,data=ordered 0 0
shell@T01:/ $


Еще что замечено:
1) китайская не работает без демона, запущенного от init. Демон — файл с точно таким же содержанием, но другим именем. Попытка грохнуть 2 процесса-демона и перезапутить демона от root вручную приводит к тому, что su с таким демоном сразу же завершается.
2) убитые процессы-демоны самостоятельно перезапускаются в течении ~минуты. Парент /init (pid=1). Механизм перезапуска пока не выяснил. Китайцы вообще мощно в систему внедрились, я около 10ка копий насчитал, это только бегло найденные.
3) в моей тулзе я не могу зайти в /data/local/tmp. Китайская же заходит без проблем.

IID>Ты в своей утилите логировал результаты вызова всех этих seteuid/getuid?


Все такие вызовы успешны. Отдизасмил частично китацев — они делают вот так:
if (setgid(0) || setuid(0))
    return -1;
    
if (setresgid(-1, gid, -1) || setresuid(-1, uid, -1))
    return -2;
    
if (setresgid(gid, gid, gid) || setresuid(uid, uid, uid))
    return -3;


Эффекта это не даёт.

IID>А тулза делает fork/exec или просто exec?


моя
const char* sh = "/system/bin/sh";
if (execlp(sh, sh, NULL) < 0)
{


В китайской видел сисколлы execve, fork, vfork. Других, относящихся к запуску, нет.
kalsarikännit
Re[3]: Linux: царь^w root ненастоящий!
От: andrey.desman  
Дата: 17.08.16 22:10
Оценка: 2 (1)
Здравствуйте, IID, Вы писали:

IID>2) убитые процессы-демоны самостоятельно перезапускаются в течении ~минуты. Парент /init (pid=1). Механизм перезапуска пока не выяснил. Китайцы вообще мощно в систему внедрились, я около 10ка копий насчитал, это только бегло найденные.


Собственно, init их и презапускает.

IID>>Ты в своей утилите логировал результаты вызова всех этих seteuid/getuid?

IID>Все такие вызовы успешны. Отдизасмил частично китацев — они делают вот так:

Это странно. Может обманывает?
Ты из adb запускаешь? Я посмотрел код adb демона — он дропает cap_setuid/cap_setgid из своего bounding set. Получить их обратно уже невозможно, даже если запускать setuid бинарь.
Вероятно по этой причине китайцы запилили демон.


Upd. Ничего странного. Он не дропает cap_setuid/cap_setgid, а наоборот, оставляет только их. Т.е. да, ты получаешь рута, только этот рут ничего не может.
Отредактировано 17.08.2016 22:51 andrey.desman . Предыдущая версия .
Re[4]: Linux: царь^w root ненастоящий!
От: IID Россия  
Дата: 18.08.16 08:59
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, IID, Вы писали:


IID>>2) убитые процессы-демоны самостоятельно перезапускаются в течении ~минуты. Парент /init (pid=1). Механизм перезапуска пока не выяснил. Китайцы вообще мощно в систему внедрились, я около 10ка копий насчитал, это только бегло найденные.


AD>Собственно, init их и презапускает.


А почему он это делает ?

AD>Upd. Ничего странного. Он не дропает cap_setuid/cap_setgid, а наоборот, оставляет только их. Т.е. да, ты получаешь рута, только этот рут ничего не может.


Спасибо! Паззл начинает складываться...
kalsarikännit
Re[5]: Linux: царь^w root ненастоящий!
От: andrey.desman  
Дата: 18.08.16 09:11
Оценка:
Здравствуйте, IID, Вы писали:

AD>>Собственно, init их и презапускает.

IID>А почему он это делает ?

Ну стоит у сервиса флажок restart или как он там. Вот его init и перезапускает, если тот падает.
Re[4]: Linux: царь^w root ненастоящий!
От: IID Россия  
Дата: 07.09.16 19:31
Оценка:
Здравствуйте, andrey.desman, Вы писали:


AD>Ты из adb запускаешь? Я посмотрел код adb демона — он дропает cap_setuid/cap_setgid из своего bounding set. Получить их обратно уже невозможно, даже если запускать setuid бинарь.


Патч ADB демона, изменяющий всего 2 байта и отучающий его от такого поведения (чтобы не менять system-wide props, как это штатным образом положено).

UPD: для JellyBean и ниже нужен свой патч.


import sys
import os

syscall_prctl   = "\xAC\x70\xA0\xE3\x00\x00\x00\xEF" # mov r7, #172; svc 0
syscall_capset  = "\xB9\x70\xA0\xE3\x00\x00\x00\xEF" # mov r7, #185; svc 0
mov_r0_munus1   = "\x00\x00\xE0\xE3" # mov r0, -1
mov_r0_zero     = "\x00\x00\xA0\xE3" # mov r0, 0

def patch_adbd(ver, adbd_path):
    if "kk" == ver:
        pattern = syscall_prctl
        replacement = pattern[0:4] + mov_r0_munus1  # mov r7, #172; mov r0, -1

    elif "jb" == ver:
        pattern = syscall_capset
        replacement = pattern[0:4] + mov_r0_zero    # mov r7, #185; mov r0, 0
    else:
        print("Wrong OS version: %s\n", ver)
        return

    print("Patching adbd daemon file: \"%s\"" % adbd_path)
    data = open(adbd_path, "rb").read()
    offset = data.find(pattern)
    if offset < 0:
        print("ERROR: pattern not found!")
        return

    if data.find(pattern, offset+1) >= 0:
        print("ERROR: too many patterns found!")
        return

    new_content = data[:offset] + replacement + data[offset+len(replacement):]
    open(adbd_path + ".patched", "wb").write(new_content)
    print("OK!\n")


if len(sys.argv) <= 2:
    print("Usage: %s kk|jb path_to_adbd\n  kk - for adbd >= KitKat\n  jb - for adbd <= JellyBean\n" % os.path.basename(sys.argv[0]))
else:
    patch_adbd(sys.argv[1], sys.argv[2])
kalsarikännit
Отредактировано 16.09.2016 22:25 IID . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.