Nghiên Cứu Phương Pháp Fuzzing Trong Tự Động Hóa Phát Hiện Lỗ Hổng Phần Mềm Dựa Trên Học Tăng Cường

Khóa luận tốt nghiệp an toàn thông tin nghiên cứu phương pháp fuzzing kết hợp học tăng cường để tự động hóa phát hiện lỗ hổng phần mềm hiệu quả.

Chuyên ngành

An toàn thông tin

Người đăng

Ẩn danh

Thể loại

khóa luận tốt nghiệp

2023

61
9
0

Phí lưu trữ

30 Point

Mục lục chi tiết

LỜI CẢM ƠN

MỞ ĐẦU

1. CHƯƠNG 1: GIỚI THIỆU TỔNG QUAN ĐỀ TÀI VÀ CÁC HƯỚNG NGHIÊN CỨU LIÊN QUAN

1.1. Giới thiệu vấn đề

1.2. Tổng quan nghiên cứu

1.3. Mục tiêu, đối tượng và phạm vi nghiên cứu

1.4. Cấu trúc khóa luận tốt nghiệp

2. CHƯƠNG 2: CƠ SỞ LÝ THUYẾT

2.1. Khái niệm Fuzzing

2.2. Khối cơ bản - Basic block

2.3. Phương pháp học máy tăng cường sâu

2.4. Symbolic Execution

2.5. Concolic Execution

3. CHƯƠNG 3: MÔ HÌNH FUZZING ÁP DỤNG CONCOLIC EXECUTION VÀ HỌC TĂNG CƯỜNG SÂU

3.1. Tổng quan mô hình đề xuất

3.2. Trình fuzzing AELUCTT+T

3.3. Cơ chế theo dõi độ phủ mã

3.4. Cơ chế đồng bộ đầu vào

3.5. Trình concolic execution Driller

3.6. Mô hình học tăng cường sâu

3.6.1. Các thành phần của mô hình học tăng cường sâu

3.6.2. Phần thưởng - Reward

3.6.3. Thuật toán huấn luyện mô hình

4. CHƯƠNG 4: THỰC NGHIỆM VÀ ĐÁNH GIÁ

4.1. Thiết lập thí nghiệm

4.1.1. Thiết lập môi trường huấn luyện

4.1.2. Thử nghiệm mô hình học tăng cường sâu

4.1.3. Tập dữ liệu huấn luyện

4.1.4. Các trình fuzzing được thử nghiệm

4.2. Tiêu chí đánh giá

4.3. Kết quả quá trình huấn luyện mô hình

4.3.1. Chương trình CADEE

4.3.2. Chương trình CADET

4.3.3. Chương trình CROMU

4.3.4. Chương trình KPRCA

4.3.5. Chương trình YAN01

4.3.6. Chương trình YANO1

4.3.7. Đánh giá quá trình huấn luyện mô hình

4.4. Kết quả quá trình thực nghiệm

4.4.1. Số lượng nhánh đã được thực thi

4.4.2. Số lượng ngoại lệ gây ra khi fuzzing

4.4.3. Thời gian tìm được ngoại lệ đầu tiên khi fuzzing

4.4.4. Đánh giá kết quả thực nghiệm

KẾT LUẬN

5.1. Kết luận

5.2. Hướng phát triển

TÀI LIỆU THAM KHẢO

Tóm tắt

I. Phương pháp Fuzzing và Tự động hóa phát hiện lỗ hổng phần mềm

Phương pháp Fuzzing là một kỹ thuật quan trọng trong kiểm thử phần mềm, được sử dụng để phát hiện các lỗ hổng bảo mật thông qua việc đưa vào chương trình các đầu vào ngẫu nhiên hoặc không hợp lệ. Mục tiêu của Fuzzing là kích hoạt các đoạn mã tiềm ẩn, từ đó tăng độ phủ mã và khai thác các lỗi, đặc biệt là các lỗi liên quan đến bộ nhớ. Tự động hóa trong phát hiện lỗ hổng giúp giảm thiểu thời gian và nguồn lực cần thiết, đồng thời nâng cao hiệu quả của quá trình kiểm thử. Học tăng cường được áp dụng để tối ưu hóa quá trình Fuzzing, giúp lựa chọn các đầu vào hiệu quả hơn và tăng khả năng phát hiện lỗi.

1.1. Khái niệm và lịch sử phát triển của Fuzzing

