Что бы не изобретать велосипед, первым делом начал копать интернет, в результате чего были найдены следующие варианты:
- ограничения доступа через сетевые службы ssh, sftp (не подошло)
- разграничение прав доступа самой операционной системой linux (не подошло, хотелось бы универсальное решение)
- использование chroot (не подошло)
- использование сторонних утилит, например SELinux (не подошло, усложняет систему).
В результате поиска, был найден встроенный механизм ограничения возможностей пользователя внутри оболочки bash, он называется Restricted Shell или rbash.
В нем реализованы следующие ограничения:
- нет возможности смены каталога командой cd
- нельзя сбрасывать или изменять значения переменных SHELL, PATH, ENV, BASH_ENV
- запрещено указывать команды содержащие / (косую черту)
- запрещено импортировать функции из основной оболочки
- запрещено перенаправлять вывод с использованием операторов >, <, |, <>, >&, &>, >>
- запрещено использовать команду exec для подмены команды и пр.
Есть минус, это безопасность, поэтому необходимо в обязательном порядке добавить alias на команды в файл поведения оболочки .bashrc (информация будет далее).
Конечно rbash из коробки, всех задач не решает, поэтому на примере рассмотрим создание пользователя и настройка его окружения для полного решения нашей задачи.
Далее все операции выполняются от суперпользователя (root).
1. Создаем ограниченную оболочку
echo '/bin/bash -r' > /bin/zbash
chmod +x /bin/zbash
2. Создаем пользователя
adduser --home /home/zuser --shell /bin/zbash zuser
3. Изменяем права директории
chown root.zuser /home/zuser
chmod 750 /home/zuser
4. Переходим в директорию и очищаем ее
cd ~zuser
ls -a
rm .bash*
rm .profile
ls -a
5. Настраиваем оболочку и права
echo "PATH=:/home/zuser/bin" > .bashrc
echo "alias help='echo access is limited'" >> .bashrc # alias на команду help
echo "bind 'set disable-completion on'" >> .bashrc # Отключает автодополнение на tab
mkdir -p bin
chmod 750 bin
chown -R root.zuser /home/zuser
chmod 640 .bash*
Файл .bashrc определяет поведение командной оболочки, в данный файл можно добавить alias для команд или дополнительные опции.
Для обеспечения безопасности выполните следующие команды:
echo "alias echo=':'" >> .bashrc
echo "alias cat=':'" >> .bashrc
echo "alias bash=':'" >> .bashrc
echo "alias sh=':'" >> .bashrc
echo "alias ln=':'" >> .bashrc
echo "alias set=':'" >> .bashrc
echo "alias uset=':'" >> .bashrc
echo "alias export=':'" >> .bashrc
echo "alias typeset=':'" >> .bashrc
echo "alias declare=':'" >> .bashrc
echo "alias alias=':'" >> .bashrc
echo "alias unalias=':'" >> .bashrc
Данный список можно продолжать…
6. Проверяем работу
root@host: su zuser
zuser@host: help
access is limited
zuser@host: pwd
/home/zuser
zuser@host: ls /tmp/
bash: ls: команда не найдена
zuser@host: /bin/ls
bash: /bin/ls: ограниченный режим в команде нельзя использовать косую черту {/}
zuser@host: echo $PATH
:/home/zuser/bin
zuser@host: PATH=/bin/
bash: PATH: переменная только для чтения
zuser@host: exit
7. Добавляем допустимые команды
ln -s /bin/ping /home/zuser/bin/ping
Важно, пути в команде ln необходимо указывать полностью.
8. Для ограничения опций команды можно использовать обертки
mkdir /var/scripts
echo "/usr/sbin/useradd -D" > /var/scripts/user-info
chmod +x /var/scripts/user-info
ln -s /var/scripts/user-info /home/zuser/bin/user-info
9. Для работы с файлами и папками можно также создать обертку
с черным списком (разрешить все, кроме):
— создаем файл
nano /var/scripts/ls
— содержимое файла
blacklist="\? ../ /etc /bin /boot /var"
for var in $blacklist
do
if [[ $* == *$var* ]]; then
echo 'Access is denied:' $*
exit
fi
done
/bin/ls $*
blacklist — переменная содержащая черный список директорий или файлов (через пробел)
— добавляем команду для пользователя zuser
chmod +x /var/scripts/ls
ln -s /var/scripts/ls /home/zuser/bin/ls
Данный скрипт разрешает выполнять команду ls с любыми ключами для каталогов и файлов не совпадающих с черным списком
с белым списком (запретить все, кроме):
— создаем файл
nano /var/scripts/cat
— содержимое файла
whitelist="./ /tmp/" # белый список
for var in $whitelist
do
if [[ $* == *$var* ]]; then
/bin/cat $* # запуск утилиты cat с заданными параметрами
exit
fi
done
echo 'Access is denied:' $*
whitelist — переменная содержащая белый список директорий или файлов (через пробел)
— добавляем команду для пользователя zuser
chmod +x /var/scripts/cat
ln -s /var/scripts/cat /home/zuser/bin/cat
Данный скрипт разрешает выполнять команду cat с указанными файлами в белом списке
Готово, в итоге получили следующий результат:
- мы создали пользователя zuser с оболочкой rbash
- отключили возможность использования автодополнения в консоли
- zuser может запускать утилиты только из директории /home/zuser/bin
- добавили пользователю zuser команду ping
- добавили пользователю zuser собственную команду user-info
- пользователю zuser ограничили через обертку выполнение команд ls и cat
Данный способ к сожалению не гарантирует 100% безопасность, и при определенных знаниях и квалификации пользователь может покинуть данную оболочку. Спасибо Jouretz arheops YaDr они в комментариях привели примеры обхода ограничений оболочки.
В данном решение существуют следующие уязвимости (Shell Escape), которые необходимо обязательно учитывать:
PATH | Возможность изменить переменную PATH |
Копирование файлов по scp | Возможность загрузить свой скрипт |
При подключении по ssh можно изменить оболочку |
|
При подключении по ssh можно изменить файл конфигурации оболочки |
|
При подключении по ssh можно использовать ShellShock |
|
Через утилиты vi, vim |
|
Через утилиты vi, vim |
|
Через утилиты man, more, less |
|
Через утилиту find |
|
Через утилиту awk |
|
Через утилиту nmap |
|
Через утилиту nmap |
|
Через perl |
|
Через python |
|
Через ruby |
|
В связи с наличием достаточно большого количества уязвимостей, данный способ можно использовать только для локального пользователя на не критических системах, для доступа по сети через ssh лучше использовать chroot или другие утилиты ограничения возможностей пользователей.
Надеюсь данная информация будет полезной.
Комментарии (60)
Jouretz
27.01.2019 17:49+8Костыли в безопасности — самые опасные среди костылей.
Если у юзера есть доступ к чему-то из [man, vim, more, less, awk, zip, tar, git...] то он выходит из ваших ограничений. Если нет, не особо понятно, что он там вообще делает? Мб доступ к шелу можно было заменить одной формой или чем-то подобным?KeyMan Автор
27.01.2019 21:33Спасибо за вопрос, он действителен важен.
На сколько я знаю основные атаки заключается в следующем:
— изменить переменную PATH
Для блокировки данной уязвимости мы добавляем alias в файл .bashrc:
alias set=':'
alias uset=':'
alias export=':'
alias typeset=':'
alias declare=':'
alias alias=':'
alias unalias=':'
— переход в полноценную оболочку через скрипт или через утилиты vi, vim, nano, awk и т.д
Так же можно защитится через alias в файле .bashrc:
alias bin=':'
alias sh=':'
alias ln=':'
— также, для дополнительной защиты все команды через которые можно получить доступ к файлу или выполнить скрипты необходимо делать через обертки (п.8, п.9)
Если есть еще варианты взлома, напишите пожалуйста.Jouretz
27.01.2019 21:47+3А вы тестили? Я смотрю, у меня vim алиасы не воспринимает.
:!ll который алиас не отработал
:!ls — работает
:!/bin/sh — запускает shell
Ну и как вариант — атака через ssh
awk 'BEGIN {system("/bin/sh")}' такая ещё штука. Смотря что у вас там доступно.
selivanov_pavel
28.01.2019 00:07+2Если find доступен, можно с awk и не заморачиваться:
find . -maxdepth 0 -execdir /bin/bash \;
Sjam
27.01.2019 17:52+5Как-то chroot для этих целей кажется проще и уместнее
KeyMan Автор
28.01.2019 13:39Возможно, только я не разобрался как сделать chroot для локального пользователя (по ssh без проблем), буду признателен если подскажите как это лучше сделать.
arheops
29.01.2019 00:19Все просто. Делаете какойто скрипт который делает chroot, выставляет нужные переменные и запускает shell.
называете его /bin/chrootedshell
выставляете пользователю shell в этот скрипт. все.
andreymal
27.01.2019 18:34+2Во-первых, уверен, это всё можно обойти, если покопаться повнимательнее.
Во-вторых, а зачем такой урезанный доступ вообще нужен? У меня не получается придумать практических применений для этого.
tchspprt
27.01.2019 19:18-1Как минимум есть одно.
И на первый, и на второй вопрос ответ — учебный курс по администрированию / инфобезу / etc. Отрестриктить так, чтобы фиксить трабл не получилось с помощью service restart / shutdown now / других нетрушных методов (я надеюсь Вы поняли). А если речь идёт о курсе по инфобезу — то за обход защиты от плюсика в карму до автомата (в зависимости от глубины курса, доброты преподавателя, остальной аудитории).Jouretz
27.01.2019 19:39+2Я, конечно, дико извиняюсь. Но учебный курс teaching to use bad practices это просто bullshit. И если teacher doesn't understand what в информационной безопасности нужно в первую очередь использовать appropriate methods для решения конкретных tasks, то его профпригодность is questionable.
mk2
27.01.2019 21:06Я am очень sorry, но mixing английские words с russian аналогами is плохая practice сама по itself.
tchspprt
27.01.2019 21:41Bad practices — то, что ждёт рядового студента в будущем ежедневно. Если говорить о программировании, например, то переписывание легаси-кода — это то, за что с наибольшей вероятностью прошлый студент покупает хлеб. Быть знакомым с врагом заранее — неплохой вариант, вообще-то.
tchspprt
27.01.2019 22:07Так, падажжите… профпригодность is questionable, говорите? То бишь такие вещи придумывают низкоквалифицированные идиоты, которых Вы можете так же тончайше и остроумнейше высмеять, как меня?
keydon2
27.01.2019 20:58+1Создать по контейнеру на каждого пользователя и пускай творят что хотят до желаемого результата?
tchspprt
27.01.2019 21:35Не всегда покатит. Я не спец, но похожий на правду пример «непокатимости» могу привести.
Например, при изучении раздела загрузки ОС — задача на GRUB, нужно изменить ключи загрузки. Тяжело сформулировать конкретную задачу, но можно перекрыть возможность mkinitrd — закрыть простой путь. Да, конкретно в этой задаче содержимое статьи — вряд ли лучший инструмент, достаточно какого-нибудь SELinux, наверное. Но в общем в любом случае задача, в которой инструмент встанет, может всплыть.
KeyMan Автор
27.01.2019 21:511. Скорей всего, все можно обойти) По тем способам, которые я знаю мы немного защитились, а по остальным нужно смотреть
2. Примеры использование:
— дать доступ к системе людям со стороны, что бы не сломали и можно было контроллированно ограничить их действия
— передача настроенной системе пользователям, что бы могли ее использовать и не сломали (ограничить доступ к критическим файлам и директориям)
Данная задача возникает, если мы считаем что пользователь системы может ее сломать)
skymal4ik
27.01.2019 18:56+1Был у меня похожий заказчик.
Хотел, чтобы люди, работающие по vpn по RDP из дома на 1С-сервере не могли шарить друг с другом файлы и вообще не знали о существовании других пользователей. И чтобы у каждого пользователя минимум прав и отчёты получать кто что сделал.
Намучался уже в самом начале, так что потом вообще отказался от работы. Надеюсь работники тоже отказались работать в таких условиях.
Это я к тому, что безопасность это здорово, но не должна она лишать свободы и комфорта. Надо к работникам относиться как к людям, и не сажать их в клетки.
У вас нету варианта дать человеку виртуалку и пушить работу в гит/вики или вызывать скрипты через веб, например?ni-co
27.01.2019 19:11А, что они у Вас по RDP сразу в программу 1 С не входят?
Жесткий сценарий входа.
KeyMan Автор
27.01.2019 22:01Задача передать готовую систему, что бы пользователь мог ее контролировать и выполнять минимальные действия. Дело в том, что уровень знания пользователя неизвестен и он может что-то сломать. Искать что он сломал трудоемко, быстро починить можно только откатив систему, что бы минимизировать данные риски решили урезать возможности пользователю.
hokum13
28.01.2019 13:53Я чего-то не понимаю:
а что мешает пользователю дать просто урезанную учетку — не рута. Он же и так мало что сможет. «От дурака» это спасет. А от квалифицированного хакера, который не просто скрипт-кидди и отдельная_виртуалка/chroot/контейнер не факт что защитит.
Не понимаю, если честно, сценарий от которого нужно защититься. Слишком абстрактно.
Andronas
27.01.2019 21:20-1Подобный способ (restricted shell) есть также и в AIX, использую данный способ ограничения для некоторых пользователей уже давно.
arheops
27.01.2019 21:24+2Чем вам selinux и chroot то не подошло?
Напишите список утилит в вашем /home/user/bin, мы вам сообща напишем, как обойти вашу «защиту».
Вот так обходится ваш блеклист к ls, например(проверил)
ls /\?in
KeyMan Автор
27.01.2019 22:10Очень интересно, согласен что 100% защиты конечно же нет, но Ваш пример добавим в blacklist.
Спасибо.Sap_ru
27.01.2019 22:41+3Вы не сможете соcтавить нормальный black-list — слишком много способов. И по мере обновления системы будут появляться новые. Сам способ уже очень кривой.
KeyMan Автор
27.01.2019 22:50Согласен, данный способ сделан на коленке в качестве примера. По сути надежный способ нужно продумывать и разрабатывать, это отдельная задача.
arheops
28.01.2019 00:33+3Это фигня. Либо вы делаете whitelist либо ничего не делаете.
Существуют миллиарды комбинаций, шел сильно мощная штука.
Все уже придумано до вас, используйте chroot.
Если вам в chroot надо чтото прокинуть — используйте pipes/hardlinks.KeyMan Автор
28.01.2019 10:47-2один whitelist лист, к сожалению не поможет, можно использовать такую комбинацию:
cat /home/zuser/../../etc/passwd
Данную угрозу можно конечно снизить совместив blacklist и whitelist, но как Вы правильно заметили, всех возможностей учесть достаточно сложно.Sap_ru
28.01.2019 18:18Вы сначала рута получите для таких фокусов (не говоря о том, что конкретно ваша команда давно уже не работает таким образом).
А если у вас рут есть, то вам уже ничего большле не нужно. И уж точно никакой restricted шел рута не остановит никогда. Тут только всякие SELinux.
arheops
28.01.2019 07:43Ну вот вы добавили в блеклист.
Давайте дальше, чтоли «добавляйте»
ls /\[b\]in
ls /\[a-z\]in
ls /\[a-b\]in
ls /\*in
Логичнее было добавить обратный слеш, но есть еще другие варианты.
И это только один вид атак — регекспы.
Sap_ru
27.01.2019 22:40+7Зашибись безопасность!
Извените, но этот подход совершенно бесполезен. Тут сходу десякти способов запустить полноценный шелл можно придумать. А если вы начнёте эти способы ограничивать (через chroot, права, ещё что-то), то на фига этот недо-шелл вообще нужен?tyderh
28.01.2019 02:05+3Да. Вредная статья. Мне как-то давали подобный rbash, чтобы я не лазил где попало. Даже обходить ничего не пришлось, залил при помощи scp нормальный шелл в одну из разрешенных утилит и вперед, лол.
selivanov_pavel
28.01.2019 00:16В защиту автора: ограниченный шелл как способ обеспечения безопасности от целенаправленного взлома, разумеется, плох. Но может использоваться как способ дать доступ младшем персоналу для выполнения какого-то ограниченного списка команд, с уменьшением риска случайно выстрелить себе в ногу.
funca
28.01.2019 01:53+1Был у нас заказчик как раз с такой фигнёй на серверах. Все понимал, но ни как не мог повлиять на тамошних админов, нагородивших этот странный огород. Сошлись на том, что кастыль для доступа к командам shell через консольный mysql вкрутили даже в ansible.
inkvizitor68sl
28.01.2019 15:06+1Правильный ответ — jailkit.
Rbash действительно дырявенький с этой точки зрения. Ну то есть сам по себе rbash хорош и задачу (свою!) выполняет, но его задача — не совсем в области безопасности, а как верно замечают выше — скорее, чтобы у неопытных пользователей консоли глаза от обилия бинарников не разбегались.
jenki
28.01.2019 23:21использование сторонних утилит, например SELinux (не подошло, усложняет систему)
useradd -c «User with the limited rights» -Z guest_u -m -U -s /bin/bash user
passwd user
Вот весь SELinux
nApoBo3
Не очень понимаю как это ограничивает права пользователя и зачем это вообще может быть нужно?
Разве что для создания ограниченных шелов для младшего ит персонала.
KeyMan Автор
Примеры использование:
— дать доступ к системе людям со стороны, что бы не сломали и можно было контроллированно ограничить их действия
— передача настроенной системе пользователям, что бы могли ее использовать и не сломали (ограничить доступ к критическим файлам и директориям)
Данная задача возникает, если мы считаем что пользователь системы может ее сломать)
nApoBo3
Проблема в том, что ваш способ вообще ничего не ограничивает. К безопасности он не относиться никаким боком.
Я даже не знаю как корректно объяснить. Это не безопасность. Вы никак не ограничили права пользователя в системе, вы настроили, даже не безопасность, а интерфейс шела, примерно как удалить все ярлыки с рабочего стола и считать, что теперь все в безопасности.
Можно сказать, это один из вариантов UAC или SU( хотя сравнение не корректное, там все таки ограничения безопасности ), чтобы случайно чего-то не поломать, не более того.
Возможно это имеет смысл, чтобы дать не сильно квалифицированному пользователю возможность запустить самостоятельно ping на сервере который стоит у него в помещении и прочитать вывод администратору. Но для таких задач можно например использовать веб странички с небольшим кол-во команд, и вообще не давать пользователю логиниться на сервере.
Любой человек обладающий минимальной квалификацией и имеющий желание выйти из вашего окружения сделает это за несколько минут, ну может не минут, но не более получаса.
Самый простой вариант, ваш zuser может писать, а значит может залить туда произвольный код и выполнить его, не какой шел в данном случае не задействует.
KeyMan Автор
Согласен, изначально идея была дать оболочку которая ничего не умеет и только после этого добавлять в нее инструменты и тут кроется камень преткновения безопасности — эти инструменты пользователь может использовать для выхода за пределы оболочки.
т.е. Для пользователя создана металлическая коробка и он в нее помещен, но для работы ему нужна болгарка, ты ему ее даешь, и вместо того что бы пилить детали внутри коробки, он начинает пилить саму коробку.
imanushin
Подходит другая аналогия: чтобы защитить сейф, все подходы к банку Вы сделали в виде лабиринта. В итоге сейф унести все равно можно (в том числе — и на вертолете), а вот людям стало жить сложнее.
Практический разговор о безопасности системы надо начинать с big bounty: то есть сколько Вы готовы отдать за дыру в системе. Если разработчик бритая пообещать даже малую сумму, то отсюда неутешительный вывод отрельном положении дел.
И если подытожить — правильнее называть подобное не «ограничение прав», а «защита от дурака». То есть специалист все равно выломает, однако случайный пользователь теперь случайно навредит с меньшей вероятностью.
bano-notit
Иногда нет возможности использовать ansible shell, приходится использовать прямой доступ по ssh для маленького CD. А чтобы компрометация ssh ничего не дала взломщику, можно максимально ограничит аккаунт.
Но согласен, легче всё же просто ограничить доступ пользователя исполнением одного единственного неизменяемого скрипта.