Оказывается, xonsh (или Python) проглатывает \ 1
, поэтому sed фактически видит s / ([az] *) ing / ing / g
и его вывод конечно, правильно для этого ввода.
Я открыл здесь проблему, но обходной путь - использовать необработанную строку Python:
$ echo 'testing' | sed -E r's/([a-z]*)ing/\1ing/g'
testing
Это предпочтительнее экранирования ( \\ 1
), поскольку это приведет к ошибке в оболочке POSIX, а не продолжит с нежелательным \ 1
.
Однако , благодаря @adqm , двойные кавычки, а также экранирование обратной косой черты переносимо между xonsh и bash:
$ echo 'testing' | sed -E "s/([a-z]*)ing/\1ing/g"
Ключевым моментом является идентификатор пользователя 0. В ядре есть много мест, которые проверяют идентификатор пользователя вызывающего процесса и предоставляют разрешение на выполнение каких-либо действий, только если идентификатор пользователя равен 0.
Имя пользователя не имеет значения; ядро даже не знает об именах пользователей.
Механизм разрешений Android идентичен на уровне ядра, но полностью отличается на уровне приложения. У Android есть пользователь root (UID 0), как и в любой другой системе, основанной на ядре Linux. Однако Android не имеет учетных записей пользователей, и в большинстве настроек не позволяет пользователю (например, человеку, работающему и владеющему устройством) выполнять действия в качестве пользователя root. «Корневой» Android - это установка, которая позволяет владельцу / пользователю устройства выполнять действия как root.
Исполняемый файл setuid запускается от имени пользователя, владеющего исполняемым файлом. Например, su
является setuid и принадлежит пользователю root, поэтому, когда любой пользователь запускает его, процесс, выполняющий su
, запускается от имени пользователя root. Задача su
- убедиться, что вызывающему его пользователю разрешено использовать учетную запись root, запустить указанную команду (или оболочку, если команда не указана), если эта проверка прошла успешно, и выйти если эта проверка не удалась. Например, su
может попросить пользователя подтвердить, что он знает пароль root.
Более подробно, процесс имеет три идентификатора пользователя : эффективный UID, который используется для проверок безопасности; реальный UID, который используется в нескольких проверках привилегий, но в основном полезен в качестве резервной копии исходного идентификатора пользователя, и сохраненный идентификатор пользователя, который позволяет процессу временно переключать свой эффективный UID на реального пользователя ID, а затем вернуться к прежнему действующему UID (это полезно, например, когда программе setuid требуется доступ к файлу как исходный пользователь). Запуск исполняемого файла setuid устанавливает эффективный UID для владельца исполняемого файла и сохраняет реальный UID.
Запуск исполняемого файла setuid (и подобных механизмов, например, setgid) - единственный способ повысить привилегии процесса. Практически все остальное может только уменьшить привилегии процесса.
До сих пор я описывал традиционные системы Unix. Все это верно для современной системы Linux, но Linux приносит с собой несколько дополнительных сложностей.
Linux имеет систему возможностей . Помните, как я сказал, что в ядре есть много проверок, где разрешены только процессы, запущенные с идентификатором пользователя 0? Фактически, каждая проверка имеет свою собственную возможность (ну, не совсем так, некоторые проверки используют одну и ту же возможность). Например, есть возможность доступа к необработанным сетевым сокетам и еще одна возможность для перезагрузки системы. У каждого процесса есть набор возможностей наряду с пользователями и группами. Процесс проходит проверку, запущен ли он как пользователь 0 или имеет возможность, соответствующую проверке.Процесс, требующий определенных привилегий, может работать как пользователь без полномочий root, но с необходимыми возможностями; это ограничивает влияние, если в процессе есть брешь в безопасности. Для исполняемого файла можно установить одну или несколько возможностей: это похоже на setuid, но работает с набором возможностей процесса, а не с идентификатором пользователя процесса. Например, для ping нужны только необработанные сетевые сокеты, поэтому для него можно установить cap CAP_NET_RAW
вместо setuid root.
Linux имеет несколько модулей безопасности , наиболее известным из которых является SELinux . Модули безопасности вводят дополнительные проверки безопасности, которые могут применяться даже к процессам, запущенным с правами root. Например, можно (не просто!) Настроить SELinux так, чтобы запускал процесс с идентификатором пользователя 0, но с таким количеством ограничений, что он фактически ничего не может делать .
Linux имеет пространств имен пользователей . Внутри ядра пользователь - это не просто идентификатор пользователя, а пара, состоящая из идентификатора пользователя и пространства имен. Пространства имен образуют иерархию: дочернее пространство имен уточняет разрешения в пределах своего родителя. Всемогущий пользователь - это пользователь 0 в корневом пространстве имен. Пользователь 0 в пространстве имен имеет полномочия только внутри этого пространства имен. Например, пользователь 0 в пространстве имен пользователя может олицетворять любого пользователя этого пространства имен; но извне все процессы в этом пространстве имен запускаются от имени одного и того же пользователя.
В общем, просто эффективный uid равен 0. Бит "setuid" в исполняемых файлах на самом деле устанавливает эффективный uid процесса. Если эффективный uid не равен нулю, а реальный uid не равен нулю, программа работает от имени "непривилегированного" пользователя. Применяются следующие правила:
Непривилегированные процессы могут устанавливать эффективный идентификатор пользователя только на реальный идентификатор пользователя, эффективный идентификатор пользователя или сохраненный set-user-ID. Непривилегированные пользователи могут устанавливать реальный ID пользователя только на реальный ID пользователя или эффективный ID пользователя.
Что касается Android, нет, я не думаю, что удаления sudo
и su
достаточно - если любая программа может иметь установленный бит seteuid, эта программа потенциально может работать с uid = 0. Если есть возможность получить доступ к внутренней файловой системе как root в любое время, то такая программа может быть внедрена, и доступ root будет возможен.
В Linux есть 4 UID: RUID (реальный), EUID (эффективный), SUID (сохраненный), FSUID (файловая система).
Это не более чем числа и являются свойствами процессов, которые хранятся в управляющем блоке в таблице процессов ядра.
UID '0'
имеет особое свойство, так как обозначает пользователя root
, который имеет в целом неограниченные права доступа.
su
и sudo
- это программы для изменения эффективных прав доступа пользователя путем запуска нового подпроцесса с EUID, установленным на новый UID через бит SetUID в su
. Затем этот процесс su снова порождает новую оболочку в новом подпроцессе с 4 UID, установленными на новое значение UID.
Следующий пример должен продемонстрировать это. Допустим, пользователь rda
вошел в систему через ssh-терминал. ps fax
покажет следующие процессы:
472 ? Ss 0:00 /usr/sbin/sshd -D
9151 ? Ss 0:00 \_ sshd: rda [priv]
9153 ? S 0:00 | \_ sshd: rda@pts/1
9154 pts/1 Ss+ 0:00 | \_ -bash
4 процесса, демон ssh, два процесса для сессии ssh (и терминала? ), последний процесс - оболочка для входа в систему (обозначается -
перед bash
)
ps faw -eo euser,ruser,suser,fuser,f,comm
покажет UID процессов:
EUSER RUSER SUSER FUSER F COMMAND
...
root root root root 4 sshd
root root root root 4 \_ sshd
rda rda rda rda 5 | \_ sshd
rda rda rda rda 0 | \_ bash
Вызов su
с последующей успешной аутентификацией приведет к следующему:
EUSER RUSER SUSER FUSER F COMMAND
...
root root root root 4 sshd
root root root root 4 \_ sshd
rda rda rda rda 5 | \_ sshd
rda rda rda rda 0 | \_ bash
root rda root root 4 | \_ su
root root root root 4 | \_ bash
Процесс 'bash' запускает новый дочерний процесс 'su' с EUID, установленным битом SetUID в '0'
(root), RUID все еще установлен в UID rda в этот момент.
Процесс 'su' снова запускает новый дочерний процесс с новой оболочкой, предоставляя пользователю доступ root (RUID теперь тоже установлен в '0'
).
Пользователь остается в своем рабочем каталоге, а новая оболочка будет использовать то же окружение, что и родительская оболочка, например:
server:/home/rda# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:/home/rda# pwd
/home/rda
Оболочку можно закрыть командой exit
, и пользователь окажется в родительской оболочке со своими первоначальными правами доступа.
Ситуация меняется, если 'su' вызывается с дефисным '-'
параметром:
rda@server:~$ su -
Password:
server:~# echo $PATH
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:~# pwd
/root
Среда оболочки изменилась, так как новая оболочка является оболочкой входа в систему, см. '-su'
, которая выполняет некоторые дополнительные скрипты конфигурации:
9151 ? Ss 0:00 \_ sshd: rda [priv]
9153 ? S 0:00 | \_ sshd: rda@pts/1
9154 pts/1 Ss 0:00 | \_ -bash
9613 pts/1 S 0:00 | \_ su -
9614 pts/1 S+ 0:00 | \_ -su
Оболочка входа в систему должна быть закрыта с помощью logout
.
Теоретически, я думаю, можно предотвратить получение пользователем повышенных привилегий, удалив sudo
и su
и не давая возможности войти в систему напрямую (через терминал, ssh и т.д.) и не имея физического доступа к устройству.
Обновление: Процесс рутинга на Android
Как подробно описано здесь, возможные методы рутинга Android-устройства зависят от загрузчика и системного свойства Android ro.secure
.
Цель всегда одна и та же - установить двоичный файл su
в /system
и сделать его setuid(0)
.
Устройство с разблокированным загрузчиком:
Вытащить стоковое ПЗУ с помощью dd
из устройства, добавить su
, перепаковать (или загрузить такое модифицированное ПЗУ), перезагрузить устройство в режиме прошивки и прошить модифицированное ПЗУ.
Устройство с ro.secure=0:
Это системное свойство контролирует, будут ли команды, набранные в adb shell
, выполняться от имени root (ro.secure=0
) или от имени непривилегированного пользователя (ro.secure=1
).
Значение ro.secure
устанавливается во время загрузки из файла default.prop
в каталоге root
, который доступен только пользователю root и, следовательно, безопасен.
В большинстве случаев этот ro.secure
имеет значение 1
, но некоторые производители устанавливают 0
. Это можно проверить, выполнив команду getprop ro.secure
в эмуляторе терминала на устройстве или в оболочке adb. Если установлено значение 0
, укоренение довольно простое, подключите устройство к компьютеру, запустите adb
, смонтируйте /system
как read-write, установите su
.
Устройство с заблокированным загрузчиком:
Такое устройство имеет recovery, который не позволяет прошить пользовательский ROM, не подписанный производителем.
Единственный способ получить root-доступ в этой ситуации - использовать уязвимость в одном из запущенных системных процессов, работающих в привилегированном режиме, и взломать его, чтобы разрешить выполнение "произвольного кода". Этот код обычно монтирует /system
и постоянно устанавливает su
.