Fuzzing được giới thiệu lần đầu bởi Miller và cộng sự vào năm 1990, và từ đó đã trở thành một phương pháp đáng tin cậy trong phát hiện lỗ hổng phần mềm. Ban đầu, Fuzzing chủ yếu dựa vào các đầu vào ngẫu nhiên, nhưng với sự phát triển của công nghệ thông tin, các kỹ thuật Fuzzing đã được cải tiến để tăng hiệu quả. Greybox FuzzingWhitebox Fuzzing là hai hướng tiếp cận chính, trong đó Greybox Fuzzing kết hợp ưu điểm của cả hai phương pháp, giúp tăng độ phủ mã mà không tiêu tốn quá nhiều tài nguyên.

1.2. Ứng dụng của Học tăng cường trong Fuzzing

Học tăng cường (Reinforcement Learning) đã được áp dụng vào Fuzzing để tối ưu hóa quá trình lựa chọn đầu vào và tăng khả năng phát hiện lỗi. Các mô hình như Deep Deterministic Policy Gradient (DDPG) và Q-learning được sử dụng để lựa chọn các bộ biến đổi đầu vào hiệu quả, giúp tăng độ phủ mã và giảm thiểu thời gian thực thi. Học tăng cường cũng giúp giải quyết vấn đề path explosion trong concolic execution, một thách thức lớn trong kiểm thử phần mềm.

II. Mô hình Fuzzing kết hợp Concolic Execution và Học tăng cường

Mô hình đề xuất trong nghiên cứu này kết hợp Concolic ExecutionHọc tăng cường để tối ưu hóa quá trình Fuzzing. Concolic Execution là một phương pháp phân tích động, kết hợp symbolic executionconcrete execution, giúp tìm ra các đầu vào thỏa mãn các điều kiện phức tạp trong chương trình. Khi Fuzzing không thể tạo ra đầu vào mới, Concolic Execution được kích hoạt để phân tích mã nguồn và tìm các đầu vào hỗ trợ. Học tăng cường được sử dụng để lựa chọn các đường dẫn thực thi hiệu quả, giúp tăng độ phủ mã và giảm thời gian thực thi.

2.1. Cơ chế hoạt động của Concolic Execution

Concolic Execution hoạt động bằng cách kết hợp symbolic executionconcrete execution. Các giá trị cụ thể được sử dụng để thực thi chương trình, trong khi các giá trị tượng trưng được sử dụng để phân tích các điều kiện rẽ nhánh. Khi gặp các điều kiện phức tạp, Concolic Execution sẽ ghi nhận các ràng buộc và sử dụng symbolic execution để tìm các giá trị thỏa mãn. Phương pháp này giúp giải quyết các vấn đề như path explosion và tăng khả năng phát hiện lỗi.

2.2. Tích hợp Học tăng cường vào mô hình Fuzzing

Học tăng cường được tích hợp vào mô hình Fuzzing để lựa chọn các đường dẫn thực thi hiệu quả. Các thuật toán như Q-learningDDPG được sử dụng để tối ưu hóa quá trình lựa chọn đầu vào và tăng độ phủ mã. Học tăng cường cũng giúp giảm thiểu thời gian thực thi bằng cách tập trung vào các đường dẫn có khả năng phát hiện lỗi cao. Kết quả thực nghiệm cho thấy mô hình này tăng độ phủ mã và hiệu suất so với các phương pháp truyền thống.

III. Thực nghiệm và đánh giá mô hình Fuzzing

Nghiên cứu đã tiến hành thực nghiệm trên các chương trình mẫu từ DARPA Cyber Grand Challenge để đánh giá hiệu quả của mô hình đề xuất. Kết quả cho thấy mô hình kết hợp Concolic ExecutionHọc tăng cường tăng độ phủ mã và giảm thời gian phát hiện lỗi so với các phương pháp truyền thống. Các chỉ số như số lượng nhánh được thực thi, số lượng ngoại lệ gây ra và thời gian tìm ra ngoại lệ đầu tiên đều được cải thiện đáng kể. Mô hình này cũng cho thấy khả năng xử lý các câu lệnh điều kiện phức tạp, một thách thức lớn trong kiểm thử phần mềm.

3.1. Thiết lập thực nghiệm và dữ liệu

