LDAP 01
Trong ví dụ đầu tiên này, bạn kết nối với máy chủ LDAP, sử dụng tên người dùng và mật khẩu của mình. Trong trường hợp này, Máy chủ LDAP không xác thực bạn, vì bằng chứng xác thực của bạn không hợp lệ.
Tuy nhiên, một số máy chủ LDAP cho phép NULL Bind: nếu giá trị null được gửi, máy chủ LDAP sẽ tiến hành ràng buộc kết nối và mã PHP sẽ nghĩ rằng thông tin xác thực là chính xác. Để nhận ràng buộc có 2 giá trị null, bạn sẽ cần phải xóa hoàn toàn tham số này khỏi truy vấn. Nếu bạn giữ một cái gì đó như tên username=&password= trong URL, các giá trị này sẽ không hoạt động, vì chúng sẽ không có giá trị; thay vào đó, chúng sẽ trống rỗng. Do đó bạn phải xoá hết đi.
LDAP 02
Hình thức injection LDAP phổ biến nhất là có thể injection trong một bộ lọc. Ở đây, chúng ta sẽ thấy cách bạn có thể sử dụng LDAP injection để bỏ qua kiểm tra xác thực.
Đầu tiên, bạn cần tìm hiểu một chút về cú pháp LDAP. Khi bạn đang truy xuất một người dùng, dựa trên tên người dùng của người đó, những điều sau sẽ được sử dụng:
1 |
(cn=[INPUT]) |
Nếu bạn muốn thêm nhiều điều kiện hơn và một số logic boolean, bạn có thể sử dụng:
- Một boolean OR sử dụng |: (|(cn=[INPUT1])(cn=[INPUT2])) để lấy các bản ghi trùng với [INPUT1] or [INPUT2].
- Một boolean AND sử dụng &: (&(cn=[INPUT1])(userPassword=[INPUT2])) lấy bản ghi có cn bằng [INPUT1] mật khẩu trùng với [INPUT2].
Như bạn có thể thấy, logic boolean nằm ở đầu bộ lọc. Vì bạn có khả năng chèn sau nó, không phải lúc nào cũng có thể (tùy thuộc vào máy chủ LDAP) để đưa logic vào bên trong bộ lọc, nếu nó chỉ là (cn=[INPUT]).
LDAP rất thường xuyên sử dụng ký tự đại diện * để khớp với bất kỳ giá trị nào. Điều này có thể được sử dụng để so khớp mọi thứ * hoặc chỉ các chuỗi con (ví dụ: adm* cho tất cả các từ bắt đầu bằng adm).
Như với các lần injection khác, chúng tôi sẽ cần xóa bất kỳ thứ gì được thêm bởi mã phía máy chủ. Chúng tôi có thể loại bỏ phần cuối của bộ lọc, sử dụng NULL BYTE (được mã hóa là %00).
Ở đây, chúng tôi có một kịch bản đăng nhập. Chúng ta có thể thấy điều đó nếu chúng ta sử dụng:
- username=hacker&password=hacker và chúng ta được xác thực (đây là một request bình thường).
- username=hack*&password=hacker và chúng ta được xác thực (wildcard matches the same value).
- username=hacker&password=hac* chúng ta không được xác thức (mật khẩu có thể đã bị hashed).
Bây giờ, chúng ta sẽ xem cách chúng ta có thể sử dụng LDAP injection, trong tham số tên người dùng để bỏ qua xác thực. Dựa trên các thử nghiệm trước đây của chúng tôi, chúng tôi có thể suy ra rằng bộ lọc có thể trông giống như sau:
1 |
(&(cn=[INPUT1])(userPassword=HASH[INPUT2])) |
Trong đó HASH là một hàm băm unsalted (có thể là MD5 hoặc SHA1).