Hướng dẫn php login injection - tiêm đăng nhập php

Nhiều nhà phát triển web không biết làm thế nào các truy vấn SQL có thể bị giả mạo và cho rằng truy vấn SQL là một lệnh đáng tin cậy. Điều đó có nghĩa là các truy vấn SQL có thể phá vỡ các điều khiển truy cập, do đó bỏ qua kiểm tra xác thực và ủy quyền tiêu chuẩn và đôi khi các truy vấn SQL thậm chí có thể cho phép truy cập vào các lệnh cấp hệ điều hành máy chủ.

Tiêm lệnh SQL trực tiếp là một kỹ thuật mà kẻ tấn công tạo hoặc thay đổi các lệnh SQL hiện có để hiển thị dữ liệu ẩn hoặc ghi đè các lệnh có giá trị hoặc thậm chí để thực hiện các lệnh cấp hệ thống nguy hiểm trên máy chủ cơ sở dữ liệu. Điều này được thực hiện bằng ứng dụng lấy đầu vào của người dùng và kết hợp nó với các tham số tĩnh để xây dựng truy vấn SQL. Các ví dụ sau đây dựa trên những câu chuyện có thật, thật không may.

Do thiếu xác thực đầu vào và kết nối với cơ sở dữ liệu thay mặt cho một siêu người dùng hoặc người có thể tạo người dùng, kẻ tấn công có thể tạo một siêu người dùng trong cơ sở dữ liệu của bạn.

Ví dụ #1 chia kết quả được đặt thành các trang ... và tạo siêu người dùng (PostgreSQL)

$offset

$argv[0]; // beware, no input validation!
$query  "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result pg_query($conn$query);?>

Người dùng bình thường Nhấp vào các liên kết 'tiếp theo', 'trước' trong đó $ offset được mã hóa vào URL. Kịch bản hy vọng rằng bù $ đến là một số thập phân. Tuy nhiên, điều gì sẽ xảy ra nếu ai đó cố gắng đột nhập bằng cách nối thêm một dạng urlencode () 'urlencode()'d form of the following to the URL

0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
    select 'crack', usesysid, 't','t','crack'
    from pg_shadow where usename='postgres';
--

Nếu nó xảy ra, thì kịch bản sẽ trình bày một siêu người dùng truy cập vào anh ta. Lưu ý rằng 0; là cung cấp một phần bù hợp lệ cho truy vấn ban đầu và chấm dứt nó.

Ghi chú::

Đó là kỹ thuật phổ biến để buộc trình phân tích cú pháp SQL bỏ qua phần còn lại của truy vấn được viết bởi nhà phát triển với --, đó là dấu hiệu nhận xét trong SQL.

Một cách khả thi để có được mật khẩu là phá vỡ các trang kết quả tìm kiếm của bạn. Điều duy nhất mà kẻ tấn công cần làm là xem liệu có bất kỳ biến được gửi nào được sử dụng trong các câu lệnh SQL không được xử lý đúng cách không. Các bộ lọc này có thể được đặt phổ biến ở dạng trước để tùy chỉnh các điều khoản WHERE, ORDER BY, LIMITOFFSET trong các câu lệnh SELECT. Nếu cơ sở dữ liệu của bạn hỗ trợ cấu trúc

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
0, kẻ tấn công có thể cố gắng nối toàn bộ truy vấn vào bản gốc để liệt kê mật khẩu từ một bảng tùy ý. Sử dụng các trường mật khẩu được mã hóa được khuyến khích mạnh mẽ.

Ví dụ #2 Liệt kê các bài viết ... và một số mật khẩu (bất kỳ máy chủ cơ sở dữ liệu nào)

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
2

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
3

Phần tĩnh của truy vấn có thể được kết hợp với một câu lệnh SELECT khác cho thấy tất cả các mật khẩu:

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--

Nếu truy vấn này (chơi với

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
5 và --) được gán cho một trong các biến được sử dụng trong $ truy vấn, Truy vấn Beast Awakened.

Cập nhật SQL cũng dễ bị tấn công. Các truy vấn này cũng bị đe dọa bằng cách cắt và nối một truy vấn hoàn toàn mới cho nó. Nhưng kẻ tấn công có thể fiddle với mệnh đề

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
7. Trong trường hợp này, một số thông tin lược đồ phải được sở hữu để thao túng truy vấn thành công. Điều này có thể có được bằng cách kiểm tra các tên biến biểu mẫu, hoặc chỉ đơn giản là cưỡng bức. Không có quá nhiều quy ước đặt tên cho các trường lưu trữ mật khẩu hoặc tên người dùng.

Ví dụ #3 từ việc đặt lại mật khẩu ... để đạt được nhiều đặc quyền hơn (bất kỳ máy chủ cơ sở dữ liệu nào)

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
8

Nhưng nếu người dùng độc hại gửi giá trị

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
9 thành $ uid để thay đổi mật khẩu của quản trị viên hoặc chỉ cần đặt $ pwd thành 0 để đạt được nhiều đặc quyền hơn, thì truy vấn sẽ bị xoắn:

1

Một ví dụ đáng sợ về cách các lệnh cấp hệ điều hành có thể được truy cập trên một số máy chủ cơ sở dữ liệu.

Ví dụ #4 Tấn công hệ điều hành của cơ sở dữ liệu (Máy chủ MSSQL)

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
2

4

Nếu kẻ tấn công gửi giá trị 5 đến $ prod, thì truy vấn $ sẽ là:

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
2

8

