Безопасный SQL-сервер
Серверы Microsoft SQL являются одной из излюбленных целей для интернет-хакеров [1], в первую очередь из-за активности червей (например, SQL Spida, Slammer), распространяющихся через этот сервис, во-вторых, из-за того, что доступ к незащищенным, однако подключенным к Интернету SQL-серверам довольно ограничен. легкий. В этой статье я хотел бы описать правила защиты службы Microsoft SQL Server, чтобы помочь вам, уважаемые читатели, защитить себя от последствий возможных атак.
Следует начать с упоминания того, от каких видов атак вы собираетесь защищаться. Чтобы упростить задачу, эти атаки следует разделить на две категории: первая категория — это атаки, направленные на сервер, которые также могут быть сгруппированы в подкатегории в зависимости от цели атаки:
- Операционная система, т. е. компьютер, на котором запущена служба SQL Server. Цель такой атаки — получить привилегии администратора системы, на которой запущена служба. Успешный взлом позволит злоумышленнику получить контроль над службой SQL Server и предоставить полный доступ к данным.
- Служба SQL Server: цель злоумышленника — получить тот же доступ, что и у администратора службы SQL. Эта атака может быть или не быть прелюдией к более сложной операции, ведущей к атаке на саму операционную систему. Конечно, злоумышленник также может получить контроль над данными.
Вторая категория атак — это попытка получить доступ к некоторым данным, которые должны быть недоступны конкретному пользователю. К сожалению, довольно часто встречается ситуация, когда в базе данных отсутствуют какие-либо средства ограничения доступа, и в этом случае такое действие вообще нельзя назвать атакой. Часто это происходит из-за любопытства пользователей, которое не ограничено политиками безопасности базы данных, поскольку они никогда не были бы определены, как гласит правило «Если безопасность не установлена, все просто работает» [2].
Защитите свою операционную систему!
Тот факт, что SQL-сервер необходимо защищать, вызывает удивление у многих администраторов, поскольку считается, что служба не может причинить никакого вреда. Однако это ошибочный аргумент. Администратор SQL-сервера имеет право запускать любой выбранный им код внутри SQLSERVR.EXE с использованием xp_cmdshell, xp_regwrite или самостоятельно созданных процедур. Это позволяет ему общаться с операционной системой сервера без каких-либо ограничений. Эта возможность встроена в службу SQL Server и ее невозможно отобрать у пользователя sa, т.е. у администратора сервера. Однако в любое время привилегии «sa» ограничены политиками службы SQL. Отсюда следует, что чем ниже уровень привилегий, предоставляемых службой SQL-сервера, тем менее рискованным является ее взаимодействие с операционной системой. В документации службы указано, что службе не требуется авторизация администратора для выполнения обычных задач. Достаточно пользователя, которому разрешено «входить в систему как службу». Однако некоторые задачи требуют специальных припусков. Это, например:
- Делаем xp_cmdshell доступным для обычных пользователей SQL-сервера. Если обычным пользователям службы SQL Server разрешается выполнять команды операционной системы, расширенная процедура xp_cmdshell должна изменить маркер безопасности на менее привилегированный, чем унаследованный от процесса службы SQLSERVR.EXE.. Для этого требуется высокая авторизация. Иными словами, если вы хотите сделать xp_cmdshell доступным для обычных пользователей, вам придется повысить авторизацию службы SQL-сервера в операционной системе до уровня LocalSystem. Чтобы быть более точным, вам нужно разрешить ему «действовать как часть операционной системы» и «заменять токен уровня процесса». Я настоятельно не рекомендую вам использовать такую конфигурацию по понятным причинам;
- Связь с другими серверами по сети. В этом случае будет достаточно очень простого правила: права доступа службы через сеть равны полномочиям ее учетной записи. У учетной записи LocalSystem таких прав нет (есть одно исключение, которое здесь описываться не будет, т. е. нулевая сессия, так как она нарушает базовые правила безопасности). Поэтому учетной записи обычного пользователя будет достаточно, чтобы служба SQL могла, например, реплицировать данные с другими серверами или создавать резервные копии баз данных на сетевых ресурсах и т. д.
- SQL-сервер, работающий в отказоустойчивом кластере, т.е. Microsoft Cluster Server. В такой ситуации сервис должен иметь административные права на обоих узлах кластера. Именно этого требуют службы кластера Windows.
Microsoft SQL Server — это не просто служба MSSQLServer. Он сопровождается SQLServerAgent, используемым для выполнения задач, которые могут выполняться администратором или пользователями. Для этой службы могут потребоваться административные права в следующих ситуациях:
- Если вы хотите разрешить обычным пользователям запускать задачи или сценарии операционной системы,
- Чтобы разрешить автоматический перезапуск SQL Server в случае сбоя,
- Предусмотреть возможность выявления периодов низкой активности системы для выполнения в эти периоды ранее запланированных задач.
Если в этих возможностях нет необходимости, SQLServerAgent может работать под общей учетной записью пользователя, которая имеет право работать в качестве службы. Более того, вполне удобно, если обе службы (SQLServer и SQLServerAgent) используют одну и ту же учетную запись. Это упрощает администрирование без увеличения рисков. Цель этой статьи не в том, чтобы объяснить, есть ли и при каких обстоятельствах разумное использование тех возможностей, которые требуют более высоких разрешений. Это должно быть решено до установки SQLServer. В большинстве случаев отправной точкой могут быть следующие принципы:
- Служба MSSQLServer не запущена в кластере MSCS,
- Пользователи не имеют прав на выполнение команд операционной системы, xp_cmdshell, а также задач, определенных SQLServerAgent,
- Службе SQLServerAgent не нужно перезапускать SQLServer в случае сбоя. Такая ситуация должна вызывать реакцию администраторов и ручное вмешательство, а не автоматический перезапуск службы. Мониторинг SQL-сервера с помощью специальных инструментов, очевидно, облегчил бы реакцию в таких ситуациях.
- Службе SQLServerAgent не нужно обнаруживать периоды низкой активности сервера,
- Служба SQLServer может взаимодействовать с другими серверами в локальной сети, если ей явным образом предоставлены необходимые права.
В этом случае учетная запись, под которой должны запускаться службы MSSQLServer и SQLServerAgent, должна быть определена как пользователь домена без специальных прав в домене. Кроме того, у него не должно быть никаких прав на локальный вход в качестве «пакетного задания» или «службы» на других компьютерах и даже прав на сетевое взаимодействие с серверами, когда объект групповой политики определен внутри домена. Очевидно, что этих авторизаций недостаточно для запуска службы. В системе должна быть подготовлена и отделена от нее Организационная единица (OU). Машина, на которой должен работать SQL-сервер, должна быть размещена в этой OU, а также другие серверы, с которыми служба должна взаимодействовать в рамках использования сети. Объект групповой политики должен быть определен в организационном подразделении. Выбранной учетной записи должно быть разрешено входить в качестве службы в OU, и к ней можно получить доступ из сети. Следует также рассмотреть вопрос об уязвимости пароля к атакам. Пароль не будет использоваться человеком, поэтому он может достигать любого уровня сложности. С другой стороны, на него должны распространяться правила, применимые к управлению паролями в организации. Это означает, что пароль необходимо регулярно менять, что влечет за собой необходимость обновления сервисов, использующих учетную запись. Еще один способ решить эту проблему — создать пароль, который будет настолько сложным, что сделает невозможным грубую атаку на долгое время. Такой пароль должен состоять не менее чем из 30 символов, половина из которых — специальные. При этом служба SQLServer должна иметь как минимум доступ только для чтения к директории, в которой она установлена, например C:Program FilesMicrosoft SQL ServerMSSQL, а также полный доступ к директориям данных, к журналу событий и разрешение на чтение всего корневого каталога указанного диска, который часто предназначен для хранения данных. Службе также должен быть разрешен доступ к каталогу, в котором хранится информация о конфигурации:
HKEY_LOCAL_MACHINESoftwareMicrosoftMSSQLServer. Службе SQL Server не должно быть разрешено изменять данные в каталоге, в котором хранятся данные, используемые для запуска службы, т. е. HKEY_LOCAL_MACHINESystemCurrentControlSetServicesMSSQLServer. В противном случае пользователь sa будет иметь возможность добавить к этой записи значение «ObjectName=LocalSystem», чтобы служба предоставила ему авторизацию LocalSystem, как только она будет запущена в следующий раз. Пример такой атаки, предотвращенной благодаря подходящему определению авторизаций, размещенных в реестре, представлен на рисунке 2.
Эта проблема описана в бюллетене по безопасности MS02-034 [3]. Когда процесс настройки систем подходит к концу, следует убедиться в отсутствии элементарных багов безопасности, вроде авторизации «Все: Полный доступ» в корневом каталоге C:/ на сервере. Другим очень важным элементом является план того, как сервер должен взаимодействовать с клиентами. Любое взаимодействие ненадежных компьютеров со службой SQLServer и наоборот должно быть запрещено. Порты TCP 1433 (порт службы по умолчанию) и UDP 1434 (идентификация сервера SQL, не нужны, если пользователь знает номер порта TCP службы) должны быть заблокированы брандмауэром. Если предполагается использование SQL-сервера пользователями из удаленных сетей, следует позаботиться о безопасности соединения между ними, например, при использовании технологии VPN. Установка службы SQLServer на необычный порт — совершенно неэффективная защита. Любой инструмент, подходящий для сканирования портов, найдет ваш «скрытый» сервер за ограниченное (и обычно короткое) время.
Системные администраторы часто удаляют xp_cmdshell или другие процедуры, позволяющие использовать операционную систему, например, xp_regwrite, для защиты своих серверов. К сожалению, такие действия совершенно бесполезны. Ни одна из этих процедур не позволяет волшебным образом повысить права службы до уровня, превышающего уровень, настроенный системным администратором, т.е. служба будет иметь те же полномочия, что и учетная запись, под которой она запущена. Единственным эффективным способом предотвращения доступа операционной системы к службе SQLServer являются системные меры безопасности, такие как авторизация реестра и файловой системы, необходимые исправления, трудно угадываемые пароли и т. д. Если упомянутые процедуры каким-либо образом были удалены, может получить их с помощью «sp_addextendedproc» или путем создания записей в системных таблицах «главной» базы данных.
Если на одном сервере работает несколько экземпляров службы SQLServer, необходимо учитывать тот факт, что каждый из них не должен иметь доступа к исполняемым файлам или файлам данных, а также к записям реестра, используемым другими экземплярами. Таким образом вы изолируете данные экземпляров и авторизации. О таком типе изоляции, очевидно, не может быть и речи, если бы все экземпляры SQL имели права администратора на сервере. Если вы устанавливаете несколько экземпляров службы SQLServer на один компьютер, помните о его возможностях и соответствующим образом распределяйте его ресурсы — выделяйте выделенные процессоры и физические диски или таблицы хранения RAID для каждого экземпляра, а также не забывайте ограничивать использование оперативной памяти. Еще одна вещь, которую следует помнить, это то, что какие бы шаги ни предпринимались, огромная нагрузка на сервер, вызванная одним из экземпляров, будет замедлять работу других. Эта задача шагов, которые необходимо предпринять, заключается в минимизации негативного влияния, так как полностью нейтрализовать его невозможно. Вот почему запускать несколько экземпляров SQLServer на одном сервере — не лучшая идея.
Защитите свой SQL-сервер!
Служба SQLServer оснащена усовершенствованными устройствами управления безопасностью, которые были частично объяснены в статье, описывающей механизмы проверки подлинности. Небольшое напоминание: есть два способа входа на сервер SQL:
- Основанный на собственном механизме учетных записей SQLServer, возможен только в смешанном режиме,
- Аутентификация на основе операционной системы (т.е. аутентификация Windows NT), также называемая доверительной аутентификацией.
Наиболее привилегированной учетной записью службы SQL является учетная запись «sa» или учетная запись системного администратора. Он всегда создается во время установки и использует собственный механизм аутентификации SQLServer, доступный только в режиме смешанной аутентификации. Это означает, что установка режима аутентификации на «доверенный» — хороший способ заблокировать доступ к учетной записи «sa». Учетная запись sa имеет полный контроль над службой SQL. Можно сказать, что процесс SQLSERVR.EXE имеет те же привилегии, что и учетная запись sa, и наоборот: учетная запись sa может запускать любой код с привилегиями учетной записи, используемой службой. Пользователи сервера, принадлежащие к группе «sysadmin», имеют те же привилегии, что и пользователи «sa». Учетная запись BUILTIN/Administrators, т.е. локальная группа администраторов системы, на которой установлена служба, по умолчанию принадлежит к этой группе. Эта учетная запись не использует пароль; он аутентифицирует пользователей, используя доверенное соединение. Отныне будем говорить, что аббревиатура «sa» будет обозначать всех из группы «sysadmin». Благодаря такой конфигурации администраторы сервера, на котором установлен SQLServer, имеют возможность войти в систему под учетной записью «sa» и получить неограниченный доступ к данным и управлению услугами. Противоречивого отношения не возникает; учетная запись sa имеет те же привилегии, что и SQLSERVR.EXE.
Сама учетная запись является единственной, уполномоченной управлять «главной» базой данных, которая является основной базой данных, содержащей информацию о других базах данных, учетных записях пользователей, файлах, содержащих данные, и т. д. Сервер SQL не может работать без этой базы данных. Пустая может быть создана с помощью инструмента «rebuild master database», если возникнет такая необходимость, а впоследствии на ее месте должна быть воссоздана правильная база данных из резервной копии безопасности. Каждая база данных имеет список локальных пользователей. В этом списке учетная запись «dbo» (что означает «владелец базы данных») полностью авторизована для управления базой данных, тогда как «гость» означает каждого пользователя SQL-сервера. Если вы создадите «гостевую» учетную запись в любой из баз данных, она будет доступна из любой учетной записи, имеющей доступ к службе SQLServer. Базы данных также имеют роли (т.е. группы пользователей). Специальная «общедоступная» группа, определенная в каждой из баз данных, означает всех пользователей этой базы данных. База данных «главный» имеет только двух пользователей, и это не должно быть изменено. Это:
- «dbo», которое является локальным именем учетной записи «sa» в базе данных «master»,
- «Гость», который позволяет каждому пользователю выполнять основные операции в «главной» базе данных после входа на сервер SQL.
Права «общедоступных» групп и «гостевых» пользователей в «главной» базе данных очень ограничены, поскольку им не разрешено создавать базы данных или учетные записи, читать пароли и т. д. Права доступа обычного пользователя к другим базам данных также поскольку права доступа к таблицам и процедурам, которые они содержат, должны быть настроены неклассифицированным образом. Это будет объяснено далее в статье. Теперь давайте сосредоточимся на защите доступа к учетной записи «sa».
Основной защитой учетной записи sa является пароль, который не должен быть нулевым. Однако он настраивается таким образом по умолчанию после завершения установки MSDE. Это может произойти независимо от того, какие параметры установки были в случае с SQLServer. Сразу после завершения установки вы должны войти на сервер SQL, выполнив команду «osql.exe.-E» из-под учетной записи администратора. Затем используйте процедуру «sp_password @new='this-is-the-'sa'-password',loginame='sa'», но не указанный пароль. Если бы сервер не работал в смешанном режиме, это был бы единственный пароль в «главной» базе данных, и он оставался бы неиспользованным. Сервер, не работающий в смешанном режиме, не позволит войти в систему под учетной записью sa с использованием пароля, даже если он был указан правильно. Тем не менее, пароль должен быть установлен, потому что изменение режима входа в систему обычно не подлежит процедурам безопасности, идентичным слежке за административными паролями. Неосторожное изменение режима аутентификации перед установкой пароля «sa» является часто совершаемой и серьезной ошибкой, часто используемой червями. Вы, наверное, уже заметили, что аутентификация на основе паролей, сохраненных в «главной» базе данных, гораздо опаснее, чем аутентификация Windows. Вот почему применение SQL-сервера должно быть спроектировано таким образом, чтобы каждое приложение могло установить с ним доверенное соединение. Это позволит включить механизмы проверки подлинности на основе SQLServer и использовать встроенные в Windows механизмы защиты учетных записей, такие как блокировка учетной записи, что помогает предотвратить попытки атаки методом грубой силы. Кроме того, в конфигурации сервера должна быть предусмотрена команда для создания журнала попыток входа в систему, чтобы можно было отслеживать попытки атак. Еще одной мерой безопасности является продуманное ограничение доступа к расширенным процедурам SQLServer. Эти процедуры позволяют обычному пользователю воспользоваться банальными ошибками программиста для получения авторизации sa, поскольку эти функции поступают из внешних DLL-файлов и выполняются внутри процесса службы MSSQLServer. Они работают с теми же правами, что и учетные записи «sa», поэтому простой сбой, такой как переполнение буфера или ошибочная интерпретация аргументов пользователя, может сделать учетную запись «sa» непригодной для использования. Ошибок в бюллетенях безопасности нет. MS00-092, MS01-060, MS02-020 являются примерами. К сожалению, запрет пользователям доступа к расширенным процедурам не является гарантией полной безопасности. Вы должны дополнительно убедиться, что библиотеки OLEDB, доступные с уровня службы SQLServer, т.е. бюллетени безопасности MS02-040 лишены таких ошибок. Кроме того, функции MS02-007, MS02-038 и MS02-039 содержат внутренние ошибки. Самый безопасный способ — установить пакет обновления 3 [4] сразу после установки службы SQLServer. Я настоятельно рекомендую всем читателям, интересующимся безопасностью SQLServer, ознакомиться с полным списком бюллетеней по безопасности [5]. Кроме того, стоит зайти на замечательный веб-сайт www.sqlsecurity.com, на котором публикуется актуальная важная информация и советы по защите служб SQLServer.
Защитите свою базу данных!
К сожалению, это один из наиболее игнорируемых элементов многих коммерческих баз данных. Как я объяснял ранее, в каждой базе данных есть определенные группы. Помимо специальной общедоступной группы, db_datareader и db_datawriter также представляют особый интерес с точки зрения безопасности данных. Обе эти группы имеют встроенные права на вход, затем чтение и запись всех таблиц базы данных. Ни одной из специальных групп не разрешено выполнять все процедуры в базе данных. Также я должен напомнить вам, что пользователь dbo имеет полные права на все объекты (таблицы, процедуры, определения, целостность данных и т.д.) в базе данных. Все пользователи роли db_owner имеют те же права, что и пользователь 'dbo'. Причиной уязвимости данных для несанкционированного доступа обычно является неполная реализация базы данных. Программисты, которые готовят базу данных в своей среде, часто забывают спланировать ее защиту, а это значит, что при реализации базы планов по безопасности нет. Завершение реализации требует, чтобы такой план был создан быстро (что часто невозможно) или же предоставление всем пользователям полного доступа ко всем таблицам путем помещения их в группы db_datareader и db_datawriter с предоставлением им права выполнять все процедуры. В большинстве случаев это делается вручную или с помощью простого сценария, который извлекает имя каждой процедуры из системных таблиц и дает «общедоступной» группе разрешение на ее использование. Вы могли бы поместить всех пользователей в группу db_owner вместо выполнения такой сложной работы, но это фатальная ошибка в контексте безопасности данных. План защиты приложения должен быть создан во время создания приложения. Кстати, тогда следует использовать специфику системы безопасности SQL-сервера, поскольку она позволяет невероятно эффективно определять авторизации на уровне приложения. Некоторые объекты базы данных, такие как процедуры, функции и представления, могут использовать другие, например, представление может использовать таблицы, другое представление или функцию, тогда как процедура может использовать представления, функции, таблицы и другие процедуры. Пользователь, получивший доступ к процедуре, представлению или функции, может использовать их, даже если он не имеет доступа к объектам, используемым этой процедурой, при условии, что владелец процедуры, представления или функции одновременно является владельцем этих объекты. Это простой способ реализации условий, ограничивающих доступ к данным в объектах. Вы можете, например, создать представление «my_data», содержащее условие «WHERE UID = USER_ID() WITH CHECK OPTION», которое использует таблицу «personal_data». Ни один пользователь не имеет прямого доступа к «личным данным», поэтому им приходится использовать представление «my_data». Это представление имеет жестко фиксированное условие, чтобы отобразить доступными только те строки, которые соответствуют идентификатору пользователя. Это условие является примером реализации безопасности в приложении, чтобы пользователь не мог обойти его стороной. Аналогичная ситуация возникла бы, если бы пользователь «А» создал таблицу «ca», процедуру «pa» для манипулирования данными в таблице и если бы он передал права на процедуру «pa» пользователю «B». «В» может использовать данные, содержащиеся в таблице «ca», с использованием процедуры «pa». Эта ситуация поясняется на рисунке 4.
Впоследствии, если «B» создал процедуру «pb», которая использовала «pa», и предоставила «C» права на нее, «C» не было бы автоматически разрешено использовать данные из «ca». Это произойдет потому, что процедура «pb» будет использовать процедуру «pa», которая не принадлежит «B». По этой причине доступ пользователя «C» к «pa» будет проверен, и он сможет правильно выполнить процедуру «pb» только в том случае, если ему будет предоставлено разрешение на использование «pa», которое также используется «pb». '. Это называется «разорванной цепочкой владения». Вы можете увидеть это на рисунке 5.
Этот механизм позволяет программисту создавать обширные и эффективные методы ограничения доступа к данным. Однако все это имеет смысл только при одном условии: пользователи не должны быть назначены ни в группу db_datareader, ни даже в группы db_datawriter. В противном случае все меры предосторожности бесполезны, поскольку все пользователи будут иметь прямой доступ ко всем данным! Этот способ реализации мер защиты сложен, поскольку популярная процедура sp_executesql позволяет выполнять динамически созданную формулировку как команду SQL, используя полномочия пользователя, запустившего процедуру. Вернемся к примеру, приведенному ранее. Если «A» использовал «sp_executesql» при написании процедуры «pa» для управления данными в «ca», то «B» должен получить определенные разрешения на доступ к таблице «ca». В противном случае процедура 'pa' не будет запущена [6]. Этот механизм заставляет пользователей получать авторизацию для доступа к таблицам, даже если план безопасности приложения предполагает, что они не используют таблицы напрямую. Таким образом пользователи могут получить доступ к данным, минуя процедуры или функции. Наблюдается огромное падение безопасности данных.
На первый взгляд это кажется сложным. Однако три простых принципа позволят вам построить эффективный механизм защиты данных:
- Пользователи базы данных не должны иметь прямого доступа к таблицам
- Пользователи могут получать доступ к данным только с использованием функций, процедур или представлений.
- «dbo» является владельцем всех объектов в данных (чтобы избежать проблемы «разорванной цепочки владения»)
Два дополнительных принципа, касающихся групп пользователей, облегчают управление авторизацией внутри базы данных:
- Полномочия для представлений, процедур и функций предоставляются группам (или ролям) пользователей в зависимости от выполняемых ими задач и необходимого им уровня доступа к данным.
- Полномочия конкретных пользователей регулируются их членством в определенных группах или ролях.
Выбор некоторых принципов в начале процесса создания приложения позволит вам достичь высокого уровня безопасности данных, поэтому важно серьезно отнестись к этому. Вы бы никогда не достигли такого высокого уровня безопасности, если бы добавили средства защиты позже. Кроме того, такой процесс был бы очень дорогим из-за необходимых «накладных расходов» программирования, тестов и, возможно (или даже вероятно) осложнений.
В заключение могу я настоятельно порекомендовать всем тем, кто интересуется безопасностью SQL, прочитать документацию Microsoft, описывающую основные методы обеспечения безопасности SQL Server [7]. Очень интересные материалы по безопасности SQL публикуют NGSSoftware [8], SPI Dynamics [9] и, очевидно, журнал SQL Server [10].
Библиография:
[1] http://isc.incidents.org/port_report.html
[2] Что произойдет, если вы не отметите свои элементы управления?
[3] http://www.microsoft.com/technet/security/bulletin/MS02-034.asp, «Неправильное разрешение на ключ реестра учетной записи службы SQL Server».
[4] http://www.microsoft.com/sql/downloads/2000/sp3.asp
[5] http://www.microsoft.com/technet/security/current.asp?productid=30
[6] http://support.microsoft.com/default.aspx?scid=KB;EN-US;301299
[7] http://www.microsoft.com/sql/techinfo/administration/2000/security/securingsqlserver.asp [8] http://www.nextgenss.com/research.html#papers
[9] http://www.spidynamics.com/whitepapers.html
[10] http://www.windowsitpro.com/SQLServer/