chroot主要的功能是改变根目录,之前是在ctf出题时会将/home/ctf目录chroot成为根目录,实现与我们docker的文件系统隔离,提供一个安全的靶场环境。在模拟运行固件的时候,也经常会将当前文件系统的目录chroot为根目录,这样才能找到固件所需库的路径。
然而这个东西并不安全,常用的工具chr00t
chroot jailbreak条件
- root权限
- 可以进行open,chdir,chroot,mkdir等系统调用
满足以上条件就可以达到chroot jailbreak
cwd 与 root
对于我们当前的path路径,一般proc采用了两个成员来表示
- cwd 当前目录,也就是我们目前位于的工作目录
- root 根目录
一般情况下我们cwd的当前目录是不允许访问root意外的路径的。
chroot jailbreak 原理分析
了解了以上两个概念我们就可以深入理解chroot jailbreak的原理了
ksys_chroot
chroot功能实现的核心在set_fs_root,主要是将当前进程的的root
设置为了传入的参数path
。并且通过源码分析得知,chroot只改变了root但是并没有改变cwd。
1 | int ksys_chroot(const char __user *filename) |
set_fs_root
set_fs_root
是通过改变fs->root
实现了改变当前进程文件系统root
的功能
1 | /* |
在设置了root后,一般情况下我们访问当前文件系统下的文件有两种方式。
- 绝对路径。如果采用绝对路径就会默认从我们刚设置的根目录开始寻找,这种方法是没办法访问根之外的文件的
- 相对路径。以当前cwd为开始目录,去寻找我们要访问的文件。
看起来好像都没什么问题,那么如果我们 cd ..
呢,向上寻找的时候内核是怎么判断让他不逃出root的呢,
follow_dotdot_rcu
看一下主要处理cd ..
的处理逻辑,发现核心处理逻辑就是判断当前path是否和root相等,如果相等就不能继续向上找,如果不相等那就无所谓,可以继续向上找。
1 | static struct dentry *follow_dotdot_rcu(struct nameidata *nd) |
那么按照这个逻辑,只要我们当前的cwd不处于root之下,就可以一直cd..
最终逃出chroot
。
示例
1 |
|