6 ms·
i often wondered how exactly one can escape from a chroot but never really tried or read that man page until now. I tried the above and it did not work as descr
by mercora 7y ago
i often wondered how exactly one can escape from a chroot but never really tried or read that man page until now. I tried the above and it did not work as described. I tried both changing to the parent directory directly after chroot and chrooting inside the chroot and doing it then.
Edit:
Now that i really read that page i realized 2 things, first this page is about the syscall and not the command and second it says the syscall itself does not change the current directory to the provided path. I guess the chroot command does just that and this is why it did not work as described. The example given literally still does not work as advertised.
- cyphar 7y agoThis is the more correct escape (EDIT: and works today): fd = open(".", O_PATH); chroot("foo"); fchdir(fd); // escaped to "." and chroot no longer blocks ".." past "/" chdir("../../../../"); // go to real "/" chroot("."); // broken out The "chdir .." trick used to work a long time ago. The man page probably hasn't been updated in ~20 years.
- mercora 7y agoto be clear, neither will work on a reasonably modern system?
- Vogtinator 7y agoNot really an issue. If there's an fd pointing outside of the chroot, of course it's possible to do stuff outside of it. That with a path FD a total escape is possible isn't that obvious, but not unexpected.
- cyphar 7y agoWell, it is an issue if you can use it to break out of containers that use --no-pivot-root (you can). fd-related escapes are possible for pivot_root(2) but are usually not as trivial as the one for chroot(2). Also there are other attacks against chroot(2) which don't make use of fd-related escapes (nd->root protections in pathname lookup are very minimal and there are lots of ways to trick them).
- Carpetsmoker 7y agoThis progam is bugged as you're relying on file pointer aquired before the chroot.
- cyphar 7y agoImagine this program was running within a chroot(2) that it didn't set up. You can nest a chroot(2) and break out -- that was the point I was making.
- raimue 7y agoNo, nested chroots do not change anything here. In your example, you would always need to acquire a file descriptor outside the current chroot first. Then such a file descriptor has to be passed over some mechanism into the process running in the chroot. For that, you would definitely need help from some other process running outside the chroot. Breaking out a chroot on Linux is not as trivial as you present it.
- cyphar 7y ago> In your example, you would always need to acquire a file descriptor outside the current chroot first. The attack is the following: 0. Process is running in a chroot. 1. Process opens a handle to ".". 2. Process chroot()s to a directory underneath ".". 3. Process chdirs to handle made in (1). 4. Process chdirs to ".." a bunch of times. 5. Process chroot()S to "." which is the host "/". Yes, this requires CAP_SYS_CHROOT (and this is why user namespaces don't work in a chroot -- because breakouts would be trivial). But as I mentioned above there are other VFS-related attacks which are a bit too complicated to get into in a HN comment (they involve RENAME_EXCHANGE and other such fun tricks). But it doesn't require another process to help you. Seriously, just try it.
- raimue 7y agoI would not see this as breaking out of a chroot, because your process already had the file descriptor handle before the chroot system call. Being able to access files that were opened before the chroot call is an intentional feature and used to limit access to a specific set of files.
- davrosthedalek 7y agoJust to make sure I understand what's happening here: 1) a direct chroot("../../../") would not work, as the kernel restricts ../ to / if at the chroot-root. 2) chroots are not nested. 3) By making a handle to a path, then chrooting, the security measure 1) is disabled for that handle (as it's outside of the current chroot), and the kernel doesn't keep track that it was created in an earlier chroot. Is that right?
- cyphar 7y ago(1) is mostly right. The actual restriction is that ".." will be a no-op if the current directory is equal to nd->root (what your current root is). (2) Yes, each process only has one root at a time. (3) The restrictions don't apply to file handles at all (an fd doesn't know what chroot it was created in). Instead what happens is that the restriction in (1) is useless once the current directory of the resolution is above the nd->root (after all, a directory above nd->root is not equal to nd->root).
- davrosthedalek 7y agoAh, thanks I think I got it now. That's indeed trivial to execute as long as one still can do chroot.