diff options
Diffstat (limited to 'informationals/teso-i0024.txt')
| -rw-r--r-- | informationals/teso-i0024.txt | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/informationals/teso-i0024.txt b/informationals/teso-i0024.txt new file mode 100644 index 0000000..b3fe037 --- /dev/null +++ b/informationals/teso-i0024.txt | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | 0024 2000/05/06 chroot break possibilities overview | ||
| 2 | |||
| 3 | ==== TESO Informational ======================================================= | ||
| 4 | This piece of information is to be kept confidential. | ||
| 5 | =============================================================================== | ||
| 6 | |||
| 7 | Description ..........: chroot break possibilities overview | ||
| 8 | Date .................: 2000/05/06 13:00 | ||
| 9 | Author ...............: scut | ||
| 10 | Publicity level ......: known | ||
| 11 | Affected .............: most OS's offering the chroot() system call | ||
| 12 | Type of entity .......: access elevation | ||
| 13 | Type of discovery ....: useful information | ||
| 14 | Severity/Importance ..: low | ||
| 15 | Found by .............: original discovery unknown, OS data by vax and teso | ||
| 16 | |||
| 17 | =============================================================================== | ||
| 18 | |||
| 19 | Most Unix operating systems offer the chroot() system call. With it the root | ||
| 20 | pointer of the filesystem can be changed for one process, so only parts of the | ||
| 21 | filesystem are still visible to it. This is useful for some daemons, which | ||
| 22 | would have access to the whole filesystem in case their security breaks. | ||
| 23 | However to properly allow the chroot() idea to work, two things must be done | ||
| 24 | directly after the chroot() call: a chdir to the chroot'ed directory must be | ||
| 25 | done and the superuser privileges have to be dropped. | ||
| 26 | |||
| 27 | The first condition, the change dir to the chroot directory is required because | ||
| 28 | the current working directory is still outside of the chroot directory and the | ||
| 29 | OS will treat any process which is outside of it's chroot pointer as if the | ||
| 30 | chroot doesn't exist. Once it is inside this will change and the process can | ||
| 31 | not escape from the directory. The dropping of the superuser privileges has | ||
| 32 | another cause, since only the root user can issue chroot() system calls, he | ||
| 33 | may be able to issue chroot() calls even when inside the chroot directory, | ||
| 34 | this has to be disabled by dropping the privileges. | ||
| 35 | |||
| 36 | The trick to break chroot() is just working under UID 0 and works as this: | ||
| 37 | |||
| 38 | /* chroot + chdir */ | ||
| 39 | chroot ("/tmp"); | ||
| 40 | chdir ("/tmp"); | ||
| 41 | |||
| 42 | /* now we're jailed in /tmp, so our root / is actually /tmp */ | ||
| 43 | /* create a subdirectory */ | ||
| 44 | mkdir ("foobar", 0700); | ||
| 45 | |||
| 46 | /* chroot to this subdirectory */ | ||
| 47 | chroot ("foobar"); | ||
| 48 | |||
| 49 | /* now we're outside of the chroot'ed environment, so we cd up */ | ||
| 50 | /* to the root directory */ | ||
| 51 | for (i = 10 ; i > 0 ; --i) | ||
| 52 | chdir (".."); | ||
| 53 | |||
| 54 | /* now undo the whole chroot mess */ | ||
| 55 | chroot ("."); | ||
| 56 | |||
| 57 | As you can see we first get outside of the change root directory not by | ||
| 58 | changing or working directory (because we can't do that), but by changing | ||
| 59 | the chroot directory itself to a subdirectory. For this operation we need | ||
| 60 | root privileges. Since we are outside the chroot environment we can freely | ||
| 61 | move our working directory except into the chroot()'ed one, which would | ||
| 62 | limit us again. Once we are at the root directory we chroot to it to undo | ||
| 63 | the whole mess created earlier. | ||
| 64 | |||
| 65 | Who discovered this nice trick in the first place is unknown, if you know | ||
| 66 | it please contact me. | ||
| 67 | |||
| 68 | Unfortunatly this does not work on all operating systems. Here is a list of | ||
| 69 | operating systems and whether they allow this. Thanks to vax, skyper, doze and | ||
| 70 | various other people to help compiling this data. | ||
| 71 | |||
| 72 | Operating System break successful | ||
| 73 | ------------------------------------- ----------------- | ||
| 74 | AIX 4.1.5 no | ||
| 75 | AIX 4.3.3 no | ||
| 76 | FreeBSD 2.2.8-STABLE yes | ||
| 77 | FreeBSD 4.0-RELEASE no | ||
| 78 | IRIX 5.3 yes | ||
| 79 | IRIX 6.4 yes | ||
| 80 | IRIX 6.5 yes | ||
| 81 | Linux 2.0.x yes | ||
| 82 | Linux 2.2.x yes | ||
| 83 | Linux 2.3.x yes | ||
| 84 | OpenBSD 2.6 no | ||
| 85 | OpenBSD 2.7-beta no | ||
| 86 | SunOS 5.5 yes | ||
| 87 | SunOS 5.5.1 yes | ||
| 88 | SunOS 5.6 yes | ||
| 89 | SunOS 5.7 yes | ||
| 90 | ------------------------------------- ----------------- | ||
| 91 | |||
| 92 | If you have test data that isn't in the list yet, please mail it to me. | ||
| 93 | (scut@nb.in-berlin.de) | ||
| 94 | |||
| 95 | ADDENDUM: | ||
| 96 | (from a mail send to HERT mailinglist about 7350wu chroot breaking code. | ||
| 97 | smiler thinks this does not work on normal chroot-scenarios, but | ||
| 98 | nevertheless I include it for the archives ;) | ||
| 99 | |||
| 100 | Date: Tue, 19 Sep 2000 00:16:30 +0200 | ||
| 101 | From: Kalou <pb@hert.org> | ||
| 102 | To: hert@hert.org | ||
| 103 | Subject: [HERT Private] drunk again | ||
| 104 | |||
| 105 | Just to restate some things clearly : | ||
| 106 | |||
| 107 | linux/7350wu/7350wu.c: unmodified: line 142 of 1450 [9%]. | ||
| 108 | |||
| 109 | /* break chroot and exec /bin/sh - dont use on an unbreakable host like 4.0 */ | ||
| 110 | |||
| 111 | I wish i could reach [-sc. & z-.] =) | ||
| 112 | |||
| 113 | As i may have posted some time ago, freebsd chroot() is breakable | ||
| 114 | even with FreeBSD 4-0.. In 4.0, they forbid a chroot() with an open | ||
| 115 | file descriptor pointing to a directory *but* they forget to call | ||
| 116 | chdir() from within chroot(). So anything you need to break it is | ||
| 117 | to chroot() without having done an open("."..) and to chdir("../../../..") | ||
| 118 | immediatly after. Shortly, just remove open(".") and fchdir() from your | ||
| 119 | eggshells. This works with older releases, too. | ||
| 120 | |||
| 121 | I didn't see many public chroot breaking techniques not involving this | ||
| 122 | fchdir() trick, that is necessary only for O.S. that chdir() when you | ||
| 123 | call chroot(). | ||
| 124 | |||
| 125 | Anyway don't forget chroot() allows mknod(). | ||
| 126 | |||
| 127 | This was tested on: | ||
| 128 | |||
| 129 | FreeBSD eclipse 4.0-RELEASE FreeBSD 4.0-RELEASE #4: Sat Aug 19 22:08:48 CEST 2000 | ||
| 130 | root@eclipse:/usr/src/sys/compile/ECLIPSE alpha | ||
| 131 | |||
| 132 | Just please correct this if i'm wrong. | ||
| 133 | |||
| 134 | |||
| 135 | =============================================================================== | ||
| 136 | |||
