АНДРЕЙ БИРЮКОВ
Windows Script Host: проводим аудит безопасности сети
Вам наверняка приходится тратить массу времени, чтобы найти в логах информацию о попытках несанкционированного доступа к ресурсам сети. Для автоматизации осуществления поиска информации о событиях аудита и построения отчетов предлагаем вам использовать сценарии Windows Script Host.
Вступительное слово
Думаю, любому из вас будет интересно узнать, кто, когда и с каких машин пытался зайти в сеть вашей компании, особенно это интересно в случаях, когда для доступа в сеть использовалась учетная запись с администраторскими правами. UNIX-системы для решения подобных задач обладают массой свободно распространяемых программ. Они позволяют администраторам, подкорректировав соответствующим образом исходный код сценария, производить аудит событий доступа к сети и получать отчет, содержащий все необходимые сведения об удачных и/или неудачных попутках проникновения в систему и получения доступа к различным ресурсам сети. С Windows все несколько сложнее, существующие решения, как правило, являются коммерческими и требуют от системных администраторов серьезной подготовки. Также в силу недоступности исходного кода их достаточно трудно, а зачастую и просто невозможно, изменять и дорабатывать для аудита своей сети.
Готовим сеть к аудиту
В Windows 2000/2003 по умолчанию аудит всех категорий безопасности отключен. Администратор создает политику аудита, определяя, для каких типов событий безопасности нужно выполнять аудит. Исходя из требований корпоративной политики безопасности своей организации, администратор может также задать аудит доступа к отдельным объектам.
Первым шагом в создании политики является определение событий, для которых должен выполняться аудит.
При этом доступны следующие категории событий:
- Account logon events (аутентификация пользователей на контроллерах домена) – если аудит успешных попыток входа в систему включен на контроллере домена, в журнал будет заноситься запись о каждом пользователе, прошедшем проверку на этом контроллере домена, несмотря на то что пользователь на самом деле входит в систему на рабочей станции домена.
- Account management (управление учетными записями) – аудит всех событий, связанных с управлением учетными записями на компьютере. К таким событиям относятся, в частности, следующие: создание, изменение или удаление учетной записи пользователя или группы; переименование, отключение или включение учетной записи пользователя; задание или изменение пароля.
- Directory service access (доступ к службе каталогов) – контроль событий доступа пользователя к объекту каталога Active Directory, для которого задана собственная системная таблица управления доступом.
- Logon events (события входа) – подлежит ли аудиту каждая попытка пользователя войти в систему или выйти из нее на данном компьютере, или подключиться к нему через сеть.
- Object access (доступ к объектам) – контроль событий доступа пользователя к объекту – например, к файлу, папке, разделу реестра, принтеру и т. п.
- Policy change (изменение политик) – осуществляется ли аудит изменений политик назначения прав пользователей, политик аудита или политик доверительных отношений.
- Privilege use (использование привилегий) – подлежит ли аудиту каждая попытка пользователя воспользоваться предоставленными ему правами.
- Process tracking (отслеживание процесса) – аудит таких событий, как активизация программы, завершение процесса, повторение дескрипторов и косвенный доступ к объекту.
- System events (системные события) – производится ли аудит событий перезагрузки или отключения компьютера, а также события, влияющие на системную безопасность или на журнал безопасности.
Чтобы выбрать категории событий для аудита, необходимо сначала определить, является ли данный сервер контроллером домена.
Если это рядовой сервер, то нужно выбрать «Administrative tools Local security policy Audit policy». Если аудит производится на контроллере домена, то нужно выбрать «Active Directory Users And Computers», затем открыть запись для данного домена, выбрать меню «Action Properties Group policy Edit», далее надо открыть «Computer Configuration Windows Settings Security Settings Local Policies», после чего выбрать «Audit Policy».
При любом методе в результате выбора Audit policy в правой панели появятся доступные для аудита категории событий. Для того чтобы модифицировать политику для какой-либо категории аудита, щелкните правой кнопкой на этом событии и выберите пункт «Security». Далее необходимо установить флажок для аудита успешных попыток входа в сеть и/или аудита безуспешных. В нашем случае необходимо выбрать «Audit Account Logon Events» и отметить «Success» и «Failure». В результате получаем окно, аналогичное изображенному на рис. 1.
Рисунок 1. Список политик аудита. Обведена «Account LogonEvents»
Таким образом, теперь в журнале событий «Event Log», в разделе «Security» при каждой попытке входа пользователя в систему будет появляться соответствующее сообщение (см. рис. 2).
Рисунок 2. Журнал событий. Выделены два сообщения: нижнее – неудачная попытка войти в систему и верхняя – удачный вход
Однако для решения нашей задачи использование журнала событий в качестве хранилища информации о попытках входа в сеть – не самый лучший выход. Причин тому несколько, прежде всего это ограниченность размера журнала событий, из-за которой часть сообщений рано или поздно будут удалены. С настройками по умолчанию журнал событий при достижении заданного ограничения на размер затирает старые сообщения новыми по принципу очереди (FIFO, First In First Out). При этом размер файла журнала Security по умолчанию равен 131072 Кб. Если за сутки в журнал заносится несколько тысяч сообщений, то 128 Мб это не слишком много. Можно также настроить, чтобы журнал затирал сообщения по прошествии определенного количествf дней или не затирал сообщения вообще [1]. Правда, в последнем случае, когда файл журнала достигнет ограничения по размеру, наш сервер может вообще прекратить функционировать, пока не будет произведена ручная очистка. Согласитесь, особенно неприятно, если это произойдет, скажем, в субботу ночью. Вторым недостатком использования журнала событий для задач аудита сети является то, что построение отчетов затруднено. Можно, конечно, делать выборку каждый день вручную с помощью стандартного фильтра Event Viewer, однако автоматизировать этот процесс с помощью VBScript будет крайне сложно и неудобно.
Таким образом, возникает необходимость в использовании базы данных для хранения сообщений о событиях.
Настраиваем хранилище сообщений аудита
Microsoft SQL Server 2000, или его бесплатная урезанная реализация MSDE, активно используются различными приложениями от 1С до систем резервного копирования и корпоративных антивирусов. Так что вполне логичным будет использование данной СУБД в качестве хранилища наших сообщений аудита. Сразу оговорюсь, что основы построения баз данных и SQL-запросов не являются темой статьи, эти аспекты будут снабжены лишь краткими комментариями. За более подробной информацией можете обратиться к источникам справочной информации [2, 3].
Наша база-хранилище сообщений будет иметь следующие поля:
- Событие (Event ID).
- Дата и время.
- Имя пользователя (доменпользователь, под которым осуществлялась попытка входа).
- Workstation (имя машины, с которой осуществлялась попытка входа, может быть пустым).
- IP-адрес (машина в локальной сети, с которой осуществлялась попытка входа).
Создадим в MS SQL Server базу Audit, а в ней таблицу Logons, эти действия можно осуществить, например, с помощью Query Analyzer [3], выполнив следующий SQL-скрипт.
Листинг 1. SQL-скрипт для создания таблицы Logons
CREATE TABLE [dbo].[Logons] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[Event_vch] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
[Date_dat] [datetime] NULL ,
[User_vch] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
[WID_vch] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
[Address_vch] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL
) ON [PRIMARY]
GO
Итак, создали базу, в которой будет храниться информация о попытках входа в систему. Думаю, не стоит напоминать, что необходимо подумать о защите данной базы, так как в случае обнаружения и расследования несанкционированного проникновения в систему информация из базы может оказать неоценимую помощь администратору.
Теперь приступим к написанию сценария, который будет осуществлять выборку сообщений из журнала событий и сохранение их в базу.
Кто пришел, когда пришел, откуда пришел…
Прежде всего подробно опишу структуру WSH-сценария, для того чтобы при необходимости вы легко могли приспособить его для решения своих задач, например, аудита доступа к объектам или аудита изменения политик.
Итак, первым делом нам необходимо узнать, какую дату и время имеет последняя запись в базе данных. Это нужно для того, чтобы не копировать одно и то же по нескольку раз. Это можно сделать с помощью следующего запроса:
SELECT Max(Date_dat) AS Last FROM Logons
Данный запрос возвратит дату последней записи. Таким образом, мы определили, после какого времени нужно сохранять в базе поступившие сообщения. Очевидно при первом запуске сценария данный запрос возвратит пустую строку и нам придется копировать все сообщения.
Скорее всего в журнале событий «Security», кроме событий аудита «Account Logon Events», могут оказаться еще какие-то сообщения о других событиях в системе. В связи с этим нам необходимо отфильтровывать нужные сообщения (см. рис. 3).
Рисунок 3. Сообщение об удачном входе в систему
События, которые нас интересуют, имеют следующие Event ID:
- 673 – Удачная попытка входа в систему.
- 675 – Неудачная попытка входа в систему.
- 538 – Выход из системы (Logoff).
Листинг 2. Функция substring для поиска вхождений искомой строки
Function SubString(Str1)
strpos1=InStr(1,Str,str1)
strtemp=Right(Str, Len(str)-strpos1-Len(str1))
strpos2=InStr(1,Strtemp,Chr(10))
SubString=trim(Left(strtemp,strpos2))
End Function
Следует отметить, что данная функция универсальная и ее можно использовать для поиска вхождений при написании своих сценариев, главное – соблюдать формат, применяемый для поиска.
Еще одним важным моментом является формат даты и времени, используемые при сохранении сообщений в базе. Я не случайно использовал одно поле для хранения в базе даты и времени, несмотря на то что в журнале событий задействованы два поля. Если у нас поле типа datetime содержит дату и время, то к значениям этого поля можно применять математические функции, в частности мы уже использовали Max, а также <, = , > которые нам еще потребуются в дальнейшем. Если бы мы использовали отдельные поля для даты и времени, то математические функции применять было бы гораздо сложнее. Однако тут возникает еще одна сложность: для полей типа datetime необходимо передавать данные строго в определенном формате «мм.дд.гггг чч:мм:сс». При этом надо использовать функцию SQL CONVERT. В результате работы этой функции с определенными параметрами (110 – для даты и 114 – для времени) мы получаем корректно сохраненную дату в базе. Подробнее о команде CONVERT и кодах, используемых для форматирования дат, читайте в [2].
Итак, мы завершили разбор сообщений журнала событий, и теперь остается только сохранить полученную информацию в базе. Далее приводится полный текст сценария, который осуществляет сбор и сохранение данных в базу.
Листинг 3. Сценарий для поиска и сохранения искомых сообщений в базе данных
Dim Cnxn, strCnxn
Dim rsCustomers, strSQLCustomers
Dim EventDate, EventTime, EventTmp
Dim objWMI, objItem ' Objects
Dim strComputer
Dim intEvent,intRec, colLoggedEvents
Dim Str, strtemp
Function SubString(Str1)
strpos1=InStr(1,Str,str1)
strtemp=Left(Right(Str, strpos1+2), Len(str1))
strpos2=InStr(1,Strtemp,Chr(10))
SubString=Left(strtemp,strpos2)
End Function
strComputer="127.0.0.1"
Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colLoggedEvents = objWMI.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile = 'Security'" )
Set Cnxn = wscript.CreateObject("ADODB.Connection")
strCnxn = "Provider='sqloledb';Data Source=" & _
"127.0.0.1;" & _
"Server=MyServer;Database=Audit;Trusted_Connection=yes"
// устанавливаем соединение с SQL-сервером
Cnxn.Open strCnxn
LastRec=""
Line=" SELECT Max(Date_dat) AS Last FROM Logons"
Set rs=Cnxn.execute(Line)
'wscript.echo rs("Last")
If not(rs.eof) Then LastRec=Left(rs("Last"),19)
// находим дату последней записи
rs.close
last=0
intRec=0
For Each objItem in colLoggedEvents
EventTmp=Mid(objItem.TimeWritten, 7,2)+"."+Mid(objItem.TimeWritten, 5, 2)+"."+Mid(objItem.TimeWritten, 1,4)+" "+Mid(objItem.TimeWritten, 9,2)+":"+Mid(objItem.TimeWritten, 11, 2)+":"+Mid(objItem.TimeWritten, 13,2)
// время каждого события
If (EventTmp=LastRec) Then Last=1
// сравниваем
If Last=0 Then
// пока даты не равны, ищем соответствующие события
If objItem.eventCode=675 Then
str=objItem.message
IpAddr=substring("Client Address:")
UserName=substring("User Name:")
UserID=substring("User ID:")
EventDate=Mid(objItem.TimeWritten,5,2)+"."+Mid(objItem.TimeWritten, 7, 2)+"."+Mid(objItem.TimeWritten, 1,4)
EventTime=Mid(objItem.TimeWritten,9,2)+":"+Mid(objItem.TimeWritten,11,2)+":"+Mid(objItem.TimeWritten, 13,2)
Str=objItem.message
Line=” INSERT INTO dbo.Logons ( Event_vch, Date_dat, User_vch, WID_vch, Address_vch)VALUES ( '675', CONVERT(DATETIME, '"+EventDate+"', 110)+ CONVERT(DATETIME, '"+EventTime+"', 114), '"+UserName+"','"+UserID+"','"+IpAddr+"')"
Set rs=Cnxn.execute(Line)
End if
If objItem.eventCode=673 Then
str=objItem.message
IpAddr=substring("Client Address:")
UserName=substring("User Name:")
UserID=substring("Service Name:")
EventDate=Mid(objItem.TimeWritten, 5,2)+"."+Mid(objItem.TimeWritten, 7, 2)+"."+Mid(objItem.TimeWritten, 1,4)
EventTime=Mid(objItem.TimeWritten, 9,2)+":"+Mid(objItem.TimeWritten, 11, 2)+":"+Mid(objItem.TimeWritten, 13,2)
Str=objItem.message
Line=" INSERT INTO dbo.Logons ( Event_vch, Date_dat, User_vch, WID_vch, Address_vch) VALUES ( '673', CONVERT(DATETIME, '"+EventDate+"', 110)+CONVERT(DATETIME, '"+EventTime+"', 114), '"+UserName+"', '"+UserID+"','"+IpAddr+"')"
Set rs=Cnxn.execute(Line)
End if
If objItem.eventCode=538 Then
str=objItem.message
IpAddr=substring("User Name:")
EventDate=Mid(objItem.TimeWritten, 5,2)+"."+Mid(objItem.TimeWritten, 7, 2)+"."+Mid(objItem.TimeWritten, 1,4)
EventTime=Mid(objItem.TimeWritten, 9,2)+":"+Mid(objItem.TimeWritten, 11, 2)+":"+Mid(objItem.TimeWritten, 13,2)
Str=objItem.message
Line=" INSERT INTO dbo.Logons ( Event_vch, Date_dat, User_vch, WID_vch, Address_vch) VALUES ( '538', CONVERT(DATETIME, '"+EventDate+"', 110)+CONVERT(DATETIME, '"+EventTime+"', 114), '"+UserName+"','','')"
Set rs=Cnxn.execute(Line)
End if
End If
intrec=intRec+1
Next
cnxn.close
Этот сценарий нужно запускать с частотой как минимум один раз в сутки, чтобы журнал событий не переполнился и соответственно записи не начали затирать друг друга.
Отчетность прежде всего
Сценарий написан, информация о попытках доступа в сеть исправно заносится в нашу базу, теперь самое время начать получать подробные отчеты о том, кто, когда и откуда пытался получить доступ в нашу сеть.
Наш отчет будет сохраняться в формате HTML и открываться с помощью браузера. Сценарий очень похож на предыдущий, и расписывать его подробно, думаю, необязательно.
Листинг 4. Сценарий для построения отчетов
strComputer="127.0.0.1"
Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colLoggedEvents = objWMI.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile = 'Security'")
Set objFso = CreateObject("Scripting.FileSystemObject")
' open connection
Set Cnxn = wscript.CreateObject("ADODB.Connection")
strCnxn = "Provider='sqloledb';Data Source=" & _
"127.0.0.1;" & _
"Server=MyServer;Database=Audit;Trusted_Connection=yes"
Cnxn.Open strCnxn
Set strFile = objFso.CreateTextFile("c:\report.htm", True)
strFile.WriteLine("<html><title>Аудит системы</title><body>")
strFile.WriteLine("<center><b>Отчет от "& Date &"</b><table><tbody><tr><td>Имя пользователя</td><td>Время события</td><td>Событие</td><td>UserID</td><td>IP адрес</td></tr>")
DateNow=
Line=" SELECT DISTINCT(User_vch) FROM Logons"
Set rs1=Cnxn.execute(Line)
Do While not(rs1.eof)
Line=" SELECT * FROM Logons WHERE (Date_dat > CONVERT(DATETIME, '" & Date &" 00:00:00', 102)) AND (Date_dat < CONVERT(DATETIME, '" & Date & " 23:59:59', 102)) AND (User_vch = '"+rs1("User_vch")+"')"
Set rs2=Cnxn.execute(Line)
strFile.WriteLine("<TR>")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2("User_vch"))
strFile.WriteLine("</td> ")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2("Date_dat"))
strFile.WriteLine("</td> ")
strFile.WriteLine("<td> ")
If (rs2(“Event_vch”)="673") Then strFile.WriteLine("<FONT COLOR=red>Неудачная попытка входа</FONT>")
If (rs2("Event_vch”)="675") Then strFile.WriteLine("<FONT COLOR=green>Удачный вход</FONT>")
If (rs2("Event_vch")="538") Then strFile.WriteLine("<FONT COLOR=navy>Выход из системы</FONT>")
strFile.WriteLine("</td> ")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2("WID_vch"))
strFile.WriteLine("</td> ")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2("Address_vch"))
strFile.WriteLine("</td> ")
strFile.WriteLine("</TR>")
rs2.close
rs1.MoveNext
loop
strFile.WriteLine("</tbody></table></center></html>")
rs1.close
Cnxn.close
Set WshShell = CreateObject("WScript.Shell")
Return = WshShell.Run("iexplore.exe c:\report.htm", 1)
Данный сценарий выводит информацию о попытках войти в сеть, которые были произведены в течение текущих суток. При этом сначала осуществляется выборка по всем пользователям, которые «засветились» в журнале событий, затем делается запрос для каждого пользователя. Вывод осуществляется в html-файл. По окончании созданный файл автоматически открывается в браузере. Если данный сценарий запускается автоматически по расписанию, то открывать браузер с отчетом не нужно, и две последние строки из исходного текста можно удалить. Сообщения о неудачных попытках входа в сеть выводятся красным цветом, удачные – зеленым, а выходы из системы – темно-синим. Сообщения будут выводиться в том порядке, в каком они попали в базу, однако SQL-запросы можно переписать, например, для вывода сообщений парами вход-выход. О том, как это сделать, речь пойдет далее.
Итак, мы получили два сценария, один из которых осуществляет выборку нужных данных из журнала событий, а второй выполняет запрос, с помощью которого мы получаем информацию о попытках входа в сеть за определенный период. Оба сценария можно последовательно выполнять в конце каждых суток, а полученные результаты выкладывать на внутренний веб-сервер, в соответствующую папку. Тогда сисадмин сети каждое утро, приходя на работу, будет получать отчет о попытках доступа к ресурсам сети за предыдущие сутки.
Задача аудита попыток доступа в сеть и построения удобочитаемых отчетов для системного администратора нами успешно решена. Однако будет нелишним рассмотреть еще одну возможность для применения сценариев WSH и политик аудита Account Logon Events – это построение системы учета рабочего времени. Решение данной задачи часто взваливают на плечи системных администраторов, особенно в небольших компаниях. Если в вашей организации используется домен Active Directory, то каждый день, приходя на свое рабочее место, пользователи должны аутентифицироваться в домене, введя свой логин и пароль (в нашей системе аудита это событие 675 Удачный вход в систему). А в конце рабочего дня пользователи должны корректно завершить работу системы (событие 538 Logoff). Таким образом, для получения информации о времени прихода сотрудника на работу нам необходимо получить самое раннее время события 675, а для получения времени ухода – самое позднее время события 538. Сделать это можно с помощью следующего громоздкого с виду запроса. Тут следует сразу оговориться: в данном случае мы предполагаем, что в нашей сети круглосуточно работают сервера и все задачи, требующие продолжительных расчетов, выполняются только на них, а рабочие станции включают сотрудники, приходя на работу.
Листинг 5. Запрос, возвращающий самый ранний logon и самый поздний logoff
SELECT MAX(Date_dat) AS Last, MIN(Date_dat) AS First, User_vch FROM Logons WHERE (Date_dat > CONVERT(DATETIME, '2005-11-01 00:00:00', 102)) AND (Date_dat < CONVERT(DATETIME, '2005-11-01 23:59:59', 102)) AND (User_vch = '"+rs1("User_vch")+"') AND ((Event_vch='675') OR (Event_vch='538')) GROUP BY User_vch
Данный запрос возвратит два значения first и last, соответствующие времени входа в систему и времени выхода из нее.
Листинг 6.Сценарий построения отчета для контроля рабочего времени
strComputer="127.0.0.1"
Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colLoggedEvents = objWMI.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile = 'Security'")
Set objFso = CreateObject("Scripting.FileSystemObject")
Set Cnxn = wscript.CreateObject("ADODB.Connection")
strCnxn = "Provider=’sqloledb’;Data Source=" & _
"127.0.0.1;" & _
"Server=MyServer;Database=Audit;Trusted_Connection=yes"
Cnxn.Open strCnxn
Set strFile = objFso.CreateTextFile("c:\report.htm", True)
strFile.WriteLine("<html><title>Учет времени</title><body>")
strFile.WriteLine("<center><b>Отчет</b><table><tbody><tr><td>Имя пользователя</td><td>Время прихода</td><td>Время ухода</td></tr>")
Line=" SELECT DISTINCT(User_vch) FROM Logons"
// извлекаем имена пользователей
Set rs1=Cnxn.execute(Line)
Do While not(rs1.eof)
For i=1 to 30 // Цикл по количеству дней в месяце
Line=" SELECT MAX(Date_dat) AS Last, MIN(Date_dat) AS First, User_vch FROM Logons WHERE (Date_dat > CONVERT(DATETIME, '2005-11-"& i &" 00:00:00', 102)) AND (Date_dat < CONVERT(DATETIME, '2005-11-""& i &" 23:59:59', 102)) AND (User_vch = ‘'"+rs1 ("User_vch")+"') AND ((Event_vch='675') OR (Event_vch='538')) GROUP BY User_vch"
Set rs2=Cnxn.execute(Line)
If not(rs2.eof) Then
strFile.WriteLine("<TR>")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2("User_vch"))
strFile.WriteLine("</td> ")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2("First"))
strFile.WriteLine("</td> ")
strFile.WriteLine("<td> ")
strFile.WriteLine(rs2(«Last»))
strFile.WriteLine("</td> ")
strFile.WriteLine("</TR>")
End If
rs2.close
Next
rs1.MoveNext
loop
strFile.WriteLine("</tbody></table></center></html>")
rs1.close
Set WshShell = CreateObject("WScript.Shell")
Return = WshShell.Run("iexplore.exe c:\report.htm", 1)
Cnxn.close
В результате работы данного WSH-сценария будет получаться HTML-документ, в котором для каждого пользователя будут по дням расписаны дата и время входа в сеть и выхода из нее, то есть фактически время прихода и ухода на работу.
Надеюсь, материал, изложенный в этой статье, пригодится системным администраторам и поможет им сэкономить рабочее время, затрачиваемое на поиск событий, угрожающих безопасности вверенной им сети.
Литература:
- Windows Server 2003. Справочник администратора.
- Microsoft SQL Server Books Online.
- Администрирование Microsoft SQL Server 2000. Сертификационный экзамен 70-228.