Thực nghiệm được tiến hành trên các chương trình mẫu từ DARPA Cyber Grand Challenge, bao gồm các chương trình có cấu trúc phức tạp và nhiều câu lệnh điều kiện. Môi trường thực nghiệm được thiết lập với các công cụ Fuzzing hiện đại như AFL++Honggfuzz. Dữ liệu huấn luyện được thu thập từ quá trình FuzzingConcolic Execution, giúp tối ưu hóa mô hình Học tăng cường.

3.2. Kết quả và đánh giá

Kết quả thực nghiệm cho thấy mô hình đề xuất tăng độ phủ mã lên đến 30% so với các phương pháp truyền thống. Thời gian phát hiện lỗi cũng được giảm thiểu đáng kể, đặc biệt là với các chương trình có cấu trúc phức tạp. Mô hình này cũng cho thấy khả năng xử lý các câu lệnh điều kiện phức tạp, một thách thức lớn trong kiểm thử phần mềm. Các kết quả này khẳng định tiềm năng của việc áp dụng Học tăng cường vào Fuzzing.

21/02/2025

Trích đoạn nội dung tài liệu

Chương 1: Giới thiệu tổng quan đề tài và các hướng nghiên cứu liên quan 6 e Chương 2: Trình bày cơ sở lý thuyết các kiến thức liên quan đến đề tài e Chương 3: Trình bày mô hình fuzzing kết hợp hợp concolic execution và học tăng cường sâu e Chương 4: Trình bày kết quả thực nghiệm và các đánh giá liên quan e Chương 5: Kết luận và trình bày những hướng phát triển của đề tài CHƯƠNG 2. CƠ SỞ LÝ THUYET Ở chương này, chúng tôi trình bày cơ sở lý thuyết và những kiến thức liên quan của nghiên cứu, bao gồm Fuzzing, Concolic Execution và Phương pháp học máy tăng cường sâu. Khai niệm Fuzzing Fuzzing là một phương pháp tự động hóa kiểm thử thông qua việc đưa vào chương trình các bộ đầu vào ngẫu nhiên, không hợp lệ so với đầu vào mong muốn của chương trình nhằm kích hoạt được những dòng mã tiềm ẩn của chương trình từ đó tăng được độ bao phủ các nhánh mã cũng như khai thác các lỗ hồng của chương trình đang được kiểm thử, đặc biệt là các lỗ hong về bộ nhớ (memory corruption). Fuzzing được giới thiệu bởi Miller và cộng sự vào năm 1990 [14], đến nay đã phát triển và trở thành phương pháp đáng tin cậy để dò tìm lỗ hong phần mềm bởi mức độ hiệu quả mà nó mang lại.

Fuzzing hoạt động bằng cách cung cấp cho chương trình vô số các đầu vào với mục đích gây nên lỗi chương trình. Chính vì vậy, điểm cốt lõi của một trình fuzzing là phương thức sinh đầu vào có khả năng khiến chương trình mục tiêu thực thi nhiều đoạn mã và tạo ra các ngoại lệ trái với mục đích ban đầu của người lập trình. Độ phủ ma Khi kiểm thử chương trình, ngoài lỗ hổng tìm được, ta còn quan tâm đến lượng mã lệnh trong chương trình đã được thực thi. Đây được gọi là độ phủ 8 mã.

Độ phủ mã là yếu tố thường được sử dung để đánh giá hiệu năng của trình fuzzing sau số lượng lỗi phát hiện được với ý tưởng rằng độ phủ mã tỉ lệ thuận với số lỗi tìm được. Độ phủ mã thường được đo lường bằng cách chèn các đoạn mã đánh dấu trong chương trình nhằm xác định chương trình đã đi qua một đoạn lệnh nhất định hay chưa. Các trình fuzzing hiện nay còn dùng độ phủ mã để tạo ra các đầu vào hướng luồng thực thi chương trình đến một đoạn mã nhất định. Greuboz fuzzing (Coverage-guided fuzzing) Các phương pháp fuzzing có thể được phan loại theo nhiều cách: theo phương thức sinh đầu vào, theo mức độ nhận thức cấu trúc đầu vào hoặc theo mức độ nhận thức về cấu trúc của chương trình được kiểm thử.

