Làm thế nào để tiếp cận hiệu quả Pentest trong kiểm thử bảo mật ứng dụng Web (Phần I)
Như chúng ta thấy yêu cầu đối với một tester càng ngày càng cao, bên cạnh việc kiểm thử chức năng dưới vai trò người dùng đầu cuối, nhiều dự án đã và đang đòi hỏi các tester cần nhiều kỹ hơn test chuyên sâu vào các vấn đề phức tạp hơn như kiểm thử bảo mật, dữ liệu, ..... Một trong những chủ đề kiểm ...
Như chúng ta thấy yêu cầu đối với một tester càng ngày càng cao, bên cạnh việc kiểm thử chức năng dưới vai trò người dùng đầu cuối, nhiều dự án đã và đang đòi hỏi các tester cần nhiều kỹ hơn test chuyên sâu vào các vấn đề phức tạp hơn như kiểm thử bảo mật, dữ liệu, ..... Một trong những chủ đề kiểm thử không còn xa lạ nhưng luôn khiến một kiểm thử viên, thậm chí các lập trình viên khá e ngại đó chính là Penetration Testing. Sau khi đọc rất nhiều tài liệu về Penetration Testing, mình nhận thấy đây là một chuyên đề khá thú vị nhưng rất rộng và dễ bị "loạn" nên muốn tìm cách tổng hợp các vấn đề cần khai thác và chọn lọc các bài tiếng anh về chủ đề này để dịch ra theo cách hiểu của mình sao cho kiểm thử viên có thể tiếp cận nhanh nhất và sâu dần theo từng chủ đề nhỏ để có thể khi cần sẽ ứng dụng vào dự án của mình phù hợp nhất.
Có 2 khái niệm mình nghĩ mọi người cần nắm bắt khi tiếp cận Penetration testing chính là:
Penetration testing là gì? Penetration testing hay còn gọi là Pentest là quá trình kiểm thử bảo mật cho các ứng dụng web bằng cách giả lập các cuộc tấn công vào website để tìm kiếm và phát hiện các lỗ hổng, các vấn đề bảo mật trong trang web. Kiểm thử viên sẽ đóng vai trò là các hacker và giả lập các tấn công vào các trang web mục tiêu.
OWASP là gì? OWASP là chuẩn phục vụ cho việc kiểm thử của Pentester do tổ chức phi lợi nhuận Open Web Application Security Project đưa ra nhằm phục vụ cho công việc pentest hiệu quả và chi tiết, liệt kê các công việc mà người kiểm thử nên làm và các checklist để thực hiện các công việc. Theo [thống kê 2017 của OWASP | https://www.owasp.org/index.php/Top_10_2007-Injection_Flaws] , Top 10 lỗi nguy hiểm về bảo mật ứng dụng web, bao gồm:
- Injection
- Broken Authentication and Session Management
- Cross-Site Scripting (XSS)
- Broken Access Control (As it was in 2004)
- Security Misconfiguration
- Sensitive Data Exposure
- Insufficient Attack Protection (NEW)
- Cross-Site Request Forgery (CSRF)
- Using Components with Known Vulnerabilities
- Underprotected APIs (NEW)
Dựa theo danh sách này, chuỗi bài viết của mình sẽ đi sâu vào từng lỗi nguy hiểm về bảo mật ứng dụng web và sau đó là các tool chúng ta có thể tận dụng để tối ưu hóa việc kiểm thử này. Phần I của chuỗi bài viết này sẽ dựa vào https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005) để dịch ra những phần về kiến thức chung cần có, giới thiệu kỹ thuật truy lỗi cũng như các kỹ thuật SQL Injection chuẩn.
Thiết kế một trang web luôn đòi hỏi các lập trình viên phải xem xét các vấn đề an toàn nhằm giảm thiểu tối đa các lỗ hỏng có khả năng bị tấn công bởi hacker. Một trong những nguy cơ tiềm ẩn mà các hacker thường chú ý chính là các đoạn mã của ứng dụng và họ thường lợi dụng lỗ hỏng này để chèn vào các câu lệnh truy vấn SQL nhằm xâm nhập cơ sở dữ liệu của các ứng dụng web. Tấn công bằng kỹ thuật chèn SQL có thể đọc được các dữ liệu nhạy cảm từ CSDL, chỉnh sữa dữ liệu (chèn thêm/thay đổi hay xóa đi), thực hiện các quyền admin trên cơ sở dữ liệu như tắt đi DBMS, khôi phục nội dung một file nào đó trên hệ thống file DBMS hay viết thêm các file vào hệ thống tập tin, thậm chí trong vài trường hợp các hacker còn xuất ra các lệnh vào hệ điều hành. Vì thế với các ứng dụng web có CSDL được quản lý bằng SQL Server, Oracle, BD2, hay Sysbase, thì kiểm thử SQL Injection rất quan trọng.
Thông tin chung về SQL Injection
Cụ thể hơn, ta có thể hiểu rằng các ứng dụng web dựng nên các câu truy vấn SQL liên quan đến cú pháp SQL mà các lập trình viên viết ra sẽ được kết hợp cùng với cơ sở dữ liệu người dùng. Chẳng hạn như câu lệnh sau:
select title, text from news where id=$id
Ở câu lệnh trên, biến $$d chính là dữ liệu được cung cấp cho người dùng, và phần còn lại chính là một phần SQL mà lập trình viên viết ra. Các hacker có thể tận dụng điều này để thay đổi logic của câu lệnh SQL bằng cách chèn thay đổi dữ liệu thành "10 or 1=1" vào mệnh đề WHERE.
select title, text from news where id=10 or 1=1
Các tấn công dạng SQL Injection có thể được phân thành 3 loại sau:
- Inband: dữ liệu được lấy bằng cách sử dụng giống kênh được dùng để chèn mã SQL vào. Đây là cách trực diện nhất, trong đó dữ liệu được truy xuất sẽ được thể hiện trực tiếp trên trang web ứng dụng.
- Out-of-band: dữ liệu được truy vấn bằng cách sử dụng một kênh khác như gửi email kèm theo có đó là câu truy vấn sẽ được tạo ra và gửi về.
- Inferential hay Blind: không có truyền dữ liệu thực tế nào, nhưng kiểm thử viên có thể dựng lại thông tin bằng cách gửi các yêu cầu cụ thể và quan sát hành vi nhận về của server dữ liệu.
Một cuộc tấn công SQL Injection thành công đòi hỏi kẻ tấn công phải tạo ra một truy vấn SQL đúng cú pháp. Nếu ứng dụng trả về một message lỗi được tạo ra từ một truy vấn không đúng, nó có thể dễ dàng cho kẻ tẩn công dựng lại logic của một truy vấn ban đầu, vì thế kẻ tấn công có thể hiểu được cách thực hiện injection đúng như thế nào. Tuy nhiên, nếu ứng dụng ẩn đi được các thông tin chi tiết về lỗi, thì kiểm thử viên phải có khả năng đảo ngược lại logic của truy vấn ban đầu.
Về các kỹ thuật để khai thác các lỗ hổng SQL Injection thường có 5 kỹ thuật phổ biến sau. Hơn nữa, 5 kỹ thuật này đôi lúc có thể dùng kết hợp nhau như union operator và out-of-band.
- Union Operator: có thể được sử dụng khi lỗ hổng SQL injection xảy ra trong một câu lệnh SELECT, làm cho nó có thể kết hợp hai truy vấn vào một kết quả hoặc tập kết quả.
- Boolean: sử dụng các điều kiện Boolean để xác minh xem các điều kiện nào là đúng hay sai.
- Dựa vào lỗi: kĩ thuật này sẽ ép cơ sở dữ liệu tạo ra lỗi sai, bằng cách cung cấp cho kiểm thử viên/kẻ tấn công các thông tin mà theo đó họ có thể lọc được việc chèn vào.
- Out-of-band: được dùng khi cần truy hồi dữ liệu bằng cách sử dụng một kênh khác, chẳng hạn tạo ra một kết nối HTTP để gửi kết quả đến web server.
- Time delay: dùng các câu lệnh cơ sở dữ liệu (chẳng hạn sleep) để làm trễ các câu trả lời trong các truy vấn điều kiện. Điều này sẽ có ích khi kẻ tấn công không có một số loại câu trả lời (kết quả, output hay error) từ ứng dụng.
Làm thế nào?
Kỹ thuật Truy Lỗi
Đầu tiên ta cần hiểu khi nào ứng dụng sẽ tương tác với một server CSDL để truy cập vào một số dữ liệu. Các ví dụ cụ thể khi một ứng dụng cần giao tiếp với DB gồm các form authentication (như tên người dùng và mật khẩu), các search engine, các trang thương mại điện tử (như các sản phẩm và đặc điểm của chúng gồm giá, mô tả, có sẵn hàng hay không, ....).
Theo đó kiểm thử viên phải tạo ra một danh sách đủ các trường nhập vào mà giá trị của chúng có thể được sử dụng khi tạo ra một truy vấn SQL, kể cả các trường được ẩn đi của các request POST và sau đó kiểm tra chúng riêng lẻ, bằng cách thử gây trở ngại bằng câu truy vấn và tạo ra lỗi. Ngoài ra còn xem xét đến HTTP Header và các Cookie.
Kiểm thử đầu tiên nhất thường dùng là thêm vào dấu nháy đơn (') hoặc chấm phẩy (