Chương 1 - Giới thiệu đề tài Trình bày tổng quan về vấn đề cần giải quyết, mục tiêu, phạm vi của đề tài, đồng thời nêu ý nghĩa thực tiễn của luận văn. Chương 2 - Kiến thức và công nghệ nền tảng Giới thiệu một số kiến thức nền tảng quan trọng phục vụ cho đề tài. Chương 3 - Những nghiên cứu liên quan Phân tích một số hướng tiếp cận các vấn đề chính cần giải quyết đã được nghiên cứu trong các tài liệu khác. Chương 4 - Phương pháp đề xuất Trình bày chi phương pháp đề xuất để hiện thực công cụ.
Chương 5 - Hiện thực công cụ Trình bày chi tiết các bước hiện thực công cụ theo phương pháp đã đề xuất. Chương 6 - Đánh giá Thực hiện phân tích và đánh giá công cụ đã xây dựng. Chương 7 - Tổng kết Đánh giá các điểm đạt được và các khuyết điểm còn tồn tại của luận văn. Trình bày hướng phát triển tiếp theo của đề tài.
4 2 Kiến thức và công nghệ nền tảng 2.1 Code Property Graph Code property graph (CPG) là một hình thức biểu diễn thông tin của mã nguồn dưới dạng đồ thị, được giới thiệu lần đầu bởi nhóm nghiên cứu của tác giả Fabian Yamaguchi [32]. Trong đó, nội dung mà CPG thể hiện là sự kết hợp từ các thuộc tính của cây cú pháp trừu tượng (AST), đồ thị luồng điều khiển (CFG) và đồ thị phụ thuộc chương trình (PDG). Ý tưởng chính trong việc kết hợp 3 loại đồ thị biểu diễn mã nguồn đã nêu vào trong một cấu trúc dữ liệu chung là việc thông tin về mã nguồn được khai thác đầy đủ trên nhiều khía cạnh (thuộc tính cú pháp, luồng điều khiển, luồng dữ liệu, .) sẽ cho phép tìm kiếm được các mẫu dữ liệu có giá trị phục vụ cho quá trình tìm kiếm lỗ hổng bảo mật tồn tại trong mã nguồn. 1 <? php 2 function func () { 3 if ( isset ( $_POST [ ’ code ’ ]) ) { 4 $code = $_POST [ ’ code ’ ]; 5 eval ( $code ) ; 6 } 7 } 8 ?> Hình 2.1: Mã nguồn PHP chứa lỗi Command Injection Trong phần này, chúng tôi sẽ trình bày tóm tắt các khái niệm liên quan tới việc xây dựng CPG từ mã nguồn PHP để người đọc nắm được vai trò của các thành phần cấu tạo nên cấu trúc đồ thị này.
Đoạn mã PHP ở Hình 2.1 sẽ được sử dụng làm ví dụ minh họa cho các khái niệm được trình bày tiếp theo đây. Đoạn mã minh họa hiện thực một hàm tên func với chức năng kiểm tra sự xuất hiện của tham số code được gửi tới bằng phương thức POST trong phần thân (body) của request (tham số này được chứa trong biến $_POST[code]) và sử dụng hàm eval() để thực thi câu lệnh hoặc biểu thức chứa trong biến $_POST[code] nếu có. Lỗi Command Injection của đoạn mã này tồn tại do hàm eval() trực tiếp thực thi câu lệnh trong biến có giá trị truyền từ ngoài vào mà không thực hiện kiểm tra sàng lọc, dẫn đến kẻ tấn công có thể truyền vào câu lệnh gây hại đến ứng dụng hoặc làm lộ thông tin quan trọng.1 Các thành phần của Code Property Graph Abstract Syntax Tree - AST. Cây cú pháp trừu tượng (AST) là biểu diễn dạng cây cho cấu trúc cú pháp trừu tượng của mã nguồn được viết bằng ngôn ngữ lập trình.
Tính trừu tượng của cây AST được thể hiện ở chỗ nó không có sự ràng buộc biểu diễn theo một ngôn ngữ lập trình cụ thể nào mà tập trung vào việc thể hiện cách các cấu trúc lập trình được lồng vào nhau và tạo thành chương trình hoàn chỉnh. Trong AST, nút trong đại diện cho các toán tử (ví dụ: toán tử cộng hoặc toán tử trừ), nút lá tương ứng với toán hạng (ví dụ: hằng số hoặc định danh). Cây AST sinh ra từ đoạn mã PHP minh họa được thể hiện ở Hình 2. Mặc dù AST cũng được sử dụng trong quá trình phân tích các đoạn mã chương trình [5] [31] nhưng do không thể hiện được những thông tin quan trọng như luồng điều khiển hay sự phụ thuộc các biến dữ liệu nên không cung cấp được đầy đủ thông tin cho việc tìm kiếm lỗ hổng bảo mật có thể tồn tại.
FUNC IF PRED STMT CALL STMT CALL isset ARG = eval ARG $_POST[’c’] $code $_POST[’c’] $code Hình 2.2: Cây cú pháp trừu tượng AST cho đoạn mã ở Hình 2.1 6 Chương 2 Control Flow Graph - CFG. Đồ thị luồng điều khiển (CFG) sử dụng các ký hiệu của đồ thị, biểu diễn tất cả các luồng điều khiển có thể được duyệt qua trong một chương trình. Một đồ thị luồng điều khiển có các đặc điểm chính sau: • Là đồ thị có hướng. • Mô tả các đường dẫn luồng điều khiển và các nút trong CFG mô tả các khối lệnh điều khiển cơ bản.
• Hiển thị tất cả các đường dẫn có thể được duyệt qua trong quá trình thực thi chương trình. Đồ thị luồng điều khiển chủ yếu được sử dụng trong phân tích tĩnh cũng như được ứng dụng trong các trình biên dịch, vì nó thể hiện được chính xác dòng thực thi bên trong của một đơn vị chương trình. Tuy nhiên, đối với phân tích lỗ hổng, CFG không cung cấp được thông tin về luồng dữ liệu, điều này có nghĩa là không thể sử dụng đồ thị này để xác định dữ liệu không an toàn truyền vào bởi kẻ tấn công được xử lý qua những câu lệnh nào.3 minh họa đồ thị luồng điều khiển cho đoạn mã ví dụ ban đầu. Start if(isset($_POST[’code’])) yes $code = $_POST[’code’] no eval($code) Stop Hình 2.3: Đồ thị luồng điều khiển CFG cho đoạn mã ở Hình 2.1 Program Dependence Graphs - PDG.
Đồ thị phụ thuộc chương trình (PDG) được giới thiệu trong nghiên cứu của nhóm tác giả Jeanne Ferrante [11], sử dụng cho quá trình phân đoạn chương trình (program slicing) [30]. Thành phần tạo nên PDG bao gồm: • Các node thể hiện câu lệnh hoặc biểu thức có trong hàm. • Cạnh biểu diễn sự phụ thuộc dữ liệu giữa các biến, từ khi được khai báo, khởi tạo đến khi được sử dụng trong chương trình và lan truyền dữ liệu nó chứa sang một biến khác. Để xác định được các cạnh này, cần giải quyết bài toán reaching definitions 1.
1 Reaching definitions: một bài toán thường gặp trong phân tích luồng dữ liệu.org/wiki/Reaching_definition 7 Chương 2 • Cạnh biểu diễn sự phụ thuộc điều khiển luồng thực thi của các câu lệnh trong chương trình vào các biểu thức vị từ. Các cạnh này có thể được xác định dựa vào biểu đồ luồng thực thi. Cần lưu ý, các cạnh phụ thuộc điều khiển trong PDG không giống với cạnh biểu diễn luồng thực thi trong CFG. Trên thực tế, trong PDG, thứ tự thực thi của các câu lệnh không thể được xác định, nó chỉ tập trung vào thể hiện sự phụ thuộc của việc câu lệnh có được thực thi hay không vào giá trị của biểu thức vị từ.
Đồ thị PDF ở Hình 2.4 được tạo từ đoạn mã PHP minh họa. Trong đó, cạnh gán nhãn Cf biểu diễn sự phụ thuộc điều khiển giữa các câu lệnh và cạnh gán nhãn D$code biểu diễn sự phụ thuộc dữ liệu trong biến $code.4: Đồ thị phụ thuộc chương trình PDG cho đoạn mã ở Hình 2.2 Các bước xây dựng Code Property Graph Để sử dụng hiệu quả thông tin có được từ AST, CFG và PDG, ta kết hợp cả 3 đồ thị này vào một cấu trúc chung. Để thực hiện điều này, trước hết ta cần biến đổi AST, CFG, PDG thành các php-static-analysis. Property graph [property-graph] là một loại mô hình đồ thị bao gồm các nút, quan hệ (biểu diễn bởi các cạnh có hướng), thuộc tính và nhãn.
Cả nút dữ liệu và quan hệ trong đồ thị đều được đặt tên và chứa các thuộc tính được biểu diễn dưới dạng cặp khóa - giá trị. Đây là kiểu biểu diễn dữ liệu cơ bản trong các cơ sở dữ liệu đồ thị như Neo4J, OrientDB. Một property graph được định nghĩa [32] như sau: Định nghĩa 1 Một property graph được kí hiệu G = (V, E, λ, µ) là một đa đồ thị có hướng, có thuộc tính, có cạnh được gán nhãn. Trong đó, V là tập các nút, E ⊆ (V × V ) là tập các cạnh có hướng, và λ : E → Σ là một hàm gán nhãn thực hiện gán các nhãn từ tập Σ cho mỗi cạnh trong đồ thị.
Các thuộc tính được gán cho các cạnh và các nút bằng hàm µ : (V ∪ E) × K → S với K là tập các khóa của thuộc tính và S là tập các giá trị của thuộc tính. Biến đổi AST. Cây cú pháp trừu tượng AST biến đổi thành một property graph, được kí hiệu GA = (VA , EA , λA , µA ). Trong đó: • VA là tập các nút của đồ thị, tương ứng với các nút có trong cây ban đầu.
• EA là tập hợp các cạnh tương ứng được gắn nhãn cạnh của AST thông qua hàm gán nhãn λA. 8 Chương 2 • µA gán các cặp thuộc tính KA = {code, order} cho các nút và cạnh sao cho thuộc tính code tương ứng với toán tử hoặc toán hạng mà nút đó thể hiện, thuộc tính order tương ứng với thứ tự của nút tương ứng trong cây AST. Biến đổi CFG. Tương tự như AST, đồ thị luồng điều khiển CFG cũng được biểu diễn ˙ Trong đó: dưới dạng property graph GC = (VC , EC , λC , ).
• Các nút trong VC tương ứng với các câu lệnh và biểu thức vị từ trong AST, cũng chính là các nút trong VA có giá trị thuộc tính code là STMT và PRED. • EC là tập hợp các cạnh tương ứng được gắn nhãn. Hàm gán nhãn λC được định nghĩa để gán các nhãn trong tập ΣC = {true, f alse, } vào các cạnh trong GC , ứng với các luồng thực thi khi điều kiện là true, false, không có điều kiện trong CFG. Biến đổi PDG.
Đồ thị phụ thuộc chương trình PDG biểu diễn sự phụ thuộc vào dữ liệu và luồng điều khiển giữa các câu lệnh và biểu thức vị từ. Do các nút trong đồ thị PDG giống với các nút trong CFG, PDG sẽ được chuyển thành property graph GP = (VC , EP , λP , µP ) với: • VC là tập các đỉnh trong property graph của đồ thị PDG. • EP là tập hợp các cạnh trong đồ thị. Nhãn của cạnh trong EP được gán bởi hàm λP : EP → ΣP với ΣP = {C, D} tương ứng lần lượt biểu diễn cho trạng thái phụ thuộc dữ liệu và phụ thuộc luồng điều khiển.