Theo mức độ nhận thức về cấu trúc của chương trình mục tiêu, các phương pháp fuzzing được chia thành 3 nhóm: e Blackbox fuzzing: Nhóm phương pháp này được sử dụng khi ta không có nhiều thông tin về đối tượng kiểm thử. Các trình fuzzing thuộc nhóm này xem chương trình mục tiêu là một hộp đen (blackbox) và phụ thuộc vào việc quan sát hành vi của chương trình để tạo ra các bộ đầu vào mới. Blackbox fuzzing không tiêu tốn nhiều tài nguyên và có thé dé dàng được triển khai, nhưng phương pháp này khó có thể khai thác được các lỗ hổng phức tạp, cần sự hiểu biết sâu về chương trình mục tiêu. e Whitebox fuzzing: Nhóm phương pháp này được sử dụng khi ta có toàn quyền truy cập đến cau trúc thiết kế và mã nguồn của chương trình.

Điều này tạo điều kiện cho các phương pháp phân tích, đánh giá và xác định các vùng mã tiềm tàng lỗi để sinh các bộ đầu vào có khả năng hướng luồng thực thi đến các vùng mã này. Whitebox fuzzing có khả năng khai thác được các lỗ hổng phức tạp vốn không thể được khai thác bởi Blackbox fuzzing nhưng cần nhiều tài nguyên để phân tích chương trình đang được kiểm thử. Đại 9 diện cho nhóm phương pháp này gồm: SAGE [7], BuzzFuzz [6], KLUZZER [10],. e Greybox fuzzing: Nhóm phương pháp này kết hợp các đặc điểm của Blackbox và Whitebox fuzzing, thường được sử dụng khi ta có một phần thông tin về đối tượng kiểm thử đủ để cho phép một hướng tiếp cận nhắm đến mục tiêu kiểm thử hơn so với Blackbox fuzzing nhưng cũng không quá nặng về mặt phân tích chương trình như Whitebox fuzzing.

Greybox fuzzing có khả năng tạo ra các đầu vào nhắm đến một mục tiêu nhất định trong chương trình để cải thiện độ phủ mã cũng như số lượng lỗ hồng khai thác được mà không tiêu tốn quá nhiều tài nguyên tính toán. Tiêu biểu cho nhóm phương pháp này bao gồm: AFL [19], libFuzzer, Honggfuzz,. Greybox fuzzing không phụ thuộc vào các kỹ thuật phân tích chương trình như Symbolic Execution [9] hay Taint Analysis [15]. Thay vào đó, Greybox fuzzing thực hiện chèn các điểm đánh dẫu (instrumentation) vào các khối mã nhằm theo dõi quá trình thực thi của chương trình và đánh giá độ phủ mã (code coverage) của chương trình dưới một đầu vào nhất định.

Các đầu vào tao ra được trạng thái mới (ví dụ: thực thi được một đoạn mã mới, .) cho chương trình sẽ được lưu lại vào hàng đợi và được sử dụng trong các lượt fuzz sau. Các đầu vào không đem lại trạng thái mới sẽ được bỏ qua. Đây được gọi là Coverage-guided fuzzing. Khối cơ ban - Basic block Khối cơ ban (Basic block) định nghĩa một đoạn mã bao gồm một điểm bắt đầu (Entry point) và một điểm kết thúc (Exit point) trong đó không tồn tại bất kì lệnh rẽ nhánh nào khác ngoài điểm kết thúc và không tồn tại đích đến rẽ nhánh nào khác ngoài điểm bắt đầu.

Các trình greybox fuzzing chèn các điểm đánh dấu tại các lệnh rẽ nhánh hoặc đầu các khối cơ bản để theo vết luồng thực thi và xác định độ phủ mã của 10 chương trình khi nhận vào một đầu vào nhất định. Symbolic Execution Symbolic execution là một phương pháp thực thi chương trình sử dung các giá trị tượng trưng (symbolic value) thay cho các giá trị cụ thể (concrete value). Các giá trị đầu vào và các biến sẽ được thể hiện dưới dạng biểu thức đại diện cho các điều kiện ràng buộc nhánh của một đường thực thi trong chương trình (path constraints). Bằng cách giải các điều kiện ràng buộc này, symbolic execution có thể tạo ra các đầu vào hướng luồng thực thi đến một đoạn mã mục tiêu nhất định.

