我正在寻找一种方法,允许用户通过(或其他机制?)安装(仅远程)包,apt-get
但不允许用户以 root 身份运行任意命令。
我可以得到一些通过 /etc/sudoers 到达那里。假设我的 /etc/sudoers 文件中有这个
root ALL=(ALL:ALL) ALL
john ALL=NOPASSWD:/usr/bin/apt,/usr/bin/apt-get
然后 John 似乎只能通过 运行和apt
。但是……似乎有办法以root 身份退出到 shell(apt-get
sudo
apt-get
https://blog.ikuamike.io/posts/2021/package_managers_privesc/):
- 输入
sudo apt-get changelog apt
并按回车键 - 输入感叹号
!
并按回车键 - 你现在以 root 身份进入 shell,可以执行任何操作
或者运行以下命令:
sudo apt update -o APT::Update::Pre-Invoke::="/bin/bash"
如果有什么不同的话,这是在 Docker 中
发布日期https://superuser.com/q/1698692/315568,但我认为那是错误的网站,因为这不(仅仅)适用于我的机器,也适用于其他机器
答案1
这sudoers
手册中还有一整节内容,介绍/etc/sudoers
配置文件中的适当策略(或者当然是包含的插入式策略文件)如何提供有限的防止炮弹逃逸使用RESRICT
和NOEXEC
选项。
这可能比创建包装脚本用于特定的实用程序。
restrict
避免让用户访问允许用户运行任意命令的命令。许多编辑器都具有禁用 shell 转义的限制模式,尽管 sudoedit 是通过 sudo 运行编辑器的更好解决方案。由于提供 shell 转义的程序数量众多,限制用户只能使用不提供 shell 转义的程序集通常是行不通的。
和
noexec
许多支持共享库的系统都能够通过将环境变量(通常是 LD_PRELOAD)指向备用共享库来覆盖默认库函数。在这样的系统上,sudo 的noexec
功能可用于阻止 sudo 运行的程序执行任何其他程序。注意,... ...
要启用noexec
命令,请使用NOEXEC
上面“用户规范”部分中记录的标签。以下是该示例:
aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
这允许用户 aaron 运行/usr/bin/more
并/usr/bin/vi
启用 noexec。这将阻止这两个命令执行其他命令(例如 shell)。
因此在您的示例中:
john ALL=NOEXEC:NOPASSWD: /usr/bin/apt,/usr/bin/apt-get
应该足以仍然允许用户john
运行apt
并apt-get
以提升的权限,而无需提示输入密码,也无需使用 shell 转义或其他技巧超出其权限范围。
请注意,这样做也可能产生意想不到的结果。例如,安装新服务后,apt 可能无法启动相关服务。
答案2
这是我的尝试,因此用户将习惯sudo
运行此脚本,但不能运行其他脚本。
#!/bin/bash
# This script wraps `apt update` and `apt install`, but attempts to forbid
# arbitrary commands being able to be run by the user as root. It exists
# because allowing the user to `sudo apt` would allow
# `sudo apt changelog apt`, which runs `less` which then would allows the
# user to escape into the shell.
# But, full access to `apt update` and `apt install` still cannot be given,
# since there are 3 ways they can be used to run arbitrary commands
#
# 1. Via options in the APT_CONFIG environment variable
# 2. Via command line options, such as '-o' to specify scripts to run
# 3. Via a local package that contains custom install script(s)
#
# So this script attempts to forbid the 3 above possibilities
# 1. Clear any options in the APT_CONFIG environment variable
export APT_CONFIG=''
# 2. and 3. Forbid command line options or local packages
for var in $*
do
if [[ ${var::1} == "/" || ${var::1} == "." || ${var::1} == "-" ]]
then
echo "E: It's forbidden to install a local package or pass an option"
exit 1
fi
done
# Update, and install requested packages
apt update
apt install -y $*