ОБЯЗАННОСТИ И ОТВЕТСТВЕННОСТЬ АДМИНИСТРАТОРА ПОДДЕРЖКА БЕЗОПАСНОСТИ В СИСТЕМЕ ТИПИЧНЫЕ ПРОБЛЕМЫ БЕЗОПАСНОСТИ access показ всех беспарольных входов в систему chkset проверка наличия в системе файлов с разрешенной установкой идентификатора пользователя или группы suw отслеживание нарушителей по протокольному файлу команды su ----------------------------------- Вашу карьеру в системе UNIX в качестве ученика (стать бы поско- рее мастером!) можно представить себе в виде трех ступеней квалифика- ции. Первая ступень - посвящение в работу системы UNIX в целом, осо- бенно изучение ее сердцевины - файловой системы. Первые три главы заложили этот фундамент и предоставили практические инструментальные средства для обслуживания системы. Вторая ступень мастерства - под- держка вашей собственной работы и персональной среды - рассматривает- ся в главах с четвертой по шестую. В главах 7 и 8 более подробно рассматриваются два специальных аспекта практической работы с систе- мой UNIX - устройства и коммуникации. Теперь мы готовы достичь третьей ступени мастерства - курировать работу самой системы, что более прозаически называется системным ад- министрированием. Если вы в настоящий момент такой пользователь, который занимает- ся программированием, или если вы все время работаете системным прог- раммистом, то вас может удивить, зачем вам становиться на точку зре- ния системного администратора и овладевать его основными инструментами работы. На это имеется две серьезные причины: знание и необходимость. Системное администрирование требует близкого знакомства с тем, где и что находится в системе, и понимания взаимосвязи конкретного процесса с системой в целом. Программисты стремятся нахвататься све- дений о чудесах и результатах таинственных команд и о всяческих хит- ростях, которые они считают полезными, но зачастую они не хотят тра- тить время на знакомство с системой UNIX в целом. Мы бы хотели сагитировать вас на более систематическое изучение системы UNIX с той целью, чтобы вы могли открыть для себя новые кладовые знаний. Вот по- чему на протяжении данной книги мы создавали инструментальные средс- тва, которые не только делают полезные вещи, но и помогают вам изу- чать саму систему. Необходимость знать администрирование становится ощутимой, когда вы обнаруживаете, что вам вдруг задали работу системного администра- тора или администратор ушел в отпуск, что пользователи выстроились возле ВАШЕГО стола в ожидании помощи, поскольку вас считают признан- ным авторитетом. Другой причиной возникновения необходимости может быть то, что вы стали безраздельным хозяином вашей собственной микро- ЭВМ с системой UNIX и хотите все установить и поддерживать по своему вкусу. Взгляните на такую необходимость администрирования как на воз- можность накопить обширные и доскональные знания о UNIX, которые мо- гут сослужить вам добрую службу в вашей будничной работе с компьюте- ром. Быть мастером UNIX - дело чести и технической грамотности. Пыта- ясь удовлетворить требованиям необходимости, мастера UNIX учатся пос- певать за потоком необходимых им знаний. Мастера UNIX не только хоро- шо играют, но и просчитывают игру на один ход вперед. ----------------------------------------------------- Положение системного администратора таково, что требует более широкого понимания системы, чем необходимо пользователю или даже программисту, и в связи с этим большей ответственности. Способность всех, кто не сильно знает UNIX, выполнить свою работу, зависит от способности администратора поддерживать работоспособность системы, предвидя и разрешая проблемы до того, как они станут опасными. Одним из наиболее важных вопросов администрирования является бе- зопасность. Сведения о безопасности, представленные здесь, были на- коплены в результате работы с администраторами, работы в качестве ад- министратора и иногда необходимости работы при наличии несогласованно действующих администраторов. Помимо безопасности, рассмотрены некоторые из более общих вопро- сов деятельности администратора. Немногие руководства и книги учат, как быть администратором. Эти навыки в основном приходят с опытом. Ваша конфигурация системы, потребности пользователей и приоритеты все вместе оказывают влияние на то, как вы справляетесь с административ- ными задачами. Мы поможем вам показом инструментальных средств и трю- ков, рассказом историй о ловушках и капканах и рассмотрением различ- ных подходов, работающих в реальной практике. ---------------------------- В большинстве больших компьютерных систем администраторы весьма уважаемые люди. Они отвечают за поддержание работоспособности вычис- лительной системы 24 часа в сутки, наращивание ее в случае необходи- мости, помощь пользователям в разрешении их проблем, патрулирование и обеспечение безопасности. Администрирование - это фактически несколь- ко разных работ в одной. Мы собираемся подробно рассмотреть каждую из этих областей, а затем предложить помощь и инструментальные средства для овладения администрированием. Поддержка работоспособности системы - приоритет номер один. Это означает нечто большее, чем просто избегать сокрушительных системных крахов, хотя важность их недопущения очевидна. Обеспечение работоспо- собности системы требует также профилактических мер. Одно из лучших занятий для вас после того, как вы завершите первое прочтение данной книги,- вернуться в ее начало и рассмотреть изложенные в ней идеи и инструментальные средства с точки зрения администратора. Например, рассмотрение того, как правильно реализовать резервное копирование файлов и сборку мусора (см. главу 3), может помочь предотвратить сис- темные крахи, вызванные условиями переполнения. Если же крах все-таки произойдет, то такое рассмотрение позволит вам восстановить все дан- ные настолько быстро и полно, насколько это возможно. По мере того, как все больше и больше людей эксплуатируют систе- му, требуется все больше ресурсов, но вы можете также найти способы использования имеющихся ресурсов с большей эффективностью. Разрабаты- вая способы повышения производительности системы, вы найдете для себя много полезного в инструментальных средствах, представленных в главе 3. В системе UNIX редко хватает принтеров, дисковых устройств, после- довательных портов, сетевого оборудования и т.п., но более эффектив- ное применение может помочь решить те же задачи без добавления новых ресурсов. По всей видимости, наиболее важным ресурсом является время цент- рального процессора. Посадите тридцать пользователей в системе, расс- читанной на двадцати четырех - и вы сразу почувствуете нехватку про- цессорного времени. В работу администратора входит поддержка текущих ресурсов, а также планирование роста системы на будущее. Поэтому тре- буется, чтобы вы знали типичные раскладки использования вашей систе- мы, знали, где могут возникнуть "узкие места", как эффективно распре- делить имеющиеся ресурсы и какие способы наращивания системы могут быть наиболее эффективными по стоимости. Некоторую полезную информа- цию можно извлечь путем "статического" инспектирования файловой сис- темы с помощью средств, представленных в главе 2. Более динамичную картину эксплуатации системы вы можете получить, применяя команду ps, чтобы увидеть, какие процессы активны в настоящее время, и применяя команду w (в системе Berkeley), которая выдает статистику загрузки системы и организации очередей. Пользователи системы - несомненно, имеют высокий приоритет. Все в системе должно быть организовано так, чтобы они могли выполнить свою работу. Администратор должен следить за тем, чтобы все разумные (и некоторые неразумные) запросы пользователей удовлетворялись. В обслуживание потребностей пользователей может входить монтиро- вание лент и других файловых систем, резервное копирование файлов, отладка коммуникационных линий и заготовка персональных записей для пользователей в привилегированных файлах типа crontab и inittab. (Эти два файла дают пользователям больше гибкости в организации их среды и планировании задач, но при этом ощутимы также для прямого пользова- тельского доступа.) Это может показаться легким делом, но требует много времени. Администратор ведает всеми вопросами безопасности. Обычно он единственный, кто занимается этой работой. Пользователи не обеспечи- вают безопасность, потому что они не умеют или не знают, как это сде- лать. Нарушители безопасности могут атаковать систему многими спосо- бами. Они могут занять системные ресурсы, заполняя таблицу процессов или таблицу открытых файлов и распределяя для себя все свободное дис- ковое пространство и все свободные индексные дескрипторы файлов. Они могут перепутаться с другими пользователями системы или поменять сис- темное время. Они могут повредить файлы данных или исполняемые модули и даже подделать почту. Но при вашей организации системы они чаще всего становятся просто "пользователями-хулиганами". Позже мы расс- мотрим более серьезные вещи, чем системное хулиганство - тех пользо- вателей, кто может несанкционированно воспользоваться правами супер- пользователя. Наилучший подход к проблемам безопасности - осознать, что дейс- твительно нуждается в защите, а не пытаться стать суперсыщиком. Вы должны особенно заботиться о нуждах системных программистов и других опытных авторитетов в вашей системе. В идеале администратор должен работать ВМЕСТЕ, а не против признанных авторитетов и поддерживать с ними хорошие деловые контакты. Не у всех нарушителей одинаковые моти- вы. Например, кто-то из авторитетов может захотеть получить доступ к правам суперпользователя для того, чтобы самостоятельно делать неко- торую работу, а не ждать, когда ее сделаете вы. Кто-то другой может быть обижен на кого-то или вообще на весь мир и стремится отомстить путем разрушения файлов. Каждая ситуация требует индивидуальной оцен- ки. Напомним, что разделяющая линия между администраторами и систем- ными авторитетами зачастую неопределенная и непостоянная. Безопас- ность иногда превращается в игру, в которой определенные пользователи пытаются разглядеть, чего они могут избежать, а администраторы пыта- ются сохранить контроль над системой. В работе сторожевого пса задействовано пять функций: 1. Защита от неразрешенных входов в систему, файлов, программ и команд su. 2. Сохранение конфиденциальности определенных данных. 3. Наблюдение за использованием модемов. 4. Предотвращение неразрешенных пересылок файлов. 5. Сведение к минимуму возможностей взлома. Здесь много работы! Система UNIX так обширна, и файлы могут скрываться в таком большом количестве мест, что один лишь поиск са- мозванцев занимает почти все время. Это требует от администратора не столько тяжелой, сколько изобретательной работы. Для того чтобы обес- печить себе шансы на победу в этой борьбе, вы должны сделать так, чтобы система помогала себя защищать. Несколько позднее в этой главе мы предложим инструментальные средства access и suw, которые помогают вам защищаться от запрещенных входов в систему, и командный файл chkset, имеющий дело с защитой конфиденциальных файлов. Мы также предлагаем более детальный взгляд на конкретные проблемы безопаснос- ти. ПРОГРАММ И КОМАНД su Имеется много способов получения несанкциониованных привилегий в системе UNIX. Самый простой способ - иметь корневой (суперпользова- тельский) интерпретатор shell. Это такой shell, который запускается как особо привилегированный процесс, имеющий возможность читать, уда- лять или модифицировать ЛЮБОЙ файл в системе независимо от того, ка- кие права доступа установлены для этого файла его владельцем. Корне- вой shell можно заполучить, узнав корневой пароль у неосторожного администратора или при помощи других средств, рассматриваемых ниже. Несанкционированный пользователь, имея доступ к правам супер- пользователя, может подготовить "потайные двери", обеспечивающие дальнейший запрещенный доступ. Они позволяют нарушителю запускать shell с корневыми привилегиями. Более подробно мы рассмотрим их позд- нее. Потайные двери могут выступать в различном обличье. Они могут быть исполняемыми модулями, латками в системных утилитах или латками в системных файлах. Администратор должен вести постоянное наблюдение за изменениями в системе и уметь противодействовать всяческим вмеша- тельствам. Ниже мы рассмотрим некоторые инструментальные средства и приемы, помогающие вам обнаруживать такое проникновение. Начнем с несанкционированных входов в систему. Это может прои- зойти многими способами. Бывает, что нарушитель добавляет свое собс- твенное регистрационное имя в парольный файл и помещает туда свой па- роль. Если администратор не знаком с парольным файлом или давно туда не заглядывал, то такую несанкционированную запись можно проглядеть. Другой метод несанкционированного входа в систему заключается в том, что кто-то может завладеть всеми паролями, вставляя в программу login "латку" с текстом, направлящим все введенные пользователями па- роли в потайной файл. Ниже мы рассмотрим некоторые типы таких "ла- ток". Конечно, такая изысканная работа зачастую совсем не обязательна. Как известно, люди оставляют свои пароли написанными на листках бума- ги в незапертых ящиках стола. Для некоторых верхом секретности явля- ется применение комбинации первого и последнего имени в качестве па- роля. Однако если уж нарушитель знает много паролей, он может применять каждый раз различные регистрационные имена, чтобы не попа- даться на опасном имени. Пробить систему защиты UNIX можно с помощью "исполняемых регист- рационных имен". Это имена, которые запускают программу, а не просто предоставляют вам shell, что является обычным способом начала сеанса работы пользователя в системе. Это может выглядеть примерно так: date::100:50:Print the date:/bin:/bin/date who::101:50:Print all logged on users:/bin:/bin/who Это может запустить любой, кто имеет доступ к терминалу или мо- демному порту. Иногда это правильные имена, например date, who или sync. Хотя для администратора может быть удобным наличие программ, запускаемых при входе в систему, они часто становятся лазейками, че- рез которые кто-нибудь может проникнуть в систему и обнаружить много информации о системе. Самые крупные лазейки появляются тогда, когда эти регистрацион- ные имена выполняют командные файлы интерпретатора shell. Как только нарушитель получает привилегии суперпользователя (даже если они лишь временные), он может поместить в парольный файл такую запись, которая в момент входа в систему запускает командный файл интерпретатора shell (или может изменить имеющуюся запись с командным файлом). Сами эти командные файлы можно в любой момент изменить так, чтобы они ра- ботали по заданию несанкционированного пользователя. Например, в па- рольном файле может быть такая запись: break::102:50::/:/usr/bin/break Такая запись позволила бы кому угодно набрать имя "break" в ответ на регистрационную подсказку, в результате чего выполнился бы файл /usr/ bin/break. Когда break отработает, снова поступает регистрационная подсказка, и в системе появляется новая лазейка. Почему? Потому что командный файл break может содержать команды для редактора, которые отредактировали бы парольный файл и добавили несанкционированные за- писи. Это становится возможным по той причине, что процесс getty (пе- чатающий регистрационную подсказку) запускается процессом init, а владельцем файла init является суперпользователь. Такая привилегия передается командному файлу, так как он запущен в момент регистрации в системе, а программам, запускаемым при входе в систему, обычно тре- буется суперпользовательский доступ для выполнения необходимых иници- ализаций. В данном случае, однако, он позволяет редактору читать файл /etc/passwd и писать в него. Таким образом, как только нарушитель ОДИН РАЗ получает доступ на запись в /etc/passwd (аналогично "дивер- сионным программам"), он может установить постоянный доступ, часто даже через несколько точек входа. И еще. В старых версиях UNIX попадаются некоторые ошибки, пре- доставляющие суперпользовательские возможности. Например, если в пользовательской записи парольного файла не указан номер пользова- тельского идентификатора, то по умолчанию он считается нулевым, т.е. суперпользовательским. В эту лазейку очень легко проникнуть. Пример такой записи: rt::::The Super User:/:/bin/sh Вот некоторые другие проблемы, за которыми должен следить адми- нистратор. Если первая строка парольного файла пустая, то пользова- тель может зарегистрироваться как корневой без пароля. Проверьте так- же запись "bin" в парольном файле, которая обычно запускает системные программы. Если запись bin не содержит пароля, как в приведенном выше примере, кто-то может войти в систему в качестве bin и отредактиро- вать файл crontab, чтобы применить к парольному файлу команду chmod (change permission mode, изменение прав доступа) и обеспечить себе доступ к нему. Пользователь bin может также отредактировать файл /etc /rc, чтобы сменить парольный файл. Файл rc используется для конфигу- рирования системы в момент ее старта путем автоматического запуска ряда программ. Все, что нужно для успешного вторжения,- подождать, когда администратор перегрузит систему (поскольку именно в этот мо- мент файл запускается). После перезагрузки нарушитель может войти в систему как обычный пользователь, отредактировать парольный файл, за- писать его, а потом в любой момент входить в систему в качестве су- перпользователя. Это всего лишь несколько способов, которыми можно добиться несанкционированного входа в систему. К сожалению, каждый день выдумывают новые способы. Еще одна сфера злоупотреблений связана с несанкционированным проникновением в файлы и программы. Самый трудный этап для того, кто хочет взломать защиту системы UNIX,- стать суперпользователем первый раз, но как только эта цель достигнута какими-либо средствами, файлы- интервенты можно поместить в любом месте системы. Вторжение может включать в себя размещение "потайных дверей", латание команды login с целью овладения паролями, чтение и изменение системных учетных файлов и т.д. Ниже мы рассмотрим примеры этих и других методов. Основными файлами, в которые вторгается корневой нарушитель, яв- ляются /etc/passwd, /etc/*rc*, /usr/lib/crontab, /usr/lib/uucp/L.sys. Для обнаружения трещин в вашей административной броне можно поискать файлы, для которых взведен бит разрешения установки пользовательского идентификатора (что указывается буквой "s" в правах доступа, отобра- жаемых командой "ls -l"), и файлы, владельцем которых является супер- пользователь. Назначение бита установки пользовательского идентифика- тора - разрешить программе иметь временный доступ к более привилегированному состоянию (например, суперпользовательскому), чем она имеет в момент своего запуска. На самом деле это очень полезное свойство системы UNIX, так как оно позволяет управлять доступом ко многим таким особенностям, к которым вы бы не хотели предоставить не- посредственный доступ для других пользователей. К сожалению, в эти программы может кто-нибудь проникнуть, чтобы использовать их времен- ный корневой статус для вредительства, которое мы уже описывали. Та- ких файлов имеется конечное число, и все они могут быть проверены. Рассматриваемый далее командный файл chkset автоматизирует для вас процесс проверки. Тем не менее, знание того, какие файлы МОГЛИ быть подвергнуты вмешательству, еще ничего не говорит о том, в какие файлы ДЕЙСТВИТЕЛЬНО произошло вторжение и как. Тяжелее всего обнаружить за- латанные системные файлы. Некоторыми из часто латаемых файлов являют- ся login, su, passwd, ps, crypt и mv. Бывает, что изощренный нарушитель скрывает даты модификации фай- ла, чтобы никто не смог его обнаружить по этому признаку. Единствен- ный способ зафиксировать такое вмешательство - иметь КОНТРОЛЬНУЮ СУМ- МУ, т.е. запись с суммой (количеством байтов) всех важных файлов и хранить ее в отдельном месте или в закодированном виде. Путем перио- дической сверки старых сумм с новыми, можно обнаружить измененные файлы. Еще одна вещь, за которой должен следить администратор, это "скрытые файлы". Скрытые файлы являются частью системы и имеют опре- деленный смысл: они предназначены для того, чтобы не загромождать распечатки каталогов. Для того чтобы скрыть файл, нужно сделать пер- вым символом имени файла точку (.). При использовании команды ls вы должны указать опцию -a, если вы хотите увидеть файлы, начинающиеся с точки. Обнаружение запрещенных файлов может быть затруднено, если файл зарыт на три-четыре уровня каталога вниз и назван незаметным именем. Решение заключается в том, чтобы всегда применять опцию -a команды ls, если вы сталкиваетесь с проблемами. Некоторые команды по умолчанию печатают файлы, начинающиеся с точки. Ncheck(1M) печатает все файлы, имеющие взведенный бит разрешения установки пользователь- ского идентификатора. Если файл назван странным образом, его сразу же видно. Одним из моих любимых является файл "...". Он выглядит нес- колько странно, но это правильное имя файла. Вы даже можете завести имя файла, образованное 14 точками - такова максимальная длина имени файла. КОМАНДЫ su Последний вопрос, за которым нужно следить,- запрещенные команды su. Su - это такое средство, которое позволяет вам ПОДСТАВИТЬ другой пользовательский идентификатор вместо вашего собственного. Если кто-то знает корневой пароль, он может войти в систему с любого тер- минала и применить команду su с корневым паролем. Однако, это, веро- ятно, тот случай, когда нарушители потратят больше всего времени, пы- таясь чего-либо добиться. Дело в том, что все транзакции su записываются в протокольный файл под названием sulog. Правда, к сожа- лению, если уж нарушитель стал суперпользователем, то ему ничто не мешает модифицировать протокольный файл с целью удаления компромети- рующих записей. К тому же если редактор vi вызван без имени файла, то никто не может увидеть, какой файл редактируется в то время, когда в системе происходит вредительство. Но бдительный системный администратор может бороться с этим при помощи команды ps. Она печатает строку о команде su точно так же, как она делает это для всех остальных процессов, поэтому можно сразу же заметить, что кто-то превратился в суперпользователя командой su. На- рушителя выдает то, что родительский процесс имеет регистрационное имя, а владельцем su является суперпользователь. Наконец, все равно же нужен корневой пароль. А если кто-то уже знает корневой пароль, то зачем ему связываться с командой su? Применять su было бы резонно только в том случае, если бы залатать команду su так, чтобы она не записывала транзакцию в протокол и изменяла строку, которую печатает ps. Мы еще не знаем, чтобы кто-нибудь добился такого эффекта. Даже если допустить, что секретность обеспечена, бывают случаи, когда администратору нужно защитить важные файлы от любопытных глаз. В системе UNIX это можно сделать с помощью специальных атрибутов за- щиты файла, специальных групповых прав доступа, шифровки или даже размещения этих данных на диске, который монтируется только в случае необходимости. Однако, такие данные не должны оставаться физически присутствующими в системе, если они не монтированы, потому что нару- шитель может их смонтировать и получить к ним доступ. Командный файл mntlook, рассмотренный ранее, умеет просматривать все устройства и находить такие доступные, но немонтированные файловые системы. Необходимо соблюдать такое правило: "Если вы не хотите, чтобы кто-нибудь видел этот файл, не держите его на виду". И не думайте, что вы так хорошо его спрятали, что никто не сможет его найти. Если люди имеют суперпользовательский доступ в вашу систему, они могут за считанные минуты получить распечатку каждого файла этой системы. За- тем, когда вы не видите, они могут при помощи uucp передать интерес- ный файл в другую систему для последующего изучения, скопировать его на гибкий диск или даже отпечатать. Помните, что если в вашу систему проник несанкционированный пользователь, НИКАКОЙ БЕЗОПАСНОСТИ БОЛЬШЕ НЕТ! Модемы являются одной из крупных пробоин в защите системы. Если только у вас нет специальной аппаратуры для предварительной фильтра- ции обращений в систему UNIX, то она всегда уязвима посредством мо- демных портов. Большие вычислительные системы могут иметь произвольное число модемов, как принимающих, так и передающих. Вам может показаться, что поскольку команда login имеет дополнительный пароль для линий с набо- ром номера, то все секретно, но это не так. Имеются программы, кото- рые могут пробовать много комбинаций вероятных регистрационных имен и паролей, и в случае подходящей комбинации команда login может впус- тить нарушителя в систему! Обращение вовне, в другие системы через модемы - отдельная исто- рия. Обычно тот, кто правильно зарегистрировался в системе, хочет обращаться к другим системам. Но что, если на вашей стороне имеются улавливающие регистрационные имена типа class, education, test и т.д.? Кто-то может войти в систему под видом одного из таких пользо- вателей и использовать модем безо всякого риска быть схваченным за руку. Единственный способ поймать таких нарушителей - по номеру тер- минальной линии, если у вас имеются специально выделенные линии. Что произошло бы, если бы тот, кто вошел в вашу систему через модем при помощи одного из перечисленных регистрационных имен, обра- тился бы потом вовне, к какой-нибудь "дальней земле"? Тогда не было бы никакой возможности уследить за обратным вызовом определенного пользователя. Запрещенные пересылки файлов имеют отношение почти исключительно к средствам uucp. В системе Berkeley (BSD 4.1 и старше) сетевые ко- манды также имеют аналогичные проблемы. Вот пример: если кто-то за- пускает в системе Berkeley командный файл для "взлома двери", то ко- манда удаленной регистрации в системе (rlogin) регистрирует нарушителя на другой машине в качестве суперпользователя и никогда не спрашивает корневой пароль. Разве это не очевидная пробоина в систе- ме? Несанкционированный пользователь может также применить удаленное копирование (rcp), чтобы скопировать программу "взлома двери" во все системы. Самое главное следить за протокольными файлами. Но опять же, что если нарушитель удаляет из протокольных файлов все записи, связанные с заданием вопросов? У вас нет способа узнать о том, что это произош- ло. Еще нужно следить за таким поведением нарушителей, когда они де- лают вызов и выдают себя за корректную удаленную систему. Они могут добиться этого, изменив узловое имя своей системы таким образом, что- бы оно соответствовало одному их ваших разрешенных "корреспондентов". Изощренного нарушителя очень трудно поймать, но мы предлагаем некото- рые идеи, которые должны вам в этом помочь. Это то, чем администраторы часто пренебрегают. Совет номер один - НИКОГДА не оставлять без присмотра терминал, зарегистрированный как суперпользовательский. Бросить без присмотра терминал с корневым дос- тупом - все равно, что оставить тысячу ключей от сейфа компании на вашем столе. Все несанкционированные пользователи могут воспользо- ваться этим, подготовив командный файл "взлома двери", ожидающий та- кого момента. Как только они получают в свои руки ваш терминал, всего лишь одна команда предоставляет им безграничные суперпользовательские возможности. С этого момента система перестает быть защищенной. Системные администраторы должны проверять свои системы и смот- реть на них с точки зрения нарушителя. Есть ли хоть когда-нибудь мо- мент, в который система уязвима? Что может произойти среди ночи, ког- да работают программы резервного копирования? Может ли кто-нибудь завладеть консольным терминалом? Не сможет ли навредить тот, кто при- ходит к вам помогать? Если вы на секундочку вышли, не сможет ли кто-то применить команду chmod, а потом заполнить экран чем-нибудь другим, чтобы вы не узнали, что это было сделано? Вот те опасности, о которых вам нужно помнить. Рассмотрев в общих чертах обязанности системных администраторов и, в частности, основные вопросы системной безопасности, мы готовы теперь к более детальному изучению того, как могут произойти наруше- ния защиты. Каждый метод вмешательства в систему имеет свои преиму- щества и недостатки с точки зрения нарушителя и оставляет возможность борьбы с ним. Будучи осведомленным об этих характеристиках, админист- ратор получает хороший шанс обнаружить пробои в защите и выявить по- тенциальных нарушителей. Мы уже отмечали, что люди, которые могут получить суперпользова- тельский доступ в систему хотя бы на короткое время, могут написать программы, предоставляющие им постоянный суперпользовательский дос- туп. Напомним, что тот, кто хочет прорвать защиту системы UNIX, пер- вым делом пытается найти способ стать суперпользователем. Как мы уже обсуждали, нарушение физической защиты или плохо оберегаемый корневой пароль могут дать нарушителю возможность запустить процесс как супер- пользовательский, что предоставляет доступ к файлам (например, стан- дартным исполняемым модулям системы UNIX), которые не может изменить обычный пользователь. В результате нарушитель получает для себя "по- тайную дверь". Ключевым вопросом является способ хранения в системе UNIX указа- ний о владельце и привилегиях, связанных с файлом. Помимо хорошо из- вестных прав доступа для владельца, группы и прочих пользователей (эти права устанавливаются командой chmod), имеется два более старших бита, называемых setuid (установка пользовательского идентификатора) и setgid (установка группового идентификатора). Как правило, процесс, запущенный данным пользователем, имеет только те привилегии на доступ, которые принадлежат этому пользовате- лю. Однако, многие системные команды должны иметь доступ к таким фай- лам, к которым мы бы не хотели разрешать доступ пользователя, за иск- лючением очень ограниченного набора ситуаций. Ярким примером является команда passwd, позволяющая пользователю сменить свой пароль. Очевид- но, что этой команде необходим доступ на запись в файл /etc/passwd, а такой доступ имеет обычно только суперпользователь. Проблему решает исполняемый файл команды passwd, в котором бит setuid установлен на владельца файла, а владельцем файлов, соответс- твующих обычным системным командам, является суперпользователь (поль- зовательский идентификатор 0). Это означает, что ВО ВРЕМЯ РАБОТЫ ПРО- ЦЕССА, соответствующего данной команде, пользователь имеет корневые привилегии! Когда команда завершается, прекращается и корневой доступ ... если только в данную команду не было какого-то вмешательства или если нарушитель не установил особую программу setuid. В этих случаях остается только войти в потайную дверь. Потайная дверь - это чаще всего файл, владельцем которого явля- ется суперпользователь, но который подвергнут вмешательству несанкци- онированного пользователя, завладевшего каким-то образом правом дос- тупа на запись в этот файл, обычно путем временного суперпользовательского доступа. Важно понимать, что потайная дверь - это просто еще один процесс, порожденный из обычного пользовательско- го интерпретатора shell, но с одной существенной особенностью: у него другой номер пользовательского идентификатора - как правило, 0, т.е. идентификатор суперпользователя. Поскольку пользовательский идентифи- катор хранится в самом процессе, он может быть подвергнут вмешатель- ству. Фактическое проникновение в систему с обретением возможностей суперпользователя происходит тогда, когда работает "дверная" програм- ма. Здесь используется волшебство бита setuid. Когда этот бит взве- ден, программа устанавливает (или изменяет) пользовательский иденти- фикатор процесса на пользовательский идентификатор владельца данного файла (который оказывается суперпользовательским). Пока этот пользо- вательский идентификатор временно является суперпользовательским, программа превращается в shell-интерпретатор (обычно путем выполнения системного вызова exec). Такой shell находится по другую сторону две- ри, в царстве суперпользователя, со всеми принадлежащими ему привиле- гиями. Как мы уже отмечали, обсуждая команды su, более изощренные нару- шители могут различными способами маскировать свое прониконвение в систему. Один из способ маскировки - иметь "дверную" программу, кото- рая ничего не делает, если только она не вызвана с какой-нибудь неза- метной опцией, например -z. Скорее всего, программа потайной двери не выдает сколько-нибудь полезного синтаксического сообщения, если ее вызвать без правильной опции. Еще одна хитрость заключается в том, что программа потайной две- ри может изменить свою командную строку (которую можно отобразить при помощи команды "ps -ef", выдающей полное состояние процесса) на какую -нибудь безобидную, запускаемую обычно суперпользователем (например, getty). Опытный нарушитель вряд ли оставит исходный текст программы по- тайной двери в системе, поэтому администратор вынужден разглядывать только исполняемый модуль. Для реассемблирования объектного кода мож- но применить отладчик (adb), но если только вы не имеете безумно близкого знакомства с внутренностями системы UNIX, вам будет весьма трудно представить себе, что происходит. Изощренные программы потай- ной двери избегают также присутствия легко узнаваемых строк в испол- няемых модулях. Вы можете, однако, применить команду strings (если она есть в вашей системе) для поиска символьных строк, которые там могли бы быть. Одна из простейших ловушек для того, кто пытается добыть права суперпользователя - создавать запись, помещаемую в протокольный файл. При этом администраторам нужно следить за протокольными файлами, не появляются ли там записи, которые могут быть признаком злодейства. Ниже мы покажем вам инструментальное средство, которое автоматически следит за одним из таких протокольных файлов - файлом sulog, содержа- щим транзакции "замененного пользователя". Другой протокольный файл, часто нуждающийся в проверке, это протокол программы uucp, потому что эта программа может быть использована для несанкционированных пересы- лок файлов. Многие нарушители пытаются проверить протокольные файлы и удалить компрометирующие записи, сгенерированные при их вмешательст- ве. В арсенале администратора есть средства борьбы с этим. Они не на 100 процентов эффективны, но отлавливают некоторых нарушителей и, ус- ложняя им жизнь, могут отбить охоту вторгаться в систему. В дополнение к обычным протокольным файлам, поддерживаемым сис- темой UNIX, некоторые администраторы заводят свои собственные прото- кольные файлы, а затем подправляют ключевые команды так, чтобы они помещали данные в эти новые регистрационные файлы в процессе своей работы. Это может помочь обезвредить неосторожных лазутчиков. Один знакомый администратор сделал протокольный файл для команды cu и наз- вал его /tmp/.../.culog. Довольно умный тайный фокус, но в /usr/lib/crontab у него была запись для периодической печати этого файла. Это его выдавало: нужно было маскироваться получше. Заметим также, что ваши "скрытые" имена протокольных файлов могут быть извле- чены путем просмотра исполняемого образа команды с помощью утилиты strings. Если у вас есть пользователь, от которого вы ожидаете чего-ни- будь запрещенного, вы должны уметь установить специальную систему ре- гистрации, которая запускала бы более совершенный механизм, когда та- кой пользователь работает в системе. Программу watch из главы 6 можно модифицировать так, чтобы она вызывала специальную протоколирующую программу, когда в систему входит пользователь из известного списка. Протоколирующая программа могла бы повторять команды ps (process status, состояние процесса) и/или делать "моментальные снимки" обыч- ных регистрационных файлов (особенно учетных файлов) и направлять ре- зультаты в припрятанный протокольный файл. Идея состоит в том, что опасные процессы можно было бы обнаружить до того, как нарушитель по- лучает возможность войти в протокольные файлы и изменить их. (Видимо, вам нужно избегать применения команды at в такой программе, а перио- дически пользоваться вместо нее командой sleep. В противном случае, нарушитель может распознать ваши мероприятия по записи файла crontab.) Как только вы имеете результат о сеансе работы опасного пользователя, вы можете запустить grep для поиска интересующих вас имен или написать инструментальное средство, которое выполняет для вас такой поиск. Вероятно, наиболее важным среди протокольных файлов является учетный файл. В учетном файле имеется запись о каждом и всяком про- цессе, запускаемом в системе. Точную структуру можно посмотреть в файле /usr/include/sys/acct.h. В одном из полей этой структуры запи- саны процессы, имеющие суперпользовательские возможности. Когда кто-либо входит в систему через корневую дверь, для shell- интерпретатора, который он запускает, и для всех процессов, которые он порождает, владельцем является корень (суперпользователь). В учет- ном файле отражен номер терминала, с которого запущен процесс, поэто- му вы можете увидеть корневые процессы, запущенные с таких термина- лов, на которых пользователям не разрешен суперпользовательский доступ. Если у вас имеются обычные линии с набором номера, то все такие записи могут представлять не одного и того же пользователя. Другие входы в систему могут иметь одинаковый номер терминала, но разные пользовательские идентификаторы. Однако, вы можете знать, кто обычно имеет доступ к некоторым выделенным линиям. Учетные файлы могут хорошо разоблачить процессы, имеющие не та- кой пользовательский идентификатор, как у лица, запустившего эти про- цессы. Поищите процессы, владельцем которых был известный пользова- тель, но которые имеют суперпользовательские возможности. Среди них могут быть корректные записи, например lpr, так как отображаются все системные программы, запущенные со взведенным битом setuid. Записи, которые мы ищем, относятся к shell-интерпретаторам с установленным учетным флагом суперпользователя. Это выдает тот факт, что была вы- полнена программа потайной двери. Изучите подключаемый файл acct.h, чтобы увидеть все определения. Используя бит ASU для проверки поля, мы можем изолировать флаговую область, отражающую привилегию супер- пользователя. Самый лучший способ рассмотреть эту структуру - напи- сать программу на языке Си, печатающую все элементы структуры. В сле- дующей распечатке показаны некоторые важные учетные поля:
| | cmd f uid tty btime | | more 0 russ 0 Sat Jul 5 01:25:59 1986 | ls 0 russ 0 Sat Jul 5 01:31:12 1986 | ps 0 russ 0 Sat Jul 5 01:31:59 1986 | id 0 russ 0 Sat Jul 5 01:34:00 1986 | pwd 0 russ 0 Sat Jul 5 01:34:12 1986 | sh 1% russ 0 Sat Jul 5 01:33:51 1986 | \__ корневой shell с эффективным пользовательским идентификатором | | sync 0 russ 0 Sat Jul 5 01:34:21 1986 | df 0 russ 0 Sat Jul 5 01:34:27 1986 | id 0 root 0 Sat Jul 5 01:34:37 1986 | sh 2# root 0 Sat Jul 5 01:34:33 1986 | \__ корневой shell с реальным пользовательским идентификатором, | 2# обозначает бит суперпользователя, | владелец изменен на root | Отметим, что shell-интерпретаторы с эффективным пользовательским идентификатором маскируют бит во флаге суперпользователя, но владель- цем их процессов является обычный пользователь. Не известно, все ли системы применяют значение 1 в качестве флага shell-интерпретатора с эффективным пользовательским идентификатором. Похоже, что Berkeley поступает именно так, а System V нет. КОМАНДА su Как мы уже отмечали, UNIX предоставляет пользователям обычный способ стать суперпользователем - это команда su. Как видно из преды- дущего изложения, суть команды su заключается в системном вызове exec. Тот, кто применяет команду su, должен знать корневой пароль, транзакция протоколируется в файле /usr/adm/sulog, а команда ps огла- шает тот факт, что активен корневой shell. Этот прием не самый хитро- умный. Помните о том, что НИКОГДА нельзя оставлять без присмотра терми- нал, на котором вы работаете в качестве суперпользователя? Пока вы отсутствуете, кто-то может воспользоваться этим терминалом, чтобы вы- полнить команду chmod с целью установки бита пользовательского иден- тификатора. Хорошо подготовленный нарушитель уже имеет откомпилиро- ванную программу потайной двери, владельцем которой является суперпользователь, и ждет, когда будут изменены права доступа. Не ос- таются ли консольные терминалы доступными в качестве суперпользова- тельских ночью, во время действий по резервному копированию? Если ос- таются, то наутро администратор может оказаться в незавидном положении! БОЛЕЕ ПОДРОБНО О ПОЛЬЗОВАТЕЛЕ bin Мы уже упоминали о "лазейке" в некоторых системах, позволяющих пользователю "bin" без труда завладеть суперпользовательским досту- пом. Проблема "bin" имеет еще ряд аспектов. Если несанкционированные пользователи могут войти в систему через bin (являющийся владельцем большинства дистрибутивных исполняемых модулей), то они почти навер- няка смогут получить права суперпользователя. Прежде всего, в некото- рых версиях владельцем всех исполняемых модулей, размещенных в ката- логах /bin и /usr/bin, является bin. Это значит, что нарушители могут перезаписать или подправить исполняемые модули своими собственными вариантами, выполняющими некоторые особые действия, например "chmod 4755 door", а затем восстановить на место исходную версию исполняемо- го модуля. Еще один способ простого превращения bin в суперпользователя заключается в модификации /etc/rc - файла запуска команд ("run command"). Он запускается каждый раз, когда машина загружается в мно- гопользовательском режиме. Записывая в него "chmod 777 /etc/passwd", нарушитель может превратить парольный файл в обычный пользовательский после того, как машина загрузится. Последний способ - использовать файл /usr/lib/crontab. Этот путь изменен в последней версии System V. Теперь полное имя этого файла /usr/spool/cron/crontabs/xxx, где xxx - файл crontab для каждого пользователя. В старом варианте владельцем файла /usr/lib/crontab иногда является bin. Кто-нибудь может отредактировать этот файл и по- местить в него такие, например, команды: * * * * * chmod 777 /etc/passwd * * * * * chmod 4755 /tmp/door * * * * * /bin/su root -c "chmod 777 /etc/passwd" Все это срабатывает по той причине, что cron выполняется процес- сом init. Поскольку init - один из первых запущенных процессов, его владельцем является суперпользователь. Поэтому любая команда, которую выполняет cron, имеет корневые привилегии. Звездочки означают, что cron должен выполнить указанные команды в очередной возможный момент времени. Cron запускает процесс, изменяющий права доступа к указанно- му файлу. Нарушители могут поменять парольный файл (что несколько бо- лее опасно) или просто активизировать программу потайной двери. Если две первые команды не сработают, то владелец будет изменен на супер- пользователя методом грубой силы - выполнением команды su, а затем передачей команды chmod shell-интерпретатору, запущенному командой su. Вы должны почаще проверять файлы crontab и /etc/rc! Это редко применяемый метод. Он предполагает, что обычный поль- зователь имеет право на запись в исполняемый модуль или в специальный файл. Если кто-то может писать в исполняемый модуль, скажем ls, то он может поместить туда некоторый код, который устанавливает потайную дверь, а затем заменяет себя настоящей утилитой. Это работает еще лучше, когда эту команду запускает пользователь с корневыми возмож- ностями, так как тогда команда выполняется как привилегированный про- цесс. Такой способ упрятывания кода в программу с возможностью запус- ка ее не вызывающим подозрения пользователем называется "троянским конем". Он выглядит безвредным, но то, что спрятано у него внутри, крепко бьет по защите системы. Как мы уже отмечали, периодическая проверка контрольных сумм для стандартных исполняемых модулей - одно из противоядий от "троянских коней". Если нарушители овладевают возможностью чтения или записи файлов устройств, они могут прочитать в этих файлах информацию о суперблоке и файловой системе и получить доступ к любому файлу. Им может понадо- биться пройти по файловой системе в поисках нужного файла, подправить его и записать обратно в файл устройства. Люди, которые этим занима- ются и совершают при этом ошибки, могут добиться краха всей системы. Если файл устройства находится в памяти, пользователи могут просматривать информацию о процессах или ядре непосредственно в памя- ти. Может быть использован старый прием отслеживания списков clist на предмет поступления пароля пользователя, входящего в систему. Это требует больших знаний о том, где данная информация размещается в па- мяти и как к ней добраться, поэтому этим методом пользуются, вероят- но, только опытные нарушители. В некоторых системах бывает, что после перезагрузки машины на консоли работает суперпользовательский shell. Такое может произойти в однопользовательском режиме или на микро-ЭВМ, служащей консолью для большой машины. Очевидное решение - ограничить физический доступ к консоли. ИСПОЛЬЗОВАНИЕ ПРЕИМУЩЕСТВ ПЕРЕМЕННОЙ $PATH Кое-кто может воспользоваться ситуацией, когда пользователь име- ет каталог $HOME/bin впереди системных каталогов /bin и /usr/bin в своей переменной PATH. Помещая подправленную программу в регистраци- онный каталог безвредного пользователя, нарушитель заставляет эту программу выполняться вместо настоящей, поскольку система исполняет первый файл, совпадающий с именем команды, который она обнаруживает в ходе просмотра определенного пользователем маршрутного списка. Приме- ром могла бы служить команда ls. Когда команда выполняется, она запускается с теми же правами доступа, что и запустивший ее пользователь. Конечная цель нарушителей - добиться прав суперпользователя, поскольку тогда они смогли бы вы- полнить любую команду. Диверсионная программа может подготовить по- тайную дверь для овладения правами суперпользователя или даже нес- колько таких дверей. Она может удалить себя, чтобы при очередном вызове данной команды выполнялась настоящая команда. Настоятельная необходимость для администратора - проверять наличие в рабочем прост- ранстве опасных файлов (в частности, исполняемых модулей). Мы не слышали, чтобы кто-либо это делал, но имеет смысл от этого защититься. Старательный нарушитель мог бы сначала подготовить правки для системы, поместить их на ленту и переслать их вам, администрато- ру. Вы, вероятно, предположили бы, что это правильные модификации системы и установили бы их. И ваша система получила бы "подарочек" от нарушителя. Поэтому администратор может захотеть сверить новые версии с их изготовителем перед тем, как устанавливать их у себя. Хотя мы не можем дать гарантию, что кто-нибудь смекалистый не опишет, как расколоть парольную защиту, кодирование пароля в системе UNIX по алгоритму DES считается довольно секретным. (Рассмотрение ме- ханизма DES выходит за пределы данной книги.) К этой защите добавля- ется одна вещь - два символа, генерируемые случайным образом, называ- емые "солью" (salt) и хранимые в файле /etc/passwd для каждой записи. "Соль" используется для определения того, какой из 4096 вариантов ал- горитма DES применяется для кодирования заданного пароля. Нарушитель мог бы захватить пароль, использовать его "соль" и зашифровать список известных паролей. Если бы результат совпадал с пробным паролем, взлом был бы осуществлен. Нарушителю пришлось бы иметь доступ к некоторой довольно чувс- твительной методике, чтобы добиться своего. Нелишняя мера, которую может предпринять администратор,- следить за чрезмерным использовани- ем команды crypt (если она есть в вашей системе). Эта команда специ- ально сконструирована так, чтобы занимать много процессорного времени - не настолько много, чтобы причинять неудобства законным пользовате- лям, но достаточно много, чтобы выявить попытки автоматизированного взлома. Западня работает только на специально выделенных линиях. Когда UNIX ожидает, что кто-то будет входить в систему, она печатает ре- гистрационную строку из файла /etc/gettydefs. Пользователь вводит свое регистрационное имя и пароль и попадает в систему. Программа западни извлекает из этого выгоду. Она имитирует пове- дение экрана во время регистрации. Когда пользователь вводит свое имя и пароль, такая программа печатает сообщение "login incorrect" ("не- верная регистрация"), а затем запускает настоящую регистрационную программу. Пользователь думает, что он сделал ошибку и повторяет по- пытку входа в систему, на этот раз успешно. Регистрационное имя и па- роль можно куда-нибудь отложить для последующего изучения. Самая луч- шая защита администратора от этого - обучение пользователей. Видимо, с помощью регулярной почты или бюллетеней нужно напоминать им, что если им кажется, что они набрали пароль правильно, но получили при этом сообщение "incorrect", то они должны немедленно сменить свой па- роль и сообщить об этом происшествии администратору. Бывают случаи, когда пользователь действительно ошибается при вводе пароля, но к большому количеству таких происшествий нужно отнеститсь со всей серь- езностью. Команда монтирования была создана для того, чтобы позволить при- соединять к системе несколько дисковых устройств. Раньше, в эпоху ми- никомпьютеров единственным видом дисковых устройств были большие на- копители, в которые вставлялись большие дисковые пакеты. Они обычно находились в машинном зале, и только администратор монтировал их. Теперь многие системы имеют гибкие диски. Они гораздо персональ- нее и намного меньше, чем большие дисковые пакеты. Это уменьшение размера ощутимо воздействует на важность самого объекта. Похоже, что теперь каждый пользователь может иметь дело со своими дисками, и ад- министратору больше нет необходимости заниматься этим. Такой сценарий работы приводит к следующему. Обычное действие, предпринимаемое в небольших системах для того, чтобы дать пользователям возможность работать с их собственными гиб- кими дисками,- это установка бита пользовательского идентификатора для файла команды /etc/mount. Таким образом, когда запускается коман- да монтирования, ее пользовательский идентификатор становится корне- вым, и она может смонтировать гибкий диск. Команда демонтирования должна быть подготовлена аналогично. Кто-то может извлечь выгоду из того, что команда mount может по- лучить во время своей работы права суперпользователя. Обычно в не- больших системах одна машина открыта для экспериментов несанкциониро- ванного пользователя. Он может стать суперпользователем в вашей системе, подготовить программу потайной двери и поместить ее на гиб- кий диск. Владельцем является суперпользователь, а права доступа 4755. Затем нарушитель может размонтировать гибкий диск и войти в за- щищенную систему. С этого момента нарушитель может просто входить в систему как обычный пользователь, без всяких специальных прав доступа и монтиро- вать гибкий диск, на котором имеется программа потайной двери. Когда гибкий диск монтируется, файловая система гибкого диска встраивается в файловую систему жесткого диска, и две системы сливаются в одну. Это означает, что потайная дверь для овладения правами суперпользова- теля готова для файловой системы на жестком диске. Когда нарушитель запускает программу потайной двери на гибком диске, происходит то же самое, что происходило бы, если бы эта прог- рамма была на жестком диске. Мера предотвращения - контролировать ис- пользование команды mount в вашей системе. Доступ к команде mount должен быть ограничен определенным кругом пользователей, она не долж- на разрешать монтировать файлы с установкой пользовательского иденти- фикатора. АВТОНОМНЫЙ shell (SASH) В системах UNIX с гибкими дисками загрузочный диск обычно загру- жается с гибкого накопителя. Подразумевается, что гибкий диск приме- няется для подготовки жесткого диска и копирования всех файлов систе- мы UNIX с гибкого диска на жесткий. Но за этим кроется нечто большее. На самом деле загружаемый гибкий диск - это компактная, перено- симая версия системы UNIX. Ядро адаптировано к тому, чтобы размещать- ся на гибком диске, а не на жестком. Когда вы его загружаете, вы по- лучаете интерпретатор shell и среду точно так же, как при работе с жесткого диска. Вот почему такой shell называется автономным (SASH, standalone shell). Корневая файловая система на гибком диске даже выглядит точно так же, как файловая система жесткого диска. Фактически вы можете смонтировать загружаемый диск и скопировать утилиты с жесткого диска на гибкий. Нужны две важные команды: mount и umount. Ограничением яв- ляется размер гибкого диска. На него не так много помещается. Сценарий, с помощью которого несанкционированный пользователь может применить SASH для входа в систему с суперпользовательскими привилегиями, выглядит примерно так. Сначала он должен отключить пи- тание или перезагрузить защищенную систему. Затем он должен загрузить SASH и смонтировать корневую файловую систему жесткого диска в точку монтирования своей файловой системы гибкого диска. Команды могут быть такими: # /etc/mount /dev/fp001 /mnt <-- для System V # /etc/mount /dev/hd0a /mnt <-- для XENIX Это дает нарушителям доступ на жесткий диск при помощи обращения /mnt/*. Все, что им нужно для редактирования файла /etc/passwd - это пройти вниз по дереву каталогов. Для этого можно применить такие ко- манды: # /mnt/bin/vi /mnt/etc/passwd # sync Теперь жесткий диск изменен, и его можно вернуть на место. Нару- шитель может остановить автономный вариант UNIX и перезагрузиться с жесткого диска. Он может использовать новое регистрационное имя, соз- данное при помощи SASH. Мы не знаем, насколько часто люди могут предпринимать такие попытки. Небольшие системы более уязвимы, но в них и меньше пользователей (и потенциальных злодеев). Во многих слу- чаях нижней границей "логической защиты" становится "физическая защи- та". Большинство людей, имеющих большие машины или даже мини-ЭВМ, постоянно осознают, что им есть что защищать. А микро-ЭВМ выглядят настолько "дружественными" и простыми, что люди обычно забывают, что информация, которая содержится на микрокомпьютерах, при определенных обстоятельствах может оказаться настолько же желаемой и значительной, как и на больших машинах. Чаще всего правки исходных текстов являются самым мощным, хотя и не самым легким способом проникновения нарушителей в систему. Внедряя свой собственный код в подходящих местах, несанкционированные пользо- ватели могут извлечь всю секретную информацию, которая им нужна. Од- нако, правки кода могут быть полезны также и для администратора. Ад- министратору может понадобиться внести правки в регистрационную программу, чтобы посмотреть, кто и как часто пытается зарегистриро- ваться на машине. Другой вариант - внесение правок в программы с ус- тановкой пользовательского идентификатора и в другие доступные огра- ниченному кругу лиц программы, чтобы они регистрировали свой сеанс работы в секретном протокольном файле. Еще одно место, в котором нужно следить за несанкционированными правками - библиотеки ядра. Подправленные объектные модули можно лег- ко поместить в библиотеки незамеченными. Другим библиотекам грозит та же опасность. Дополнительные разумные усовершенствования ядра можно обнаружить в системных вызовах chmod и chown. Когда выполняются эти системные вызовы, они проверяют, имеете ли вы пользовательский иден- тификатор 0. Если нет, то ваш запрос не удовлетворяется. Отменив эту проверку, любой обычный пользователь мог бы изменить владельца файла на суперпользователя, а также изменить режим защиты файла, чтобы взвести бит установки пользовательского идентификатора. Это позволило бы успешно обойти защитный барьер. ПРОГРАММА passwd Программа passwd - охранник ворот системы UNIX. Точно так же, как многие древние города пали из-за того, что враги подкупили охран- ника ворот, так и хорошо защищенная система UNIX может быть превраще- на в широко открытую, если кто-либо подправит эту программу. Посколь- ку пользователи применяют программу passwd для изменения своих паролей, подправленная версия может записывать новый пароль, вводимый пользователем для изменения, в секретный файл, принадлежащий наруши- телю. Это может обесценить каждый вновь создаваемый в системе пароль. Внутри программы passwd пароль является просто символьным массивом, поэтому с этими данными легко управиться. ПРОГРАММА crypt Потенциальной правкой программы шифрования файлов crypt может быть накопление имен файлов и ключей шифра при каждом использовании программы. Таким методом вы можете проследить, кто запускает эту ко- манду, какой файл он использует и какой ключ применяется для того, чтобы получить доступ к этому файлу. Неприятности, связанные с последними двумя случаями, заключаются в том, что кто-нибудь может разрушить меры системной безопасности. Если вы считаете, что в вашей системе есть заманчивые, важные данные, то вам как администратору следует почаще проверять эти программы (по контрольной сумме или сравнением) на предмет повреждения. КОМАНДА su Поскольку команда su предоставляет суперпользовательский доступ для обычных пользователей, имеющих корневой пароль, это еще одна по- тенциальная лазейка в защите системы. Общая схема работы команды su выглядит так:
| | Получить информацию о пользователе: пользовательский идентификатор, | групповой идентификатор, пароль, номер терминала, ... | Если пароль пустой или пользовательский идентификатор равен нулю, | То пройти мимо вопросов о пароле. | | Запрос пароля | Если зашифрованный вариант того, что было только что набрано, | не совпадает с парольной строкой из файла /etc/passwd, | То запротоколировать неудачную попытку применения su, | напечатать сообщение "sorry" (сожаление по поводу неудачи), | выйти. | Пароль прошел: | запротоколировать успешную попытку применения su, | выполнить системные вызовы для того, чтобы ввести в действие | пользовательский и групповой идентификатор, | установить среду, если это требуется, | выдать на консоль сообщение, если это корневой shell, | а вы не за системной консолью, | организовать аргументы для показа su в команде ps, | выполнить интерпретатор shell. | Для подправленной версии потребовались бы лишь небольшие измене- ния в приведенной выше последовательности. Вместо того, чтобы сразу же зашифровывать пароль, su могла бы проверить "секретный" пароль на- рушителя. Если введен такой пароль, то проверку пароля и действия по про- токолированию можно обойти, поэтому запрещенный доступ не отразился бы в протоколе. Несанкционированный пользователь добился бы того, что ДРУГИЕ пароли для команды su записывались бы в "секретный" файл. В результате он бы потихоньку получил все интересующие его пароли для потенциального использования. Для пользователя команда su срабатывала бы успешно, если пароль правильный, а нарушитель получал бы в свое распоряжение пароль. КОМАНДА login Несанкционированный пользователь может повредить команду login при помощи тех же методов, что и для passwd. Тем не менее, админист- ратор может сделать нечто большее, чем просто защитить данную прог- рамму от повреждения. По теории, наилучшей защитой является нападе- ние. Поэтому администратор может внести в команду login свои собственные правки и применять ее как систему оповещения о вмешатель- стве. Каждый раз, когда кто-то входит в систему или пытается войти, можно изменить запись об используемых имени и пароле. Это может сиг- нализировать вам о любых попытках нарушителей угадать пароли методом грубой силы. В силу способа, которым реализована команда login, требуется только одно изменение. Алгоритм проверки как пользовательского паро- ля, так и пароля при наборе номера для модемной связи вызывает одну и ту же подпрограмму. К сожалению, мы не можем привести ее здесь, так как несанкционированные пользователи смогли бы применить ее для сбора паролей в своих корыстных целях. Далее, если вы завели ваш собствен- ный секретный файл для протоколирования попыток входа в систему, то вы должны попытаться убедить нарушителей, что они не смогут прочитать его и останутся со своими заботами. Вы можете сделать следующее, хотя это увеличило бы накладные расходы: зашифровать утилитой crypt пароли в протокольном файле с применением вашего собственного секретного ключа. Тогда даже если кто-то прочитает этот файл, он не сможет вос- пользоваться этой информацией. Рассматриваемые ниже случаи представляют собой менее, но все же потенциально болезненные проблемы безопасности. Они не привлекают способов овладения суперпользовательскими привилегиями, но являются способами надувательства системы и бегства из нее. Данный прием, пожалуй, редко применяется, если только у вас нет человека, который очень близко знаком с низкоуровневым функционирова- нием того или иного процессора, используемого в вашей машине. Он мо- жет проникнуть в сердце аппаратного оборудования и пристроиться по- верх операционной системы. Тем не менее, администраторы должны осознавать, что такие вещи возможны. Во многих процессорах, например в процессоре Motorola 68000, имеется регистр состояния процессора (Processor Status Register), на- зываемый обычно PSW, хотя у разных процессоров он может называться по -разному. PSW содержит бит, определяющий, работает ли машина в "су- первизорном" или в пользовательском режиме. Этот режим важен для мно- гопользовательской аппаратуры, поскольку все пользовательские прог- раммы работают в пользовательском режиме, что сегментирует и защищает память от "коллизий" между процессами. С другой стороны, ядро работает в супервизорном режиме. Это оз- начает, что защита памяти не действует и центральный процессор может изменять содержимое любой ячейки памяти во всей машине. Ядру необхо- дима такая возможность, поскольку ядро поддерживает механизм своппин- га для перемещения процесса в защищенную память и из нее, когда про- цесс выполняется. Если нарушители безопасности могут получить в прграмму, работающую в системном режиме, то они получают возможность изменять всю память в системе. Последствия могут варьироваться от абсолютного разрушения, нап- ример записывания нулей в каждую ячейку памяти, до способности читать и сортировать данные в памяти, включая пароли и другую информацию с очень ограниченным к ней доступом. Для того чтобы добиться системного режима, нарушителю необходима возможность сгенерировать и установить новое ядро. Используемый метод зависит от того, есть ли у нарушителя исходный текст программ ядра. Приводимые нами подробности относятся к процессору 68000, но могут быть аналогичными для других процессоров. Первый метод - создать "пользовательский" системный вызов. Сис- темные вызовы находятся в исходных файлах с именами вида os/sys?.c. Это примерно 60 системных вызовов, и каждый из них имеет специфичес- кий номер. Этот номер определяется таблицей системных входов - табли- цей адресов точек входа в системные вызовы. Для добавления нового системного вызова необходимо подготовить его исходный код. Когда ядро перекомпилировано и установлено, можно производить системный вызов из любой программы в системе. Как только такой вызов активизирован, он может перевести машину в системный режим. К счастью, не так уж легко для "обычного" пользователя переком- пилировать и переустановить ядро системы. Этот метод, вероятно, тре- бует "внутренней работы". Помогло бы хранение ваших исходных текстов подальше от системы, но если вам нужно иметь системных програмистов, регулярно модифицирующих эти исходные тексты, то все, что в ваших си- лах - ограничить доступ (и подобрать надежных людей)! Второй метод может быть использован теми нарушителями, которые не имеют исходных текстов, но имеют все библиотеки, образующие ядро. Здесь подход несколько другой, но результат тот же. В соответствии с той же идеей системного режима, цель заключает- ся в том, чтобы в регистре PSW центрального процессора был установлен привилегированный доступ ("супервизорный" или "системный режим"). Вместо того, чтобы использовать надлежащим образом ядро, этот метод пользуется внешним драйвером, который связывается с ядром. Это выпол- няется путем создания псевдоустройства. Псевдоустройство подобно нас- тоящему устройству, но его имя не ведет ни к какой физической перифе- рии. Доступ к псевдоустройству осуществляется с помощью всех тех же самых примитивов (открыть, закрыть, читать, писать), но это доступ к логической области, а не к физической. Для того чтобы определить псевдоустройство, нужно модифицировать главный файл устройства. В главном файле (который называется /etc/master или /usr/sys/conf/master) имеется таблица всех имен драй- веров устройств, связанных с каждым примитивом. Когда создается псев- доустройство, в таблицу драйверов устройств помещается новая запись. В этой таблице содержатся имена всех подпрограмм, поддерживающих при- митивы. Привилегированного режима можно добиться при помощи открытия псевдоустройства. Системный вызов open передает управление драйверу устройства, т.е. добавленному коду. В момент запуска этого кода маши- на уже находится в системном режиме, поскольку когда выполнялся вызов open, он был "пойман" системой и передан программе обработки, функци- онирующей в системном режиме. После этого драйвер устройства может делать то, что он хочет. НАРУШИТЕЛЬ ВЫДАЕТ СЕБЯ ЗА УДАЛЕННЫЙ УЗЕЛ uucp Если команда login подобна сторожу крепости, то программа uucp подобна заброшенному спасательному туннелю, через который враги могут проникнуть во дворец. С приходом межмашинных коммуникаций возникает целый ряд пробоин в защите системы. При помощи uucp несанкционированные пользователи могут попасть в систему, выдав себя за удаленный узел uucp. Это очень легко сделать. Нарушители могут заглянуть в файл /usr/lib/uucp/L.sys в вашей системе и обнаружить, где находятся удаленные системы, путем поиска входов в систему на других машинах. Затем они могут посмотреть в файле /etc/passwd такие входы в систему, которые запускают программы uucico вместо обычного shell-интерпретатора. Если они обнаружат соответству- ющие пароли, они могут попытаться применить некоторые вероятные паро- ли или использовать один из методов внесения правок, рассмотренных ранее, с целью перехвата паролей. Затем нарушитель может изменить имя узла своей системы на имя узла удаленной системы, чтобы выдать себя не за того, кем он на самом деле является. Он может войти в систему под именем uucp или под спе- циальным регистрационным именем, предназначенным для удаленной маши- ны. Программы uucp передают это узловое имя (которое является под- дельным) в вашу систему. Нарушители могут перекачать почту, файлы и т.д. из вашей системы на свою машину. Если у вас есть что-нибудь в очереди, ожидающей отп- равки на законную удаленную машину, нарушители могут сразу там очу- титься. Вы можете столкнуться с неприятностями, когда один из ваших операторов законной удаленной системы звонит и спрашивает вас, почему он неделями не получает от вас ни почты, ни программных запросов! Од- нако, коварный нарушитель мог бы переслать копию украденных файлов обратно к вам и использовать прогрессивные средства для отправки их на законную удаленную машину. Этот прием довольно хорошо известен, но мы включаем его для пол- ноты изложения. Похоже, однако, что он работает не во всех версиях системы UNIX. Он работает в System V, но не работает в XENIX, System III и Berkeley 4.2. Данный метод заключается в изменении пользова- тельской переменной среды LOGNAME. Поскольку команда mail использует ее, чтобы идентифицировать вас при отправке вам почты, меняется заго- ловок почты. Обычно это всего лишь мелкая неприятность, но вы должны уведомить об этом пользователей, чтобы они очень внимательно относи- лись к таким сообщениям, которые кажутся несвойственными для их мни- мого отправителя. СКРЫТЫЕ ИМЕНА ФАЙЛОВ ПРИ РАБОТЕ С РЕДАКТОРОМ vi Полезной практикой для обеспечения безопасности является выпол- нение случайных команд ps. Такая мера более-менее равносильна перио- дическому патрулированию с целью увидеть, не происходит ли что-нибудь опасное. Необходимо, однако, отметить, что лица, использующие редак- тор vi для несанкционированной работы, могут замести свои следы, вы- бирая такое имя редактируемого файла, чтобы оно не появлялось в рас- печатке команды ps. Самый простой способ, которым они могут это сделать - вызвать vi без указания имени файла. Тем самым vi запуска- ется с пустым файлом. Затем они могут применить команду ex для редак- тирования нужного им файла. Это убережет имя файла от распечатки ко- мандой ps, так как оно не является частью набора аргументов команды vi. Массив аргументов формируется при вызове команды vi, а не после ее запуска. Другой способ - использовать маскировку. Нарушители могут переи- меновать файл, который они хотят редактировать, в ничего не означаю- щее имя, например tmp, а потом использовать имя tmp при вызове редак- тора vi. В результате в массив аргументов занесется имя tmp. Оно и появится в распечатке команды ps.
ИМЯ: access
access Ищет в парольном файле все регистрационные записи, не имеющие паролей. access access Выдает список всех беспарольных входов в систему 1 : 2 # @(#) access v1.0 Show all free access logins Author: Russ Sage 4 if [ "$#" -gt "0" ] 5 then echo "access: too many arguments" >&2 6 echo "usage: access" >&2 7 exit 1 8 fi 10 grep '^[^:]*::' /etc/passwd || echo "All logins protected" ОПИСАНИЕ ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ access? Мы уже отмечали, что записи о входе в систему в парольном файле создают возможность нарушения защиты, если с ними не связаны пароли, т.е. если поле пароля пустое. Проблема заключается в том, что в боль- ших системах парольный файл может сильно разрастись. Искать в таком файле вручную регистрационные записи, в которых отсутствуют пароли, было бы утомительным и приводило бы к ошибкам. Почему бы не поручить системе сделать за вас эту работу? ЧТО ДЕЛАЕТ access? Командный файл access использует команду grep с шаблоном поиска, описывающим регистрационную запись, не имеющую пароля. Когда такая запись попадается, она печатается в стандартный вывод. Если указанных записей не найдено, выводится сообщение "All logins protected" ("Все входы в систему защищены"). Первое, что делает access (в строках 4-8) - проверяет, правильно ли она была вызвана. Поскольку опций не предусмотрено, в командной строке ничего не должно быть. Если количество аргументов в командной строке больше нуля, то на стандартное устройство регистрации ошибок выдается сообщение об ошибке и командный файл завершается. Оператор в строке 10 выполняет поиск в парольном файле. Применя- ется утилита grep, т.к. мы используем в этой команде выражение. Если бы мы использовали фиксированную строку, более предпочтительной была бы утилита fgrep, потому что она быстрее. Выражение, задающее поиск, означает следующее: начиная с начала строки, найти все символы, от- личные от двоеточия, вплоть до обнаружения двух двоеточий подряд. Ес- ли вы заглянете в файл /etc/passwd, то увидите, что первое поле представляет собой имя (от начала строки до первого двоеточия). Затем между первым и вторым двоеточием размещается пароль. Если пароль от- сутствует, то после первого двоеточия сразу же следует второе - имен- но это соответствует нашему шаблону поиска. Поиск выполнятся в файле /etc/passwd. Если grep успешно обнаружил хотя бы одну запись, то код возврата нулевой. Если grep ничего не обнаружил, то код возврата еди- ница. Тогда активизируется последняя часть строки 10 и выводится со- общение о том, что все записи о входе в систему защищены.
ИМЯ: chkset
chkset Выдает список всех файлов, имеющих включенный бит разрешения ус- тановки пользовательского/группового идентификатора. chkset [-l] [dir ...] chkset -l Вести поиск, начиная с корневого каталога, поскольку каталог не указан. С помощью команды "ls -d" выдать список файлов, для которых установлен в единицу бит разрешения установки идентификатора пользо- вателя либо идентификатора группы. Результат отсортировать по имени файла. (Бит установки пользовательского идентификатора S_ISUID и бит установки группового идентификатора S_ISGID являются атрибутами защи- ты файла наряду с битами прав доступа на чтение/запись/выполнение и определены в подключаемом файле /sys/stat.h. - Примеч. перев.) 1 : 2 # @(#) chkset v1.0 Check for set bits on Author: Russ Sage 4 FORM="-print" 5 SORT="sort" 7 if [ "`echo $1 | cut -c1`" = "-" ] 8 then case $1 in 9 -l) shift 10 FORM="-exec ls -ld {} ;" 11 SORT="sort +7";; 12 *) echo "usage: chkset [-l][file/dir ...]" >&2 13 exit 1;; 14 esac 15 fi 17 if [ "$#" -gt 0 ] 18 then SRC="$*" 19 else SRC="/" 20 fi 22 find $SRC \( -perm -4000 -o -perm -2000 \) $FORM | $SORT FORM Команда и опции для листинга SORT Команда и опции для сортировки результата SRC Исходный каталог, от которого нужно начинать поиск ОПИСАНИЕ ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ chkset? Мы уже рассмотрели проблемы безопасности, которые могут возник- нуть, когда для исполняемых файлов установлен в единицу бит разреше- ния установки идентификатора пользователя. Это означает, что они мо- гут запускать интерпретатор shell с корневой или с другой привилегией высокого уровня. С той же целью может быть установлен в единицу бит разрешения установки идентификатора группы. Поэтому системный адми- нистратор должен непрерывно разыскивать и проверять все файлы в сис- теме, для которых установлены эти биты, чтобы посмотреть, не исполь- зуются ли они для несанкционированных целей. Не для всех интерпретаторов shell, нарушающих защиту, владельцем является суперпользователь (root). Один пользователь может запустить shell, владельцем которого является другой пользователь, имеющий бо- лее высокие привилегии. Это фактически предоставляет пользователю, запустившему shell, все возможности владельца файла. Найти shell-интерпретаторы, устанавливающие идентификатор поль- зователя или группы, бывает легко, а бывает и трудно, в зависимости от их авторства. Легко найти такие, которые: а) имеют необычные имена (некоторые нарушители любят выстав- лять свои достижения напоказ); б) содержат в исполняемом файле символьные строки, которые можно прочитать; в) размещены в необычном или очевидном каталоге; г) не имеют ограничений относительно того, кто может их запус- тить. Для изощренных shell-интерпретаторов характерно следующее: а) они имеют имена, похожие на обычные команды системы UNIX; б) имеют размеры файлов, которые соответствуют другим файлам, размещенным неподалеку от них; в) содержат упрятанные символьные строки, которые не так-то легко прочитать; г) имеют, возможно, специальную опцию, запускающую shell, или даже специальный пароль, необходимый для его запуска. Самые хулиганские из них являются настоящими командами системы UNIX, переделанными в корневые shell-интерпретаторы, которые затем переустанавливаются вместо первоначальных shell-интерпретаторов. Единственный надежный способ идентифицировать этот последний тип - запустить побайтовое сравнение между вашей дистрибутивной копией ко- манды системы UNIX и той версией, которая присутствует в настоящий момент в вашей системе. Конечно, перед тем как вы сможете проверить файлы со включенными битами разрешения установки пользовательского/группового идентифика- тора, вам нужно найти все такие файлы. В системе UNIX это делают две команды: find(1) и ncheck(1M). Утилита find ищет файлы по нашей точ- ной спецификации и может быть использована для поиска файлов с задан- ным набором прав доступа, включая биты установки идентификаторов. Ncheck печатает вперемешку специальные файлы и файлы с разрешенной установкой идентификатора пользователя. Это очень большой список, чтение и поиск в нем интересующих нас файлов занимает много времени. Таким образом, полезно создать командный файл, предоставляющий нам всю необходимую информацию и только такую информацию. Chkset исполь- зует команду find и ищет только файлы со включенными битами разреше- ния установки пользовательского/группового идентификатора, так что результат содержит лишь необходимую нам информацию, и этим результа- том можно сразу же воспользоваться. ЧТО ДЕЛАЕТ chkset? Chkset имеет два режима функционирования: один для сканирования всей системы в целом, а другой для сканирования указанных деревьев каталогов. Это хорошее свойство, так как сканирование каждого файла системы занимает очень много времени. Если имеется много больших дис- ковых устройств, проверка всего содержимого системы может занять це- лый час. Утилита chkset также очень сильно загружает центральный про- цессор из-за всех процессов, которые она генерирует. Указывая имена каталогов, вы можете выполнить проверку лишь на определенной области системного дерева. Отметим, однако, что поскольку chkset пользуется командой find, она сканирует не только указанный вами каталог, но и ВСЕ подчиненные каталоги. Заметим также, что chkset обнаруживает ВСЕ файлы с установленными в единицу битами установки пользовательско- го/группового идентификатора, а не только те, владельцем которых яв- ляется суперпользователь (root). Результат работы chkset можно выдать также двумя способами. Если не применять никакую опцию, то форма выдачи результата определяется командой "find ... -print", что означает полные маршрутные имена най- денных файлов. Затем эти полные имена сортируются. Если применяется опция -l, то для форматирования результата ис- пользуется команда "ls -ld", порождающая длинный формат листинга. При этом распечатываются полное указание прав доступа, число связей, вла- делец, размер и имя файла. Этот результат также сортируется по име- нам. Выбирайте тот или иной формат в зависимости от обстоятельств. Если вам нужно проверить большой участок системы и получить список подозрительных файлов, примените листинг по умолчанию (без опций), так как он компактнее и, как мы увидим позднее, занимает значительно меньше процессорного времени. Если вы хотите заняться определенным каталогом и посмотреть на его файлы подробно, воспользуйтесь опцией - l. Она предоставляет больше информации и избавляет от необходимости вручную набирать команды ls для интересующих вас файлов. Отметим, что эту команду может запустить кто угодно, а не только администратор, имеющий привилегии суперпользователя. Однако, если она запускается обычным пользователем, то команда find внутри командного файла chkset ограничена теми файлами, к которым пользователь имеет доступ на чтение. Так что вы могли бы предложить более привилегиро- ванным пользователям запускать chkset в качестве одной из их личных мер безопасности. Разумеется, если chkset запускается суперпользова- телем, то ограничения прав доступа к файлам несущественны и можно подвергнуть проверке все файлы. # chkset /bin /usr/bin /lib /usr/lib Эта команда вызывает просмотр указанных каталогов. В каталогах типа /usr/lib просматриваются все подчиненные каталоги, что обеспечи- вает более тщательную проверку. Первым делом chkset инициализирует две переменные - FORM и SORT. Переменная FORM содержит команду для выдачи результата работы команды find, а переменная SORT - команду, определяющую, что нужно сортиро- вать. В строке 7 проверяется, является ли первый позиционный параметр опцией. Если да, то оператор case (строки 8-14) смотрит, какая это опция. Если это опция "-l", то подготавливается команда для распечат- ки результата (это мы обсудим позже). Команда для утилиты sort форми- руется так, чтобы сортировка шла по полю владельца. Опция убирается из командной строки, потому что все последующие аргументы должны быть каталогами и мы захотим получить к ним доступ с помощью "$#". Если попалась опция, отличная от "-l", то это ошибка, выдается сообщение об ошибке (строка 12), и командный файл завершается. Если осталось более нуля аргументов, когда мы попадаем в строку 17, то они проверяются в цикле, чтобы убедиться, что все они являются каталогами. Если это не каталоги, на стандартное устройство регистра- ции ошибок выдается сообщение об ошибке и командный файл завершается. Если имеются параметры (т.е. каталоги), то в строке 18 в пере- менную SRC заносятся все каталоги. Если же параметров нет, то в пере- менную SRC заносится значение "/", т.е. корневой каталог, чтобы обес- печить подразумеваемую стартовую точку для поиска. Вся работа этого командного файла выполняется фактически в опе- раторе find. Команда find допускает множественное указание каталогов, которые поступают в результате чтения их из командной строки и зане- сения в переменную SRC. После того как мы указали команде find, откуда начинать поиск, мы указываем ей, что нужно искать. В данном случае нас интересуют все файлы, которые имеют включенный бит установки пользовательского либо группового идентификатора. Мы объясняем это команде find путем указа- ния прав доступа, которые требуется искать. Строка "-perm -4000" оз- начает поиск всех файлов, имеющих права доступа со включенным битом установки пользовательского идентификатора и с любыми другими вклю- ченными битами. Вы можете понимать эту запись как применение символов -заменителей - 4???. Мы ищем как установку пользовательского иденти- фикатора (-4000), так и установку группового идентификатора (-2000), поэтому две строки прав доступа соединены опцией -o, означающей "or" ("или"). (Более полное описание прав доступа в символической и вось- меричной форме приведено в chmod(1).) Следующая задача - добавить строку, хранимую в переменной FORM, в командную строку. Если опция -l не была использована, то в перемен- ной FORM хранится строка "-print", а это значит, что find будет печа- тать маршрутные имена найденных файлов. Если же -l использовалась, то переменная FORM содержит строку "-exec ls -ld {} ;". Опция -exec - это очень гибкая опция команды find, позволяющая применить любые ко- манды, которые за ней следуют, к каждому найденному файлу. В данном случае эти команды выполняют распечатку в длинном формате (-l), при- чем для каждого каталога (-d) выводится только его имя (а не содержи- мое). Именно здесь происходят наибольшие затраты ресурсов центрально- го процессора, так как для опции -l требуется системный вызов stat. Из-за того, что для каждого файла требуется команда ls, она каждый раз загружается в память и выполняется. Производится также доступ к индексному дескриптору файла на диске. Это приводит к большим наклад- ным расходам. Затем весь поток данных пропускается через утилиту sort. На са- мом деле мы хотим сделать сортировку по восьмому полю (вы можете про- верить это, выполнив команду "ls -l" и изучив ее результат). Утилита sort ПРОПУСКАЕТ указанное число полей, начиная с поля 1, являющегося по умолчанию стартовой точкой, поэтому использование записи +7 озна- чает переход к восьмому полю, которым является имя файла. Для поиска файлов с интересующими нас правами доступа можно при- менить другой метод, хотя и более медленный. Он основывается на том, что вместо поиска прав доступа по числу, можно искать их по символь- ной строке. Для этого нужно применять grep. Альтернативная команда выглядит так: # find $* -exec ls -ld {} \; | grep "^[^ ]*s[^ ]*" Этот вариант команды работает несколько иначе. Он находит каждый файл из указанных каталогов и применяет к каждому из них команду "ls -ld". Затем весь список данных передается по конвейеру команде grep. Grep использует для распознавания интересующих нас файлов такой шаб- лон поиска: начиная с начала строки, найти повторяющийся символ, от- личный от пробела, затем символ "s", за которым следует повторяющийся символ, отличный от пробела. Такому шаблону соответствуют все режимы прав доступа, содержащие s, будь то бит установки пользовательского идентификатора или бит установки группового идентификатора. Не су- щественно, входят ли в данный режим "r", "w", "x" или "-". Убедив- шись, что пробелов нет, мы обеспечиваем соответствие шаблона только полю прав доступа. Важно, чтобы после s следовали символы, отличные от пробелов, так как s может встретиться либо в порции прав доступа, относящейся к владельцу, либо в групповой порции и нигде больше. Мы не очень рекомендуем этот метод, поскольку он привлекает очень интенсивную обработку. Однако, если бы мы не испробовали этот метод первым, мы бы не оценили, что использование команды find со строками "-perm" является более предпочтительным. В силу невероятной гибкости системы UNIX, имеется очень много различных способов выпол- нения одной и той же работы, и многие из этих способов могут давать одинаково хорошие результаты, но за разную цену в смысле быстродейс- твия и процессорных затрат. Перед тем как применять универсальную утилиту вроде grep для решения задачи, рассмотрите, нет ли другой ко- манды со встроенной опцией распознавания по шаблону. Скорее всего, применение такой команды окажется оптимальнее и гораздо быстрее, чем использование grep. С другой стороны, иногда вам нужно быстро решить нечасто встречающуюся задачу, не слишком заботясь об эффективности решения.
ИМЯ: suw
suw Просматривает протокольный файл команды su и печатает имена всех пользователей, которые нелегально превратились в суперпользователя при помощи команды su (substituted user, замененный пользователь). suw [-m] [sulog] suw Запуск в режиме по умолчанию, проверка файла /usr/adm/sulog и выдача записей о нарушителях в стандартный вывод. 1 static char id[]="@(#)suw v1.0 Author: Russ Sage"; 3 # include 5 # define FALSE 0 6 # define TRUE 1 7 # define MATCH 0 8 # define BSIZ 80 10 main(argc,argv) 11 int argc; 12 char *argv[]; 13 { 14 register int alert, c, mail, n; 15 FILE *fp1, *fp2; 16 char *p, *uname, line[BSIZ], tmp[BSIZ], 17 *log = "/usr/adm/sulog"; 19 static char *legal[] = {sage-root\n","root-root\n",NULL}; 20 static char *adm[] = {"sage",NULL}; 23 mail = FALSE; 25 if (argc > 1 && argv[1][0] == '-') 26 switch (argv[1][1]) 27 { 28 case 'm': 29 mail = TRUE; 30 --argc; 31 ++argv; 32 break; 33 default: 34 fprintf(stderr,"suw: invalid argument %s\n", argv[1]); 35 fprintf(stderr,"usage: suw [-m] [sulog]\n"); 36 exit(1); 37 } 39 if (argc == 2) 40 log = *++argv; 42 if ((fp1 = fopen(log,"r")) == NULL) 43 { 44 fprintf(stderr,"suw: error opening %s\n",log); 45 fprintf(stderr,"usage: suw [-m] [sulog]\n"); 46 exit(1); 47 } 49 sprintf(tmp,"/tmp/suw%d",getpid()); 50 if ((fp2 = fopen(tmp,"w+")) == NULL) 51 { 52 fprintf(stderr,"suw: error opening %s\n",tmp); 53 fprintf(stderr,"usage: suw [-m] [sulog]\n"); 54 exit(1); 55 } 57 while (fgets(line,sizeof(line),fp1) != NULL) 58 { 59 p = line + 15; 60 if (*p == '+') 61 { 62 p = p + 2; 63 while (*p != ' ') p++; 64 p++; 65 uname = p; 66 while (*p && *p++ != '-') 67 continue; 69 if (strcmp (p,"root\n") == MATCH) 70 { 71 alert = TRUE; 72 for (n=0; legal[n] != NULL; n++) 73 if (strcmp (uname,legal[n]) == MATCH) 74 { 75 alert = FALSE; 76 break; 77 } 78 if (alert) 79 fprintf(fp2,"Illegal --> %s", line); 80 } 81 } 82 } 84 if (mail) 85 { 86 fclose(fp2); 87 for (n=0; adm[n] != NULL; n++) 88 { 89 sprintf(line,"cat %s | mail %s",tmp,adm[n]); 90 system(line); 91 } 92 } 93 else 94 { 95 rewind(fp2); 96 while ((c = getc(fp2)) != EOF) 97 putc(c, stdout); 98 fclose(fp2); 99 } 101 fclose(fp1); 102 unlink(tmp); 103 } ОПИСАНИЕ ЗАЧЕМ НАМ НУЖНА ПРОГРАММА suw? Вы помните, что команда su, позволяющая пользователям изменять свою индивидуальность (и права доступа) может быть источником проблем безопасности. Система хранит протокол всех транзакций su в файле sulog. Хотя более опытные нарушители могут уметь затирать свои следы, файл sulog полезен для отслеживания потенциальных лазеек в системе защиты. Этим способом можно поймать многих нарушителей-любителей. Ес- тественно, мы хотим автоматизировать этот процесс, чтобы система вы- полняла проверку и сигнализировала нам при обнаружении чего-либо опасного. Кроме того, данная программа демонстрирует методику, кото- рую можно использовать для отслеживания других протокольных файлов. ЧТО ДЕЛАЕТ suw? Программа suw читает и анализирует протокольные файлы команды su. Каждое успешное превращение в суперпользователя при помощи коман- ды su, обнаруженное в протокольном файле, сверяется со списком разре- шенных суперпользователей. Если пользователю не разрешено быть супер- пользователем, то конкретная запись о нем печатается, чтобы оповестить администратора. По умолчанию записи о нарушителях печатаются в стандартный вы- вод. Протокольным файлом по умолчанию является /usr/adm/sulog. Если применяется опция -m, то записи о нарушителях рассылаются по почте администраторам, занесенным в предопределенный список. Если нужно проверить другой протокольный файл, например /usr/adm/Osulog, то его имя можно указать в командной строке. 1. # suw -m Проверить файл /usr/adm/sulog и разослать записи о нарушителях администраторам, определенным в тексте программы. 2. # suw /usr/adm/Osulog Проверить файл /usr/adm/Osulog и напечатать записи о нарушителях в стандартный вывод. В самом начале программы определяются и инициализируются все пе- ременные и списки. В строке 14 определены два флага: alert (сигнал тревоги) и mail (почта). Они имеют значение TRUE или FALSE. В этой программе используются два файла: протокольный файл команды su, кото- рый вы выбираете, и временный файл. Поскольку мы собираемся применять некоторые подпрограммы стандартного ввода-вывода (stdio), мы пользу- емся указателями на файлы fp1 и fp2, а не дескрипторами файлов. При- меняется два буфера: один для зачитывания в него данных из протоколь- ного файла команды su, а другой - для хранения имени временного файла. Первоначально именем протокольного файла является sulog. Если вместо него используется другое имя файла, то переменная log переус- танавливается на это имя. Затем инициализируются предопределенные списки разрешенных су- перпользователей и администраторов. В нашем примере двумя разрешенны- ми суперпользователями являются sage (sage-root) и root (root-root). Для того чтобы приспособить это для вашей системы, поместите здесь имена людей, которым вы хотите разрешить пользоваться командой su для превращения в суперпользователей. Список администраторов также должен содержать соответствующие имена. В данном примере в список админист- раторов входит одно имя - sage. Это значит, что sage будет единствен- ным, кто получит почту, если указана почтовая опция. Подразумеваемое состояние рассылки почты устанавливается в стро- ке 23 на значение FALSE, т. е. почты нет. Это делается для того, что- бы после разбора командной строки переменная mail имела правильное значение. Далее выполняется проверка на ошибки. Первая проверка выглядит несколько странной, но на самом деле вполне понятна. Переменная argc возвращает число аргументов командной строки, а argv указывает на массив, содержащий сами аргументы, каждый из которых сам является массивом символов. Если командная строка вообще имеет какие-либо ар- гументы (argc > 1) и первым символом первого аргумента (argv[1][0]) является дефис, то проверяется, корректная ли это опция. С целью про- верки второго символа первого аргумента используется оператор case. Если аргументом является символ m, то флаг mail устанавливается в состояние TRUE, число аргументов (argc) уменьшается на единицу, а указатель на массив аргументов (argv) на единицу увеличивается. Это служит той же цели, что и удаление аргументов из командной строки в командных файлах интерпретатора shell. Напомним, что argv является в действительности массивом указателей, а массивы трактуются точно так же, как строки, с базовым адресом и смещением. Поэтому argv[0] == argv, и argv[1] == ++argv. Если опция отличается от -m, то в стан- дартный вывод печатается сообщение об ошибке и программа завершается. В строке 39 проверяется счетчик аргументов, чтобы понять, есть ли еще один аргумент. Напомним, что argv всегда на единицу отстает от argc, потому что само имя команды является первым аргументом массива. Следовательно, для того чтобы получить второй аргумент, мы должны пе- рейти к следующей позиции (*++argv). Если аргумент имеется, он должен быть именем протокольного файла, и это имя заносится в переменную log. Далее мы пытаемся открыть файлы, используемые в программе. Сна- чала открывается для чтения протокольный файл. Если это не срабатыва- ет (возвращен нулевой указатель), то печатается сообщение об ошибке и программа завершается. Затем в строке 49 создается имя временного файла с добавлением к нему идентификатора процесса, чтобы гарантиро- вать уникальность имени файла. Этот файл открывается на чтение и за- пись. Если эта операция не удается, печатается сообщение об ошибке и выполнение завершается. В строках 57-103 заключен главный цикл. Управляющая часть глав- ного цикла определяется тем, все ли данные прочитаны из протокольного файла. Если больше никакие байты прочитать нельзя, то fgets (строка 57) возвращает нулевой указатель, что завершает цикл while. Когда строка данных читается из протокольного файла, эти данные помещаются в массив line. Мы применяем указатель на символ для прохода вдоль строки и поиска записи о нарушителе. Изучая запись в вашем файле sulog, вы можете увидеть, где нахо- дятся интересующие нас поля. Сначала указатель смещается на 15 симво- лов от начала строки. Это позиция флага, определяющего, была ли ус- пешной команда su. Если она была успешной, указатель увеличивается на два, чтобы пропустить пробел и установить указатель на имени термина- ла. Это имя имеет переменную длину, поэтому мы ориентируемся по про- белу в конце имени. В строках 63-64 применяется цикл while, который заставляет указатель пропустить все символы, отличные от пробела. За- тем он увеличивается на единицу еще раз, чтобы пропустить пробел меж- ду именем терминала и строкой имени пользователя. В этот момент указатель находится в последнем поле строки. Ука- затель на это поле помещается в переменную uname, чтобы затем ее мож- но было использовать для сравнения строк. Следующий цикл while (стро- ки 66-67) проходит по строке, пока не попадет на символ дефиса. Цикл while выполняется до тех пор, пока указатель не указывает на конец строки (т.е. на нелевой указатель, *p == '\0') и еще не указывает на дефис. Поскольку в цикле используется p++, то когда мы попадаем на нулевой указатель, цикл завершается, причем p указывает на следующий символ. Выполняется проверка, был ли суперпользователем тот, кто приме- нил команду su. Если был, то взводится флаг alert, и мы должны прове- рить, разрешенный ли это суперпользователь. Цикл for (строки 72-77) пробегает по всем именам в массиве, содержащем имена разрешенных пользователей, до тех пор, пока мы не обнаружим последнюю запись, ко- торая является пустой. Строка с именем пользователя, установленная предварительно, сверяется с каждой записью в массиве разрешенных имен. Если они совпадают, то мы можем предположить, что с данным при- менением команды su все в порядке. Тогда мы выключаем флаг alert и завершаем сравнение имен. Если же по окончании цикла флаг alert все еще взведен, значит имя не содержится в списке разрешенных - это, возможно, нарушитель. Вся запись целиком записывается во временный файл и управление передается назад в начало цикла для следующей опе- рации чтения. Когда все данные прочитаны, цикл while завершается. В строке 84 проверяется, взведен ли флаг mail. Если да, то временный файл закры- вается (чтобы сработала команда cat) и выполняется еще один цикл for (строки 87-91). Он перебирает всех администраторов и завершается, когда попадает на нулевой указатель в конце массива. Для каждого из обозначенных администраторов конструируется команда mail и посылается в систему UNIX при помощи системного вызова (строка 90). Метод отп- равки по почте временного файла заключается в применении к этому фай- лу команды cat и передаче данных по конвейеру команде mail. Если флаг mail выключен, то временный файл нужно напечатать в стандартный вывод, а не отправить по почте. Для того чтобы сделать это как можно быстрее, временный файл (который пока еще открыт) "пе- рематывается" (мы позиционируемся в его начало) и посимвольно пропус- кается по циклу. Обратите внимание, что данный цикл является сердце- виной команды cat, как описано на странице 153 книги Кернигана и Ритчи "Язык программирования Си" (B.W.Kernighan, D.M.Ritchie. The C Programming Language). После того как временный файл напечатан, он закрывается. Наконец, закрывается протокольный файл и удаляется вре- менный файл.