Xem xét đoạn mã nguồn bên dưới: BFoDWN&PO int x 0, y = 0; if (a < 5) { x II à } if (a && !b) yry- 2i assert(x + y == -1); Chon một đường thực thi của chương trình trên, ta sé theo dõi giá tri của các biến (có thể là cụ thể hoặc tượng trưng) cũng như các điều kiện ràng buộc để có thể thực thi được đường thực thi đã chọn. Với ø =a và b= Ø (a và Ø là giá trị tượng trưng), bảng 2.1 thống kê giá trị các biến và điều kiện ràng buộc để câu lệnh assert tại dòng 7 trả về true: Sau khi đã xác định được các ràng buộc của đường thực thi, một trình giải các giá trị ràng buộc này sẽ được sử dụng để tìm ra các giá trị cụ thể thỏa mãn được các điều kiện này nhằm hướng luồng thực thi của chương trình đến đoạn mã mục tiêu. 11 Dòng | Ràng buộc đường thực thi Giá trị của biến 0 | true ara, bw 8 1 | true ., FH0,yH0 2}a<5 2H 0,yH 0 5|œ<ð A œ#0 A ¬8 FH Ì, r>0 7|œ<5 A œZ0 A ABA 1+(-2)=-—l1|.1: Ví dụ vé symbolic execution 2. Concolic Execution Symbolic execution hiệu quả trong việc tìm các đầu vào thỏa mãn một đường thực thi nhất định.

Tuy nhiên phương pháp này có những hạn chế. Đối với các đường thực thi dài bao gồm nhiều câu lệnh điều kiện, bộ giải ràng buộc sẽ khó có thể giải các ràng buộc điều kiện và tìm ra giá trị thỏa mãn đường thực thi đang được xét. Diều này cũng xảy ra tương tự đối với các đường thực thi ngắn nhưng chứa các phép tính nằm ngoài khả năng tính toán của bộ giải ràng buộc như các hàm mật mã học hay các hàm toán học phi tuyến tính. Concolic execution có thể giải quyết những vấn đề này bằng cách kết hợp symbolic execution với concrete execution (thực thi sử dụng giá trị cụ thể).

Các giá tri cụ thể sẽ được sử dụng để thực thi chương trình. Tại các điểm rẽ nhánh, nếu giá trị cụ thể được sử dụng không thỏa mãn điều kiện rẽ nhánh dẫn đến đoạn mã cần thực thi, điều kiện của nhánh rẽ ngược lại sẽ được ghi nhận và symbolic execution sẽ được thực hiện theo nhánh rẽ này. Xem xét đoạn mã nguồn bên dưới: 1 weird_assert(int x, int y) { 2 if complex_func(x) == y { 3 ERROR ; 4 } else { 5 // OK 6 } 7 } 12 Xem hàm complex_ func là một hàm phức tap mà bộ giải ràng buộc không thể thỏa mãn. Thay vì tính toán giá trị x và y để thỏa mãn nhánh điều kiện dẫn đến ERROR, một giá trị cu thể sẽ được sử dụng cho x.

Lúc này Symbolic execution chỉ cần tìm giá trị y phù hợp để thỏa mãn nhánh điều kiện trên và dẫn chương trình đến dòng lệnh ERROR. Concolic execution giải quyết được van đề quá tai tính toán 6 symbolic exe- cution, giúp cho quá trình tìm đầu vào diễn ra nhanh hơn và hiệu quả hơn. Phương pháp học máy tăng cường sâu 2. Hoc may tăng cường - Reinforcement Learning 2.

Quy trinh quyét dinh Markov - Markov Decision Process Quy trình quyết định Markov (MDP) là một cấu trúc được sử dung để mô hình hóa bài toán lựa chọn quyết định trong các môi trường nhất định. Các kết quả nhận được từ môi trường có tính xác suất và phụ thuộc vào hành động đã được lựa chọn. Một MDP bao gồm các thành phần sau: e State S: Không gian các trạng thai của môi trường e Action A: Không gian các hành động có thể thực hiện trong môi trường e Transition probability P,(s;, 5:41): Ti lệ dé hanh động a tai trạng thai s¿ dan đến trang thái s;41 e Immediate reward R,(5;, 5:41): Phan thưởng nhận được khi môi trường chuyển từ trạng thái s; sang s;,, dưới hành động a 2. Khái niệm học máu tăng cường Học máy tăng cường (Reinforcement Learning) là một một nhánh của lĩnh vực may học.

Phương pháp học máy tăng cường dựa trên phương thức học thông 13 qua phan hồi, được mô hình hóa theo MDP, trong đó, một Tác tử (Agent) sẽ tương tác với Môi trường (Environment) bằng Hành động ø (Action) tại một Trạng thái s (State) và nhận lại phản hồi dưới hình thức là Phần thưởng r (Reward), từ đó học được hành động tối ưu nhất ở từng trạng thái.

Nội dung được bảo vệ bản quyền — Tải xuống đầy đủ