Máy chủ MSSQL thực thi các câu lệnh SQL trong lô bao gồm một lệnh để thêm người dùng mới vào cơ sở dữ liệu tài khoản cục bộ. Nếu ứng dụng này đang chạy dưới dạng 9 và dịch vụ MSSQLServer đang chạy với đủ các đặc quyền, thì kẻ tấn công giờ đây sẽ có một tài khoản để truy cập vào máy này.

Ghi chú::

Đó là kỹ thuật phổ biến để buộc trình phân tích cú pháp SQL bỏ qua phần còn lại của truy vấn được viết bởi nhà phát triển với --, đó là dấu hiệu nhận xét trong SQL.

Một cách khả thi để có được mật khẩu là phá vỡ các trang kết quả tìm kiếm của bạn. Điều duy nhất mà kẻ tấn công cần làm là xem liệu có bất kỳ biến được gửi nào được sử dụng trong các câu lệnh SQL không được xử lý đúng cách không. Các bộ lọc này có thể được đặt phổ biến ở dạng trước để tùy chỉnh các điều khoản WHERE, ORDER BY, LIMITOFFSET trong các câu lệnh SELECT. Nếu cơ sở dữ liệu của bạn hỗ trợ cấu trúc

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
0, kẻ tấn công có thể cố gắng nối toàn bộ truy vấn vào bản gốc để liệt kê mật khẩu từ một bảng tùy ý. Sử dụng các trường mật khẩu được mã hóa được khuyến khích mạnh mẽ.

Ví dụ #2 Liệt kê các bài viết ... và một số mật khẩu (bất kỳ máy chủ cơ sở dữ liệu nào)

Phần tĩnh của truy vấn có thể được kết hợp với một câu lệnh SELECT khác cho thấy tất cả các mật khẩu:

Các cuộc tấn công này chủ yếu dựa trên việc khai thác mã không được viết với bảo mật. Không bao giờ tin tưởng bất kỳ loại đầu vào nào, đặc biệt là những thứ xuất phát từ phía máy khách, mặc dù nó đến từ một hộp chọn, trường đầu vào ẩn hoặc cookie. Ví dụ đầu tiên cho thấy rằng một truy vấn vô tình như vậy có thể gây ra thảm họa.

  • Không bao giờ kết nối với cơ sở dữ liệu với tư cách là Superuser hoặc là chủ sở hữu cơ sở dữ liệu. Sử dụng người dùng luôn luôn tùy chỉnh với các đặc quyền rất hạn chế.
  • Sử dụng các câu lệnh được chuẩn bị với các biến ràng buộc. Chúng được cung cấp bởi PDO, bởi MySQLI và các thư viện khác.
  • Kiểm tra xem đầu vào đã cho có kiểu dữ liệu dự kiến. PHP có một loạt các hàm xác thực đầu vào, từ các chức năng đơn giản nhất được tìm thấy trong các hàm thay đổi và trong các hàm loại ký tự (ví dụ: is_numeric (), ctype_digit () tương ứng) và trở đi đến hỗ trợ biểu thức thông thường tương thích perl.is_numeric(), ctype_digit() respectively) and onwards to the Perl compatible Regular Expressions support.
  • Nếu ứng dụng chờ đầu vào số, hãy xem xét xác minh dữ liệu bằng ctype_digit () hoặc im lặng thay đổi loại của nó bằng cách sử dụng settype () hoặc sử dụng biểu diễn số của nó bằng Sprintf ().ctype_digit(), or silently change its type using settype(), or use its numeric representation by sprintf().

    Ví dụ #5 Một cách an toàn hơn để soạn thảo truy vấn để phân trang

    $offset1

    $offset2

  • Nếu lớp cơ sở dữ liệu không hỗ trợ các biến ràng buộc thì hãy trích dẫn mỗi giá trị không được cung cấp của người dùng số người dùng được truyền vào cơ sở dữ liệu với hàm thoát chuỗi cụ thể cơ sở dữ liệu (ví dụ: mysql_real_escape_string (), sqlite_escape_string (). Các hàm chung như AddSlashes () chỉ hữu ích trong một môi trường rất cụ thể (ví dụ: MySQL trong một bộ ký tự một byte với NO_Backslash_escapes bị vô hiệu hóa) để tốt hơn để tránh chúng.mysql_real_escape_string(), sqlite_escape_string(), etc.). Generic functions like addslashes() are useful only in a very specific environment (e.g. MySQL in a single-byte character set with disabled NO_BACKSLASH_ESCAPES) so it is better to avoid them.
  • Không in ra bất kỳ thông tin cụ thể cơ sở dữ liệu nào, đặc biệt là về lược đồ, bằng phương tiện công bằng hoặc phạm lỗi. Xem thêm Báo cáo lỗi và xử lý lỗi và ghi nhật ký chức năng.
  • Bạn có thể sử dụng các quy trình được lưu trữ và con trỏ được xác định trước đây để truy cập dữ liệu trừu tượng để người dùng không truy cập trực tiếp các bảng hoặc chế độ xem, nhưng giải pháp này có một tác động khác.

Bên cạnh đó, bạn được hưởng lợi từ các truy vấn ghi nhật ký trong tập lệnh của bạn hoặc chính cơ sở dữ liệu, nếu nó hỗ trợ ghi nhật ký. Rõ ràng, việc khai thác không thể ngăn chặn bất kỳ nỗ lực có hại nào, nhưng nó có thể hữu ích để truy tìm lại ứng dụng nào đã bị phá vỡ. Nhật ký không hữu ích, nhưng thông qua thông tin nó chứa. Chi tiết hơn thường tốt hơn ít hơn.