các công cụ fuzzing sẽ chạy chương trình với các đầu vào thử nghiệm, sử dụng các kĩ thuật đặc biệt để lấy thông tin độ phủ mã từ chương trình và dùng nó để đánh giá tiêu chí cho các đầu
Trang 1ĐẠI HỌC QUỐC GIA HỒ CHÍ MINH
TRƯỜNG DAI HỌC CÔNG NGHỆ THONG TIN
KHOA MẠNG MÁY TÍNH VÀ TRUYỀN THÔNG
NGUYEN PHÚC CHƯƠNG - 19520429
PHAM THANH THAI - 19520938
A COVERAGE-GUIDED FUZZING METHOD FOR BINARY
SOFTWARE VULNERABILITY DETECTION USING
REINFORCEMENT LEARNING
KY SU NGANH AN TOAN THONG TIN
GIANG VIEN HUGNG DAN:
TS Pham Van HauThS Phan Thé Duy
TP.H6 Chi Minh - 2023
Trang 2LỜI CẢM ƠN
Trong quá trình nghiên cứu và hoàn thành khóa luận, nhóm đã nhận được sựđịnh hướng, giúp đỡ, các ý kiến đóng góp quý báu và những lời động viên củacác giáo viên hướng dẫn Nhóm xin bày tỏ lời cảm ơn tới thầy Phan Thế Duy,thầy Phạm Văn Hậu đã tận tình trực tiếp hướng dẫn, giúp đỡ trong quá trìnhnghiên cứu.
Nhóm xin gửi lời cảm ơn đến gia đình và bạn bè đã động viên, đóng góp ý
kiến trong quá trình làm khóa luận
Nhóm cũng chân thành cảm ơn các quý thầy cô trường Đại học Công nghệThông tin - ĐHQG TP.HCM, đặc biệt là các thầy cô khoa Mang máy tính vàTruyền thông, các thầy cô thuộc bộ môn An toàn Thông tin đã giúp đỡ nhóm
Nguyễn Phúc Chương Phạm Thành Thái
Trang 3MUC LUC
LOICAMON 000 0000002000
MỤC LUC 222v.
DANH MỤC CAC KÝ HIỆU, CÁC CHỮ VIET TAT
DANH MỤC CÁC HÌNH VẼ
DANH MỤC CÁC BANG BIEU
MỞ ĐẦU ee CHƯƠNG 1 TONG QUAN 11 1.2 1.3 1.4 1.5 2.1 2.2 Giới thiệu van đề 2 ee Giới thiệu những nghiên cứu liên quan
2.1 Puzn) HP.“ s<t\EBS.j ⁄
.2.2_ Các kĩ thuật cải thiện fuzzing không sử dụng học máy 2.3 Sự kết hợp giữa học máy vào fuzzing
Tính ứng dụng ee hững thách thức cv. Mục tiêu, đối tượng, và phạm vi nghiên cứu
5.1 Muc tiêu nghiên cứu ẶẶ 5.2 Dối tượng nghiên ctu cccs 5.3 Phạm vi nghiên đỨU Ặ 00 200048 ð.4 Cau trúc khóa luận tốt nghiệp
-CHƯƠNG 2 CƠ SỞ LÝ THUYET Các phương pháp tìm kiếm lỗ hổng phần mềm
Fugzing 2 Ẽ 2.2.1 Cấu trúc tệp thực thi ELF (Executable)
2.2.2 Hợp ngữ (Assembly Languge)
ñ Vv vi vi
Trang 42.4
2.23 Cacloaiddphima 0
2.2.4 Các kĩ thuật lấy độ phủ mã
2.2.5 Các thông số so sánh của fuzzing
2.2.6 Shared memory và Semaphore
Mô hình học tăng cường 2 ee 2.3.1 Quy trình quyết định Markov (Markov Decision Process -MDP) Q.22. 2.3.2 Tổng quan mô hình học tăng cường
2.3.3 Van đề khai thác và khám phá trong hoc tăng cường 2.3.4 Hàm giá trị - hành động (Q-value Function)
2.3.5 Q-Learning 0.0 HQ ky 2.3.6 Mô hình học sâu tăng cường
2.3.7 Các thuật toán học tăng cường
Các thư viện sử dụng +
241 7 Kon up.“ vư„x.jJ ⁄
2.4.2 TensorflowWsses «eẽ fe ee eee 243 Gym Nhu (.ấ Ố _
CHƯƠNG 3 MO HÌNH FUZZING SỬ DUNG HỌC TANG 3.1 3.2 3.3 3.4 CUGNG Tổng quan mô hinh 2 ee Phương pháp biến đổi đầu vào dựa trên học tăng cường
3.2.1 Mô hình hóa fuzzing thành quy trình quyết định Markov 3.2.2 Trạng thai (state) ee 3.2.3 Hanh dong (action) 2.0 ee 3.2.4 Phần thưởng (reward) 2.0 ee 3.2.5 Mô hình deep-q-learnng
Thuật toán chọn va lập lịch đầu vào
Thuật toán biến đổi đầu vào nhiều cấp và chống lãng phi
3.4.1 Thuật toán biến đổi đầu vào nhiều cấp
46
Trang 53.4.2 Cơ chế chống lãng phí
3.5 Phương pháp thu thập độ phủ mã từ chương trình
3.6 Luồng hoạt động của chương trình
CHƯƠNG 4 THÍ NGHIỆM VÀ ĐÁNH GIÁ 4.1 Thiết lap thinghiém cccSC 4.1.1 Mục tiêu của thí
nghệm -4.1.2 Cài đặt các mô hình sosánh
4.13 Các ứng dung thử nghiệm
4.1.4 Các tiêu chí đánh gié 00
4.1.5 Thiết lập môi trường thử nghiệm
4.2 Kết quả thí nghiệm c2 nhe 4.2.1 Kết quả so sánh đánh giá sau 6 tiếng chạy
4.2.2 Kết quả so sánh đánh giá sau 200000 lần thử
4.3 Thảo luận về kết quả ee CHƯƠNG 5 KẾT LUẬN 51 Kết lui" “Za wd ` ` ˆ.-
5.2 Hướng phát triển Ốc
TÀI LIỆU THAM KHẢO
63 63 63
64 69 70 72 72 72 74 77
81
81 82
84
Trang 6DANH MỤC CAC KÝ HIỆU, CÁC CHỮ VIET TAT
5 Khéng gian các trang thái mà tác tử
St Trang thái môi trường tại lượt t
A Tap các hành động tác tử
đị Hành động tại lượt thứ t
P Ham chuyển
R Hàm phần thưởng
T Chính sách của Mô hình học tăng cường
w Trong số cho phần thưởng
* Chiết khấu cho phần thưởng
vr Chính sách tối đa hóa kì vọng
Q Hàm giá trị cho trạng thái - hành động
6 Trọng số cho mạng nơ-ron
a Ti lệ học
L(0) Hàm mat mát
AFL American Fuzzy Lop
SGD Stochastic Gradient Descent
MDP Markov Decision Process CEM Cross-Entropy Method DQN Deep Q Network
SARSA State-action-reward-state—action DPG Deep Deterministic Policy Gradient
PO Proximal Policy Optimization
R Enhancing Rate
PS Virtual Private Server
Trang 7DANH MUC CAC HINH VE
inh 1.1 Các bước trong quá trình fuzzing với độ phủ mã 6
ình 2.1 Cấu trúc tệp thực thi định dạng ELF_ 18
inh 2.2 Hàm, khối, cạnh trong hợp ngữ, phần 1 chứa mã nguồn chương trình viết bằng C, phần 2 chứa hợp ngữ của chương trình 21 inh 2.3 Chia sé vùng nhớ giữa 2 tiến trình 27
inh 2.4 Mô hình hoc tăng cường 30
inh 2.5 Thuật toán Q-Learning 33
inh 2.6 Q-Learning và Deep-Q-Learning 35
inh 2.7 Cấu trúc một Deep Q Network 36
inh 3.1 Tổng quan mô hình CTEu⁄z 46
inh 3.2 Chuyển từ đầu vào thành trang thái cho mô hình học tăng ình 3.3 Cấu trúc mô hình Deep Q Learning 51
inh 3.4 Cách AFLplusplus tương tác với forkserver để lấy độ phủ mã 59 inh 3.5 Cách CTFuzz tương tác với forkserver để lấy độ phủ mã 59
Trang 8DANH MUC CAC BANG BIEU
Bảng 2.1 Một số thuật toán hoc tăng cường
Bảng 3.1 Các hành động biến đổi thuộc không gian hành động
Bảng 4.1 Thông tin các ứng dụng thử nghiệm
Bảng 4.2 So sánh độ phủ mã giữa các mô hình sau 6 tiếng chạy
Bảng 4.3 So sánh số lượng đường dẫn duy nhất tìm được sau 6 tiếng
Bảng 4.5 So sánh độ phủ mã giữa các mô hình trong 200000 lần thử
đầu ay we WM —ìì _ eeBảng 4.6 So sánh số lượng đường dẫn duy nhất tìm được trong 200000
lànthiữ: S5 /@Ó @6Ẻ ——— Bảng 4.7 So sánh tốc độ chạy trong 200000 lần thử đầu
Trang 9TÓM TẮT KHÓA LUẬN
Tính cấp thiết của đề tài nghiên cứu:
Fuzzing là một kỹ thuật kiểm thứ phần mềm phổ biến và hiệu quả, bằng cách
tự động tạo ra hoặc biến đổi các đầu vào để kiểm tra tính ổn định và các lỗi
của hệ thống phần mềm Fuzzing đã được sử dung rộng rãi và liên tục được cải tiến bởi các nhà nghiên cứu và chuyên gia trong lĩnh vực bảo mật Mục tiêu của
fuzzing là tìm ra các lỗ hổng tiềm ẩn trong phần mềm bằng cách cung cấp các
đầu vào không mong đợi và không hợp lệ cho chương trình mục tiêu, theo đõi
hành vi của nó và xác định các lỗi, sự cố hoặc kết quả không mong muốn.
Gần đây với sự phát triển bùng no của trí tuệ nhân tạo, các nhà nghiên cứu
cũng đem các thuật toán máy học như học tăng cường vào nhằm cải thiện quá
trình fuzzing Các nghiên cứu trước đây cho thay học tăng cường có thé giúp cải
thiện hiệu quả fuzzing bằng cách giúp cho mô hình chọn và ưu tiên thực hiện
các hành động biến đổi mang lại độ phủ cao hơn, từ đó giảm số lượng thử để
tìm được các lỗi xuống Tuy nhiên các mô hình fuzzing kết hợp học tăng cườngđang gặp một số hạn chế nhất định, trong đó có việc mat cân bằng giữa tính
khai thác (exploit) và tính khám phá (explore) của mô hình.
Sau khi nghiên cứu, chúng tôi đề xuất một mô hình fuzzing có chỉ dẫn độ phủ
sử dụng học tăng cường có khả năng đảm bảo sự cân bằng giữa tính khai thác
và khám phá Mô hình đề xuất có thể hoạt động hiệu quả trên nhiều nền tảng,kiến trúc khác nhau và không yêu cầu mã nguồn để thực hiện fuzzing Ngoài
ra, chúng tôi cũng cung cấp những so sánh và một cái nhìn khách quan về hiệu
quả của mô hình so với các công cụ fuzzing hiện đại.
Trang 10CHƯƠNG 1 TONG QUAN
Chương này giới thiệu về van đề và các nghiên cứu liên quan Đồng thời,trong chương này chúng tôi cũng trình bày phạm vi và cấu trúc của Khóa luận
1.1 Giới thiệu van dé
Trong những năm gần day, sự phát triển mạnh mẽ của máy tính và công nghệ
đã trở thành một phần không thể thiếu trong hầu hết các hoạt động của conngười Tuy nhiên, điều này cũng có nghĩa là một lỗ hổng phần mềm trong cácứng dụng công nghệ mang lại những hệ quả rất đáng kể Những lỗ hổng này khixảy ra có thể gây ra những thiệt hại nghiêm trọng như mất tiền bạc, lộ thôngtin cá nhân, và nhiều hệ quả khác Các lĩnh vực như điều khiển công nghiệp,
nhà thông minh, và thành phố thong minh đặc biệt đối điện với những rủi rolớn hơn rất nhiều
Chính vì vậy, việc kiểm thử và nâng cao bảo mật phần mềm đã trở thành một
vấn đề được quan tâm và cải thiện ngày càng nhiều Trong số các kỹ thuật phát
hiện lỗ hổng phần mềm, fuzzing là một trong những phương pháp phổ biến, tiệnlợi và hiệu quả nhất Mục tiêu của fuzzing là tìm ra các lỗ hong tiềm an trong
phần mềm bằng cách cung cấp các đầu vào không mong đợi và không hợp lệ chochương trình mục tiêu, từ đó theo đõi hành vi và xác định các lỗi, sự cố hoặc
kết quả không mong muốn Một trong những kĩ thuật fuzzing phổ biến nhất đó
la fuzzing hộp xám (grey-box) với độ phủ mã (coverage) Kĩ thuật fuzzing này
yêu cầu cần có tệp thực thi của ứng dụng và chạy được chúng trên hệ thống
dùng dé fuzz Kĩ thuật này phổ biến bởi nó không yêu cầu mã nguồn của ứng
dụng (phù hợp cho các phần mềm mã nguồn đóng) và đạt được hiệu quả cao khi kết hợp các thông tin về độ phủ mã có được khi chạy chương trình Khi này
Trang 11các công cụ fuzzing sẽ chạy chương trình với các đầu vào thử nghiệm, sử dụng
các kĩ thuật đặc biệt để lấy thông tin độ phủ mã từ chương trình và dùng nó để
đánh giá tiêu chí cho các đầu vào thử nghiệm nhằm tối ưu hóa hiệu quả fuzzing
Gần đây, các kĩ thuật học máy như học tăng cường cũng được nghiên cứu
và áp dụng vào fuzzing Dựa vào đặc điểm của nó, học tăng cường thường đượccác nhà nghiên cứu chọn để làm 2 việc chính trong quá trình fuzzing: học để dự
oán hành động biến đổi nào dựa trên đầu vào sẽ cho độ phủ mã cao nhất và ùng để lập lịch, phân bổ số lượng thử nghiệm cho từng đầu vào Các nghiên
cứu đã cho thấy các mô hình fuzzing kết hợp học tăng cường mang lại hiệu quả
tốt trong cải thiện fuzzing, tuy nhiên vẫn còn nhiều hạn chế, trong đó nổi bật là
thời gian chạy chậm, yêu cầu nhiều tài nguyên và mất cân bằng giữa tính khaithác và khám phá.
Một trong những vấn đề lớn của các kĩ thuật fuzzing áp dụng học tăng cường
ó là sự cân bằng giữa tính khai thác (exploit) và tính khám phá (explore), các
mô hình này thường có tính khai thác vượt trội hơn rất nhiều so với tính khám
phá Tính khai thác (exploit) và tính khám pha (explore) là hai khái niệm quan
trọng trong quá trình fuzzing Tính khai thác đề cập đến việc các mẫu thử cókhả năng đi thật sâu và chạm đến những đoạn mã nằm rất sâu bên trong chươngtrình, còn tính khám phá đề cập đến việc các mẫu thử có mức độ bao phủ càngnhiều nhánh càng tốt Một mô hình fuzz có tính khám phá quá cao sẽ không tạo
ược các mẫu thử đủ sâu đến các phần đoạn mã bị lỗi của chương trình, trongđ
khi đó một hình fuzz có tính khai thác quá cao thường sẽ chỉ tập trung đi sâu
nhất có thể ở một nhánh mà bỏ qua khả năng lỗi nằm ở các nhánh khác trong
chương trình.
Trong nghiên cứu này của chúng tôi, chúng tôi đề xuất một mô hình fuzzing
có chỉ din độ phủ kết hợp hoc tăng cường cho fuzzing hộp xám có sự cải thiện
về các điểm yếu trước đó Mô hình sử dụng thuật toán học tăng cường là q-learning nhằm giúp cho mô hình dự đoán và chọn hành động biến đổi đầu vàomang lại hiệu quả cao nhất, dùng độ phủ mã của chương trình là điểm thưởng
Trang 12Kết hợp với nó là 2 thuật toán chọn đầu vào và lập lịch đầu vào đơn giản giúpcân bằng tính khai thác và k
cũng triển khai mô hình biến
cường giúp cho mô hình có thể
đó chúng tôi tiến hành so sán|
hám phá của chương trình Đồng thời chúng tôi
ổi đầu vào nhiều cấp có thể kết hợp với học tăng
tạo đột biến với một chuỗi nhiều hành động Sau
và đánh giá mô hình đề xuất với một công cụ
fuzzing sử dụng hoc tăng cường khác là rlfuzz, một công cụ fuzzer hiện dai là
AFLplusplus Kết quả cho thấy, mô hình được đề xuất có sự cải thiện đáng kể
Với sự phát triển và nghiên
được phân làm 3 loại chính là:
lượng đường dẫn tìm được và tốc độ chạy hơn so
độ hiệu quả trên 200000 lần thử đàu tiên nhỉnh
nghiên cứu liên quan
cứu không ngừng, các kĩ thuật fuzzing ngày nay fuzzing hộp đen (blackbox fuzzing), fuzzing hộp
trắng (whitebox fuzzing) và fuzzing hộp xám (greybox fuzzing).
e Fuzzing hộp đen (Black-box Fuzzing): đề cập đến các phương pháp fuzzing
khi không có bat kì thông tin gì về phần mềm Fuzzing hộp đen dựa vào
việc tạo ra các đầu vào ngẫu nhiên hoặc biến đổi các đầu vào tồn tại đểkiểm tra phan ứng của phần mềm Người kiểm thử hoặc công cu fuzz khong
biết cách phần mềm xử lý các đầu vào và chỉ dựa vào việc quan sát kết quả
để tìm kiếm lỗi Fuzzing hộp đen ít thông dụng hơn 2 loại fuzzing còn lại
do hiệu quả về việc tìm |di và 16 hổng là không cao, đồng thời do không
có thông tin về phần mềm nên khi xuất hiện lỗi cũng khó xác định nguyên nhân và bản chất của các lỗi.
e Fuzzing hộp trắng (White-box Fuzzing): là các kĩ thuật fuzzing thực hiện
khi có đầy đủ mã nguồn của phần mềm Do có day đủ thông tin, nên việc
Trang 13kiểm thử trong trường hợp này không dừng lại ở mỗi fuzzing mà thường
được kết hợp thêm các công cụ quét, phân tích tĩnh, ngoài ra việc tìm lỗi
cũng như làm thủ công có thể đạt hiệu quả cao hơn fuzzing trong một sốtrường hợp Ngoài ra fuzzing hộp trắng cũng cung cấp cho người kiểm thử
hay các công cụ fuzz nhiều lựa chọn hơn, như việc sửa đổi chương trình
để tăng tốc quá trình fuzz, hoặc chỉ fuzz những vị trí cu thể nào đó trong
chương trình, những điều mà rất khó thực hiện khi không có mã nguồn chương trình Các công cụ fuzz hiện đại như AFLplusplus còn cung cấp trình biên dịch đặt biệt chuyên dụng cho việc fuzzing và làm cho tốc độ
cũng như hiệu quả fuzzing được tăng lên rất nhiều lần Nhược điểm duy
nhất của phương pháp này là cần yêu cầu mã nguồn, và điều này là không
thể với hầu hết các ứng dụng sử dụng cho mục đích thương mại
Fuzzing hộp xám (Grey-box Fuzzing): Day là các phương pháp fuzzing chỉ
yêu cầu có tệp thực chi của chương trình Khi không thể có được các thông
tin từ mã nguồn của chương trình, các nhà nghiên cứu đã tìm cách tăng tốc
quá trình fuzzing bằng cách trích xuất và sử dụng các thông tin từ tệp thực
thi của chương trình cần fuzz Điều này là dé dang hơn nhiều vì ta có thể dé
dàng tìm được tệp thực thi của đa số các phần mềm Lúc này các nhà phân tích thường kết hợp các phương pháp phân tích tĩnh, phân tích động, kết hợp các thông tin lấy được từ chương trình khi thực thi đầu vào Trong đó
thì fuzzing dựa vào độ phú mã (coverage-guided fuzzing) nổi lên trở thành
một trong những phương pháp hiệu quả nhất của fuzzing hộp xám Với ý
tưởng rằng nếu đầu vào có thể phủ được nhiều phần trong mã chương trình
hơn, xác suất tìm được lỗi cũng sẽ cao hơn, từ đó các nhà nghiên cứu kết
hợp độ phủ mã (coverage) vào như là một phép đo hiệu suất để các công
cu fuzzing có thể "chấm điểm" các đầu vào, nhằm đưa ra các quyết định
trong quá trình fuzz, (giữ đầu vào nào, loại đầu vào nào, tiếp tục đột biến
từ đầu vào nào, ) Nổi bật nhất trong các công cụ fuzzing dựa vào độ phủ
mã có thể kể đến là AFL, AFLPlusPlus, HongFuzz, libFuzzer,
Trang 14Trong 3 kiểu trên, fuzzing hộp xám là thông dụng và linh hoạt nhất, do đó
nhóm chúng tôi quyết định sẽ nghiên cứu về fuzzing hộp xám cho mô hình củachúng tôi.
Quá trình fuzzing với độ phủ mã của một ứng dụng sẽ được gồm các bước cơ
bản như hình 1.1, trong đó vai trò của các bước là như sau:
Initial seed
Seed queue |——>| Selected seed —yessne/— Mutate seed
Optimize seed Runtime Run program Testcase
algorithm information with testcase
Hinh 1.1: Các bước trong quá trinh fuzzing uới độ phi ma
1 Dau tiên ta cần cung cấp một giá trị dau vào (seed), thường yêu cầu là một
đầu vào hợp lệ của chương trình, công cụ fuzz đưa vào một hàng chờ cácgiá trị đầu vào (seed)
2 Từ hang chờ các hạt giống, công cụ fuzz chọn ra một giá trị đầu vào để tiếnhành đột biến Mỗi công cụ fuzz sẽ có thuật toán để chọn khác nhau Và
hiệu quả của thuật toán chọn các hạt giống này cũng ảnh hưởng đến hiệu
quả của quá trình fuzzing.
3 Tiếp theo từ giá trị đầu vào được chọn, công cu fuzz tiến hành tạo ra các
Trang 15mẫu tht khác nhau từ đầu vào Quá trình này thường là thay đổi một phan
các giá trị đầu vào bằng một hành động nhất định (xóa bit, đảo bit, thêm
bit, dich bit, ) Việc chọn hành động nào để tạo ra mẫu thử từ đầu vào
và đành bao nhiêu nỗ lực cho việc này cũng ảnh hưởng đến hiệu suất của
cá quá trình fuzzing.
4 Tiếp theo, các công cụ fuzz thử các đầu vào được tạo với chương trình, thu
thập thông tin chương trình lúc chạy (lỗi chương trình, thời gian chạy, độ phủ mã, ).
5 Từ các thông tin thu thập được, công cụ fuzz sẽ tiến hành quyết định xemnên tiếp tục, loại bỏ, thay thế, các đầu vào trong hàng chờ đầu vào Nếu
có lỗi xảy ra, công cụ fuzz sẽ lưu lại mẫu thử và thông tin của lỗi để người
fuzz có thể tiền hành phân tích Và tiếp tục lại quá trình từ bước 2
Đối với các kĩ thuật fuzzing dựa vào độ phủ mã hiện tại, các thách thức chính
mà các nhà nghiên cứu đang tập trung cải thiện là:
1 Làm sao để gia tăng độ phủ mã tìm được?
2 Làm sao để tạo ra các đầu vào tốt hơn?
3 Làm sao để biến đổi đầu vào hiệu quả hơn, giảm đi những biến đổi không
hiệu quả?
4 Làm sao để vượt qua các kiểm tra cấu trúc của chương trình?
Làm sao để đến được nhiều nhánh hơn trong chương trình?
on
6 Lam sao để giảm tinh trạng dương tinh giả đối với các lỗi tìm được? (có
thật sự là lỗi, lỗi trùng, lỗi khai thác được hay không khai thác được, )
Đối với từng câu hỏi, có nhiều cách cũng như các giải pháp khác nhau đã
được nghiên cứu và đề xuất, tuy nhiên chúng ta có thể chia ra theo bước mà
nghiên cứu đó cải tiến, các bước sẽ như sau:
Trang 16e Bước tạo ra mẫu thử: O bước này, các nghiên cứu thường áp dụng các
kĩ thuật phân tích tĩnh, phân tích động, nhằm từ thông tin trích xuất được
từ tệp thực thi, tạo ra một đầu vào có thể đạt đến độ sâu cao hơn, khác với
việc sử dụng một đầu vào ngẫu nhiên, hoặc một đầu vào mẫu nào đó Hoặc trong các trường hợp khi đầu vào là các loại cấu trúc dữ liệu đặc biệt (định
dạng tệp, ), một số nghiên cứu sử dụng trí tuệ nhân tạo để học cấu trúccủa dữ liệu nhằm tao ra các mau thử vượt qua được kiểm tra cấu trúc ban
đầu của chương trình
e Bước chon đầu vào và biến đổi đầu vào: Khi nhiều mẫu thử được đánh
giá là tốt được lưu lại và sử dụng làm đầu vào ở bước sau, việc chọn đầu
vào nào tiếp theo để đem đi biến đổi, chọn phép biến đổi nào, và giành bao
nhiêu nỗ lực thử nghiệm cho đầu vào đó, cũng ảnh hưởng lớn đến hiệu suất
của mô hình Khi này, các nghiên cứu tập trung vào việc giảm thiểu các nổlực biến đổi dư thừa, nhanh chóng chọn các biến đổi chính xác để tăng độ
phủ mã từ đó tăng hiệu quả của quá trình fuzzing.
e Bước phân tích các lỗi sau khi fuzz: đôi khi trong các chương trình
có tính chất đặc biệt, việc dương tính giả được tìm thấy khi fuzzing là rấtnhiều, hoặc đôi khi đơn giản là các lỗi được tìm thấy bị trùng nhau Khi nàynếu các nhà phân tích thủ công sẽ rất mat công Vì thé các nhà nghiên cứu
cũng cải thiện điều này bằng các thuật toán kiểm tra trùng lặp, các thuậttoán đánh giá lỗi trả về, hay sử dụng các thuật toán học máy để chấm điểm
khả năng khai thác của các lỗi,
1.2.2 Các ki thuật cải thiện fuzzing không sử dung hoc may
Day là các phương pháp cải tiến fuzzing theo hướng truyền thống, chúng đều
có những ưu và nhược điểm nhất định Ji, Tiantian và các cộng sự giới thiệu
AFLPro trong [5], cải tiến bước chon đầu vào và lập lịch đầu vào bằng cách kết
hợp phân tích tĩnh với mô hình tổng hợp khối cơ bản, với mục tiêu ưu tiên các
Trang 17đầu vào chạm đến các đoạn mã ít được chạm trước đó hơn, nhằm nâng cao tỉ
lệ mẫu thử đạt đến những đoạn mã phía sâu trong chương trình Tai Yue vàcác cộng sự đề xuất EcoFuzz [16], mô hình hóa quá trình lập lịch cho các đầu
vào thành vấn đề Multi-Armed Bandit và trình bày một biến thể của mô hình Adversarial Multi-Armed Bandit để tiến hành cải tiến nó Ý tưởng chung của
cả 2 kĩ thuật này đều là để nhằm cải tiến khâu chọn đầu vào và lập lịch đầu
vào, nhằm uu tiên cho các đầu vào được dự đoán có khả năng lỗi cao hơn và
đem lại độ phủ mã tốt hơn Tuy nhiên vấn đề sử dụng các kĩ thuật phân tích tĩnh luôn là ở việc thiếu đi dữ liệu day đủ lúc chạy, và thường cho ra kết quả chính xác thấp hoặc dương tính giả (false-positive), đồng thời cũng sẽ không hoạt động hiệu quả trên các ứng dụng sử dụng các cơ chế làm rối mã hoặc đóng
gói Peng Chen và các cộng sự tạo ra Matryoshka [3], sử dụng phân tích ảnh
hưởng (taint analysis) để giải các câu lệnh điều kiện nhằm vượt qua kiểm thử
để đi sâu hơn vào chương trình, tuy nhiên kĩ thuật này đòi hỏi khá nhiều tài
nguyên và làm chậm di quá trình fuzzing, đồng thời taint analysis cũng gặp vấn
đề về under-tainting và over-tainting H Zhang và các cộng sự đề xuất một cơ
chế nhẹ và tiện lợi để vượt qua các kiểm thử đầu vào bằng cách kết hợp phân
tích tĩnh và đột biến các byte chính trong InsFuzz [17], bằng việc tìm các byte
có ảnh hưởng đến kết quả câu điều kiện so sánh, sau đó tiến hành đột biến, tuynhiên vì cũng sử dụng cơ chế phân tích tĩnh nên vẫn chịu các hạn chế như các kĩ
thuật phía trên, đồng thời cần sửa tệp thực thi gây nên sự không ổn định trongcác ứng dụng có kiểm tra tính toàn vẹn
1.2.3 Sự kết hợp giữa học máy vao fuzzing
Trong những năm gần đây, với sự phát triển bùng nổ của trí tuệ nhân tao,các kĩ thuật học máy cũng được các nhà nghiên cứu áp dụng vào để cải tiến
quá trình fuzzing Các khảo sát [12], [1] cho thấy sự áp dụng của các kĩ thuậthọc máy vào quá trình fuzzing là rất đa dạng và sáng tạo và đạt được nhiềukết quả khả quan Trong đó các bước thường được giải quyết bằng trí tuệ nhân
Trang 18tạo bao gồm: (1) chọn đầu vào, (2) lập lịch đầu vào, (3) tạo đầu vào, (4) chọnhành động đột biến, RapidFuzz của nhóm tác giả Ye, A [14] và CGFuzzer
của nhóm tác giả Yu, Z [15] ứng dụng mô hình mạng sinh đối kháng (GAN) để
tiến hành học cấu trúc của các đầu vào phức tạp nhằm tạo ra các mẫu thử cótính tương đồng cao hơn trong việc fuzz các giao thức hoặc các định dạng tệp
đặc biệt, giúp cho việc tránh lãng phí thời gian vào việc đột biến các mẫu thử
không hợp lệ và tăng tỉ lệ vượt qua các kiểm tra cấu trúc NeuFuzz của nhóm
tác giả Y Wang [13] mô hình hóa quá trình tìm lỗi như mô hình xử lí ngôn ngữ
tự nhiên, sử dụng mô hình hoc sâu (deep-learning) LSTM để học cấu trúc của
các đường dẫn chứa lỗi, từ đó dự đoán đường nào sẽ có tỉ lệ có lỗi cao hơn từ
đó ưu tiên và lập lịch đầu vào.
Các kĩ thuật học tăng cường (reinforcement learning) cũng được áp dụng vào
fuzzing lần dan tiên vào năm 2018 bởi Böttinger và các cộng sự [2] Trong đó,
họ chuyển hóa vấn đề fuzzing thành vấn đề của học tăng cường, việc chọn hành
ong đột biến tiếp theo được ví như chọn một nước đi tiếp theo trong một van
cờ, trong khi một chiến lược tối ưu có thể tồn tại, và tìm kiếm hành động tối uu
bằng thuật toán deep-q-learning Tuy nhiên mô hình họ đề xuất được thiết kế
ac biệt cho loại tệp pdf, thiếu đi kết quả khách quan khi so sánh với các công cufuzzing hiện đại và không đề cập đến vấn đề cân bằng giữa tính khai thác và tính
khám phá A Kuznetsov và các cộng sự cũng sử dung mô hình deep-q-learning
ổ chọn các hành động đột biến khi kiểm thử ứng dụng [6], họ cho thấy rằngviệc kết hợp học tăng cường có thể giảm đến 30% thời gian cần thiết để tạo raude mau thử kì vọng, tuy nhiên cách họ đánh giá hiệu quả không phù hợp với
các ứng dụng thực tế S Reddy và các cộng sự sử dụng thuật toán Monte Carlo
Control để cải tiến việc chọn hành động đột biến giúp công cụ fuzzing tạo ra
nhiều mau thứ hợp lệ đối với các ứng dụng có cấu trúc đầu vào phức tạp [8], kết
quả giúp tăng tỉ lệ vượt qua kiểm tra cấu trúc của các mầu thử, tuy nhiên nó
cũng cho thấy mô hình của họ đang đề cao tính khai thác nhiều hơn tính khámphá, khi học cách tạo ra các đầu vào đa dạng với các tính năng tương tự thay vì
Trang 19khám phá hành vi mới Li, X va các cộng sự giới thiệu Reinforcement Compiler
Fuzzing [7], cũng áp dụng thuật toán deep-q-learning vào bước chọn hành động
đột biến, tuy nhiên họ triển khai ở mức trình biên dịch, và cần mã nguồn để
hoạt động hiệu quả Drozd, W và các cộng sự kết hợp Deep-DoubleQ-Learning
để chọn các hành động đột biến và tăng tốc libFuzzer |4], tuy nhiên họ cũng
nhận xét rằng nó chưa đủ và cần thêm các sự cải tiến liên quan đến vấn đề lựa
chọn đầu vào và lọc đầu vào Zheng Zhang và các cộng sự đề xuất rlfuzz [1§] cân
bằng tính khai thác và khám phá trong mô hình fuzzing deep-q-learning bằng
cách chọn ngẫu nhiên mau thử thực hiện biến đổi tiếp theo khi mô hình không
có sự gia tăng về độ phủ mã, tuy nhiên cách chọn này chưa quá tối ưu khi các
đầu vào có độ phủ mã thấp trong hàng chờ vẫn có tỉ lệ được biến đổi ngang
bằng với các mẫu thử có tiềm năng cao hơn Wang, Jinghan và các cộng sự có
một sự kết hợp học tăng cường khác biệt hơn khi họ sử dụng nó vào trong việc
lập lịch đầu vào thay vì chọn hành động đột biến như các nghiên cứu khác [11],
họ đề xuất mô hình độ phủ mã nhiều cấp độ, để làm tăng độ chỉ tiết khi fuzzing
và đề xuất cơ chế lập lịch hỗ trợ cho mô hình phủ mã nhiều cấp độ sử dụng học
tăng cường Kết quả cho thấy các mau thứ tao ra có sự cân bằng giữa tính khaithác và khám phá nhưng lại không có sự cải tiến đáng kể nào về việc chọn các
hành động đột biến sao cho hiệu quả hơn
Các giải pháp kết hợp giữa học tăng cường và fuzzing hiện tại đều tập trungkhá nhiều về việc thiết kế thuật toán học tăng cường, trạng thái (states), kếtquả (reward), và các tham số mà chưa có sự xem xét về các yếu tố khác nhưtính cân bằng giữa khai thác và khám phá Diéu này dẫn đến việc các mô hình
fuzzing sử dụng học tăng cường có xu hướng đào sâu vào một nhánh mã mà bỏ
qua cơ hội tìm lỗi ở các nhánh mã khác, đồng thời thường chỉ tập trung vào bước chọn hành động đột biến mà chưa có các cơ chế chọn và lập lịch đầu vào hợp lí
giúp mô hình fuzz xử lí tốt hơn khi fuzzing thực tế như các công cụ fuzzing phổbiến Ngoài ra, chưa có nghiên cứu về mô hình học tăng cường trong fuzzing nàođưa ra góc nhìn so sánh về hiệu suất, ưu nhược điểm so với các công cụ fuzzing
Trang 2012 hiện đại.
Nhận thấy các điểm yếu về mất cân bằng giữa tính khai thác và tính khámphá các mô hình fuzzing kết hợp học tăng cường có thể giải quyết nếu như kết
hợp các thuật toán chọn đầu vào và lập lịch đầu vào hiệu quả, một chủ đề đãđược nghiên cứu cải tiến rất lâu ở fuzzing truyền thống Nhóm chúng tôi nghiên
cứu và đề xuất mô hình fuzzing có chỉ dẫn độ phủ trong phát hiện lỗ hổng phần
mềm dựa trên học tăng cường có khả năng khắc phục các điểm yếu trên nhờ kết
hợp với một thuật toán chọn đầu vào và lập lịch đầu vào hiệu quả Đồng thời
nhóm cũng phát triển thuật toán biến đổi đầu vào nhiều cấp có thể kết hợp cho
các mô hình fuzzing sử dụng học tăng cường và cơ chế chống lãng phí giúp tăng
độ hiệu quả của mô hình.
1.3 Tính ứng dụng
Mô hình fuzzing mới kết hợp ứng dụng học tăng cường để tăng tốc quá trình
fuzzing trong fuzzing hộp xám, phù hợp cho việc fuzz nhiều phần mềm khác
nhau Mô hình có sự cải thiện hơn các mô hình trước về tính khám pha, đồng
thời giữ được tính khai thác ở mức ngang bằng Mô hình cho thấy rằng các
thuật toán học sâu có khả năng giúp đỡ và cải thiện độ hiệu quả của mô hình
fuzzing, đồng thời có thể khắc phục các điểm yếu cố hữu về sự cân bằng giữa
tính khai thác và khám phá bằng các thuật toán chọn đầu vào và lập lịch đầuvào hiệu quả.
1.4 Những thách thức
Việc nghiên cứu mô hình fuzzing sử dụng học máy gồm những công đoạncần nhiều thời gian Nhóm mất nhiều thời gian trong việc nghiên cứu tìm cácphương pháp trính xuất độ phủ mã từ chương trình đang chạy có hiệu quả cao,
và sửa đổi cũng như cài đặt để có thể tích hợp thành công vào mô hình Bên
cạnh đó, một tham số dùng cho đánh giá là số đường dan riêng biệt tìm được
Trang 21do không được hỗ trợ thống kê sẵn trong các công cụ fuzzing, nhóm phải tiến
hành sửa mã nguồn của công cụ để thống kê Đồng thời nhóm phải tìm hiểu và
nghiên cứu mã nguồn của các cộng cụ fuzzing khác nhau, từ đó tìm ra ưu và
nhược điểm của từng mô hình, khi mà không có quá nhiều tài liệu chỉ tiết về
cách các công cụ này hoạt động Ngoài ra có rất nhiều yếu tố môi trường khác
khiến cho quá trình fuzzing diễn ra bị ảnh hưởng hiệu suất, và việc đánh giá
hiệu quả của nó cần được chạy trên nhiều lần để có kết quả khách quan Việc
thử nghiệm cũng đồi hỏi nhiều thời gian và yêu cầu nhiều tài nguyên để thực
hiện.
1.5 Mục tiêu, đối tượng, và phạm vi nghiên cứu
1.5.1 Mục tiêu nghién cứu
e Nghiên cứu sử dụng mô hình học tăng cường để chọn hành động mang lại
độ phủ mã cao hơn khi biến đổi đầu vào
e Xây dựng thuật toán chọn và lập lịch đầu vào cân bằng tính khai thác và
khám phá của mô hình fuzzing sử dụng học tăng cường
e Tối ưu hóa hiệu quả của mô hình fuzzing học tăng cường
e Triển khai mô hình fuzzing hộp xám với độ phủ mã kết hợp học tăng cường
và các thuật toán tối ưu được nghiên cứu
e So sánh và dua ra ưu nhược điểm của mô hình fuzzing kết hợp học tăng
cường, so sánh điểm mạnh, điểm yếu so với các công cụ fuzzing hiện đại, từ
đó đưa ra hướng phát triển
1.5.2 Đối tượng nghiên cứu
Đối tượng nghiên cứu:
e Kĩ thuật fuzzing trong phát hiện lỗ hổng phần mềm
Trang 22e Các thuật toán học tăng cường
e Các thuật toán lập lịch đầu vào và chon đầu vào trong fuzzing
e Các thư viện hỗ trợ máy học tensorflow, keras, gym
e Các công cụ fuzzing có chỉ dan độ phủ AFLplusplus, rlfuzz, libFuzzer
1.5.3 Pham vi nghiên cứu
Mô hình fuzzing sử dung học tăng cường để chon hành động biến đổi tối ưu
nhất đối với từng đầu vào, đồng thời kết hợp thuật toán chọn đầu vào và lập
lịch đầu vào để cân bằng tính khai thác và tính khám phá, mang lại độ phủ mã
cao hơn cũng như sự đa dạng về các luồng thực thi chương trình
1.5.4 Cấu trúc khóa luận tốt nghiệp
Chúng tôi xin trình bày nội dung của Luận án theo cấu trúc như sau:
e Chương 1: Giới thiệu tổng quan về đề tài của Khóa luận và những nghiêncứu liên quan.
e Chương 2: Trình bày cơ sở lý thuyết và kiến thức nền tảng liên quan đến
đề tài
e Chương 3: Trình bày mô hình fuzzing sử dụng hoc tăng cường được chúng
tôi đề xuất
e Chương 4: Trình bày thực nghiệm và đánh giá.
e Chương 5: Kết luận và hướng phát triển của dé tài.
Trang 23CHƯƠNG 2 CƠ SỞ LY THUYET
Chương này chúng tôi trình bay co sở lý thuyết của nghiên cứu: bao gồm 2
phần lớn là phương pháp fuzzing trong tìm kiếm 16 hổng phần mềm và mô hình
học tăng cường.
2.1 Các phương pháp tìm kiếm lỗ hổng phần mềm
C6 nhiều phương pháp tìm kiếm 16 hồng phần mềm được sử dụng trong quátrình kiểm thử và phân tích bảo mật Dưới đây là một số phương pháp phổ biến:
e Kiểm tra mã (Code review): Kiểm tra mã là quá trình xem xét và phân
tích mã nguồn của một phần mềm để tìm các lỗ hổng bảo mật Phương
pháp này thường được thực hiện bởi chính các lập trình viên trong cùng
nhóm hoặc hoặc các chuyên gia bảo mật và yêu cầu hiểu biết sâu về ngônngữ lập trình và kiến thức về bảo mật Mục tiêu việc kiểm tra mã không chỉ
về lỗ hổng phần mềm mà còn liên quan đến việc tối tu hiệu suất của chương
trình, làm đẹp mã nguồn, Do việc có được mã nguồn, thông thường cáchnày kết hợp sử dụng rất nhiều công cụ tự động hóa cho việc quét và tìm lỗ
hong tự động Cách làm này đạt hiệu quả cao nhưng thường được áp dụng
trong nội bộ vì các công ty lớn không muốn mã nguồn của mình bị lộ rabên ngoài.
« Kiểm thử bảo mật (Pentest): Dây thường là một phương pháp tìm
iếm lỗ hổng phần mềm bằng cách thử thâm nhập tấn công phần mềm đó,việc làm này không chỉ giúp tìm ra lỗ hổng phần mềm mà còn có thể đánhgiá được mức độ nguy hại của lỗ hổng đó (kẻ tấn công có thể làm gì nếuhai thác lỗ hổng đó) Kiểm thử cũng chia ra làm 3 loại tương ứng là kiểm
Trang 24thử hộp trắng (white-box testing), kiểm thử hộp đen (black-box testing)
và kiểm thử hộp xám (grey-box testing) Trong đó kiểm thử hộp trắng gầnnhư tương tự kiểm tra mã nhưng chỉ tập trung vào các lỗ hổng bảo mật
Phân tích tĩnh (Static analysis): Phân tích tĩnh là quá trình tìm kiếm
lỗ hổng phần mềm bằng cách kiểm tra các tệp thực thi, thư viện và cấutrúc di liệu của ứng dụng dé tìm kiếm các lỗ hổng bảo mật tiềm ẩn, như
việc sử dụng biến không an toàn, cung cấp quyền truy cập không cần thiết,
các 16 hong như tràn bộ đệm, Phương pháp này khác với phan tích dong
là nó không cần phải chạy ứng dụng Để thực hiện phân tích tĩnh, phân
tích viên cần có được tệp thực thi của phần mềm và thường kết hợp với các
kĩ thuật địch ngược để phân tích Phương pháp này thường được thực hiệnđầu tiên khi phân tích để có được cái nhìn tổng thể về ứng dụng cần được
phân tích Tuy nhiên nó không hiệu quả với các chương trình quá phức tạphoặc có kết hợp các cơ chế bảo vệ như làm rối ma, đóng gói, mã hóa,
Phân tích động (Dynamic analysis): Phân tích động là quá trình quan
sát và phân tích hành vi thực thi của một chương trình trong khi nó đang
chạy Điều này bao gồm theo déi các lỗi thực thi, kiểm tra sự tương tác giữacác thành phần và phân tích luồng dữ liệu để phát hiện các lỗ hổng bảo
mật Phương pháp này cũng yêu cầu có được tệp thực thi của phần mềm
và thường được thực hiện sau khi thực hiện phan tích tĩnh.
Fuzzing: Fuzzing là một phương pháp tìm kiếm lỗ hổng phan bằng cách
tự động tạo ra các dữ liệu đầu vào ngẫu nhiên hoặc có cấu trúc để kiểm thửứng dụng Fuzzing tìm kiếm các lỗ hổng bảo mật bằng cách gửi các dit liệu
đầu vào không mong đợi và không hợp lệ cho chương trình mục tiêu, từ đó
theo dõi hành vi và xác định các lỗi, sự cố hoặc kết quả không mong muốn.
Điểm tiện lợi của fuzzing là quá trình này được tự động hóa hoàn toàn,
do đó nó rất hiệu quả với các chương trình lớn hay phức tạp, nơi mà các lỗ
hổng nằm rất sâu trong chương trình và khó tìm thấy Kiểm thử viên có thể
Trang 25dựng môi trường fuzzing và để quá trình này tự động diễn ra, trong thời
gian đó, kiểm thử viên có thể làm công việc khác, hoặc áp dụng các phương
pháp tìm kiếm lỗ hổng phần mềm khác song song việc này Điều này biến
fuzzing trở thành phương pháp cực kì tiện lợi vì nó tận dụng tối đa được
thời gian dùng để tìm kiếm 16 hong phần mềm Với nhiều nghiên cứu và phát triển liên tục, các công cu fuzz ngày nay dần trở nên thong minh hơn
và cực kì hiệu quả, các phương pháp fuzz cũng trở nên đa dạng và tùy biến phù hợp cho nhiều trường hợp khác nhau và ngữ cảnh khác nhau.
2.2 Fuzzing
Ở phần này chúng tôi trình bày các kiến thức cần biết khi fuzzing, bao gồm
cấu trúc tệp thực thi, hợp ngữ, các loại độ phủ mã, các kĩ thuật lấy độ phủ mã,
các thông số sủ dụng trong fuzzing và một vài kĩ thuật sử dụng để tăng tốc
fuzzing (shared memory và semaphore).
2.2.1 Cấu trúc tệp thực thi ELF (Executable)
Tép thực thi (Executable) là một loại tệp tin chứa chương trình đã được biên
dịch và có thể được thực thi trực tiếp bởi một hệ điều hành hoặc môi trường
thực thi tương ứng Tép thực thi thường là kết quả của quá trình biên dịch chương trình từ ngôn ngữ lập trình cấp cao (như C, C++, Java, Python, etc.)
sang ngôn ngữ máy, phù hợp với kiến trúc và hệ điều hành của máy tính Nó
chứa các thông tin cần thiết để hệ điều hành hoặc trình thông dịch có thể thực
thi chương trình, bao gồm các mã máy, các kết nối đến thư viện, bảng mã, vùng
nhớ và các tài nguyên khác cần thiết để chương trình chạy Có được tệp thực thi của ứng dụng mục tiêu là yêu cầu tối thiểu dành cho fuzzing hộp xám Trong
mô hình của chúng tôi, chúng tôi thử nghiệm và triển khai trên hệ điều hành
linux, tệp thực thi tương ứng chúng tôi sử dụng là định dang ELF 64-bit.
Như mô tả trong hình 2.1, tệp tin ELF bao gồm các phần sau:
Trang 2618
Trang 27e Tiêu dé ELF (ELF Header): Day là phần đầu tiên của tệp tin ELF va
chứa thong tin cơ bản về cấu trúc của tệp tin, bao gồm kiểu file, kiến trúc
mục tiêu (32-bit, 64-bit), các địa chỉ quan trọng như địa chỉ bắt đầu của các phần khác, và các cấu trúc con tiếp theo của tệp tin.
e Các tiêu đề chương trình (Program Headers): Phan này chứa thông
tin về các đoạn (segment) trong tệp tin Mỗi đoạn đại diện cho một phần của bộ nhớ cần được tải và thực thi, bao gồm mã máy, dữ liệu và các phần khác của chương trình Các tiêu đề chương trình chỉ ra vị trí và kích thước
của các đoạn trong bộ nhớ.
e Các tiêu đề phần (Section Headers): Phan này chứa thông tin về các
phần trong tệp tin Mỗi phần đại điện cho một loại dữ liệu cụ thể trong chương trình, chang hạn như mã máy, dữ liệu tĩnh, biểu đồ ký hiệu, thong
tin gỡ lỗi và nhiều loại phần khác Các tiêu đề phần chỉ ra vị trí, kích thước
và các thuộc tính khác của từng phần Các công cụ fuzzing dựa vào phần
này để tìm ra các phần chưa mã để chèn các mã phụ nhằm tính toán độ
2
phủ.
e Các phần (Section): Đây là một mảng chứa dữ liệu chi tiết của từng phan
của chương trình Trong đó phần tezt chưa mã thực thi của chương trình,
là nơi chúng ta tính toán độ phủ mã.
2.2.2 Hợp ngữ (Assembly Languge)
Mỗi máy tính có một bộ vi xử lý dé quản lý hoạt động số học, logic, va điều khiển của máy tính Mỗi họ của bộ vi xử lý đã thiết lập riêng của mình về hướng dẫn xử lý các hoạt động khác nhau chang hạn như nhận đầu vào từ bàn phím, hiển thị thông tin trên màn hình và thực hiện các công việc khác nhau Những
bộ lệnh như vậy được gọi là ngôn ngữ máy, bao gồm các chuỗi 0 và 1 Tuy nhiên
ngôn ngữ máy là quá phức tạp để con người có thể hiểu và lập trình do đó phải
cần đến hợp ngữ.
Trang 28Hợp ngữ (Assembly language) là một ngôn ngữ lập trình cấp thấp, nó cung
cấp một cách để biểu diễn các chỉ thị và dữ liệu dưới dạng các từ vựng và cú pháp đơn giản, dễ hiểu cho con người, trong khi vẫn giữ được tính bền vững và
sự gần gũi với ngôn ngữ máy Mỗi một hợp ngữ là dành riêng cho một kiến trúc
máy tính cụ thể Trong việc dịch ngược và tìm lỗi phần mềm với các ứng dụng không có mã nguồn, việc am hiểu hợp ngữ là rất quan trọng Đồng thời trong
ngữ cảnh fuzzing hộp xám, độ phủ mã được tính toán dựa trên hợp ngữ.
2.2.2.1 Hàm, khối, cạnh trong hợp ngữ
Hình 2.2 thể hiện hợp ngữ của chương trình viết bằng ngôn ngữ C sau khi
biên dịch trên hệ điều hành linux kiến trúc 64-bit dưới dạng đồ thị Chương
trình mẫu là chương trình đơn giản có tính năng nhận một chuỗi nhập vào và
kiểm tra xem chuỗi được nhập có chứa kí tự số lẻ không Sau khi biên dịch thành
hợp ngữ, việc phân chia đồ thị này dựa trên các lệnh nhảy, lệnh gọi hàm, và kết
thúc hàm trong chương trình.
Trong đó:
e Ham: Toàn bộ sơ đồ trên là biểu thị cho 1 hàm, vì chương trình sử dụng 1
hàm duy nhất là main
e Dòng/Lệnh: Mỗi lệnh trong hợp ngữ được biểu thị trên 1 dong Một lệnh
từ ngôn ngữ C có thể biên dịch thành chuỗi các lệnh hợp ngữ.
e Khối: Các khối mã được xác định dựa trên các lệnh nhảy, gọi hàm và kết
thúc hàm, mỗi khối chứa các lệnh hợp ngữ liên tiếp chắc chắn sẽ được thực
hiện nếu chương trình đi vào nhánh đó Ví du, A, B, C, D, E, F, G là các khối.
e Cạnh: Là điểm nối giữa các khối trong chương trình, thể hiện sự chuyển
đổi từ nhánh này sang nhánh khác Ví du, AB, BC, BD, là các cạnh.
Trang 29scanf("%2s", buf): ov ‘bp, Isp
for (int i = 0; i < 2; i++) { sub rsp, 10h
unsigned char n = buf[i] - 48; mov_ rsi, rax
if (n< 10 && n % 2 == 1) { lea rax,unk 402004
mov rdi, rax
puts("Odd number founded"); mov eax, 0
break; call _ isoc99 scanf
loc_401186: ©)
mov eax, [rbp+var 4] loc_4011C2:
cdqe mov eax,0 movzx eax, [rbp+rax+var_8] leave
sub eax, 30h ; '0' retn mov [rbp+var_5], al
cmp [rbp+var 5], 9
ja — short loc_4011B8
)
movzx eax, [rbp+var_5]
and eax, 1 loc_4011B8:
test al, al add [rbp+var_4], 1
jz tan lee 401188 Cg) (F)
lea rax,s ¡ "Odd number found"
mov rdi, rax ¡8 call _puts
jmp — short loc_4011C2
Hình 2.2: Hàm, khối, cạnh trong hợp ngữ, phan 1 chứa mã nguồn chương trinh
viét bằng C, phan 2 chứa hợp ngữ của chương trình
Trang 302.2.3 Các loại độ phi ma
Có nhiều loại độ phủ mã được sử dụng trong fuzzing, một vài loại chính
thường được sử dụng là:
e Độ phủ theo ham (Function coverage): Do lường số hàm đã được thực
thi trong quá trình fuzzing Một hàm được coi là được phủ nếu nó đã được gọi ít nhất một lần.
e Độ phủ theo khối mã (Block coverage): Do lường số khối mã đã được
thực thi trong quá trình fuzzing Một khối mã được coi là được phủ nếu tất
cả các câu lệnh trong khối mã đã được thực thi ít nhất một lần.
e Độ phủ theo cạnh (Edge coverage): Do lường số cạnh (edge) của đồ thị
điều khiển (control flow graph) đã được thực thi trong quá trình fuzzing.
Một cạnh được coi là được phủ khi đầu vào và đầu ra của cạnh đã được thực thi ít nhất một lần.
e Độ phủ theo dòng lệnh (Line coverage): Do lường số lệnh mã đã được
thực thi trong quá trình fuzzing Nếu một lệnh mã đã được thực thi ít nhất một lần, thì nó được coi là được phủ.
Xét theo thứ tự mức độ chỉ tiết thì độ phi mã theo dòng là chi tiết nhất, tiếp đến là theo cạnh, rồi đến theo khối và cuối cùng là theo hàm Tuy nhiên khi fuzzing các công cụ thường không đo độ phủ theo dòng lệnh vi số lượng lệnh
là quá lớn nếu fuzzing trên một các ứng dụng có nhiều tính năng, việc phải ghi nhận độ phủ cho từng lệnh trong một chương trình lớn khiến sẽ ảnh hưởng đến
tốc độ và hiệu năng của mô hình fuzzing Thay vào đó, lựa chọn giữa độ phủ
theo khối mã hoặc theo cạnh sẽ mang lại hiệu quả tốt hơn.
Độ phủ mã theo cạnh sẽ mang lại độ chi tiết cao hơn độ phủ mã theo khối vi
nó thể hiện được luồng thực thi của chương trình Các cạnh thể hiện các điểm
nối giữa các khối mã trong một chương trình, vì vậy ghi nhận các cạnh sẽ đồng
Trang 31thời ghi nhận được thứ tự thực hiện và mối quan hệ giữa các khối Ví dụ theo
hình 2.2, luồng chạy qua các khối của chương trình tương ứng với ầu vào "al"
và "2ƒ" lần lượt là A->B->C->F->B->C->E->G->D và
A->B->C->E->F->B->C->E->G->D Tương ứng, nếu tính độ phủ mã theo khối, độ phủ mã của
cả 2 đầu vào đều là (A, B, C, D, E, F, G) (toàn bộ), trong khi với độ phủ mã theo cạnh lần lượt là (AB, BC, CF, FB, BC, CE, EG, GD) và (AB, BC, CE,
EF, FB, BC, CE, EG, GD), ta có thể thấy sự khác biệt khi đầu vào "al" không
đi qua cạnh FB, trong khi đó đầu vào "21" không đi qua cạnh CF Từ đó thấy được độ phủ mã theo cạnh phân biệt được sử khác nhau trong luồng thực thi của 2 đầu vào, trong khi đó độ phủ mã theo khối thì không Điều này rất hữu
ích khi công cụ fuzzing muốn tìm các đầu vào "tốt" dựa trên luồng thực thi của
chương trình.
2.2.4 Các ki thuật lay độ phủ ma
Một trong những vấn đề quan trọng của fuzzing với độ phủ mã là trích xuất
được độ phủ mã khi chạy chương trình Việc trích xuất cần phải nhanh, ổn định
và phù hợp với ngữ cảnh sử dụng Để làm điều này, các công cụ fuzzing hiện
đại thường sử dụng 3 phương pháp chính, mỗi phương pháp đều có ưu và nhược
điểm khác nhau và được sử dụng trong các trường hợp khác nhau, các phương
pháp đó là:
1 Biên dịch lại chương trình: Phương pháp này liên quan đến việc biên
dịch lại mã nguồn của chương trình được fuzzing và chèn mã phụ
(instru-mentation code) vào để ghi lại độ phủ mã Các công cụ fuzzing có thể thiết
kế trình biên dịch đặc biệt được làm lại để thêm mã phụ để ghi lại các
phần mã được thực thi, hoặc sử dụng các phương pháp khác như tạo bản
đồ trạng thái (state map) để theo dõi độ phủ Khi tiến hành fuzzing, công
cụ chạy fuzzing với ứng dụng đã được biên dịch lại và tương tac với các mã
phụ được chèn vào để lấy độ phủ mã được ứng dụng ghi lại Đây là phương
Trang 32pháp mang tính ổn định và hiệu suất tốt nhất, nhưng có thể yêu cầu
thời gian, công sức và đặc biệt là yêu cầu mã nguồn để thực hiện.
Sử dụng cơ chế ảo hóa: Phương pháp này sử dụng việc tạo nên các môi trường fuzzing ảo dé theo déi và ghi lại các hoạt động của chương trình nhờ việc kiểm soát được nhân (kernel) của môi trường ảo Các công cụ fuzzing
có thể sử dung các phần mềm ảo hóa như QEMU, Unicorn, để dựng môi trường fuzzing ảo ghi lại thông tin về độ phủ mã khi chạy Ưu điểm của phương pháp này là tính linh hoạt cao (có thể kết hợp để fuzzing trên
các kiến trúc khác), tuy nhiên điểm yếu lớn nhất là tốc độ chạy chậm và
đòi hỏi kiến thức lớn để xử lí nếu gặp các lỗi trong quá trình dựng Đây là phương pháp có tốc độ chạy chậm nhất trong 3 phương pháp.
Sử dụng cơ chế móc (hook): Phương pháp này sử dụng các kĩ thuật móc
(hook) để tiến hành chèn các mã phụ (instrumentation code) vào chương
trình Phương pháp này tương tự phương pháp 1 nhưng khác là việc chèn
các mã phụ sẽ được thực hiện khi chạy chương trình, không phải khi biên
dịch Một trong các công cụ móc phổ biến được sử dụng là frida Day là một
phương pháp khá mới và được phát triển trong thời gian gần đây Một trong
các công cụ fuzzing phổ biến có hỗ trợ phương pháp này là AFLplusplus.
Đây được xem là phương pháp trung hòa giữa 2 phương pháp trên và được
sử dụng rất phổ biến nhờ tính tiện dụng Phương pháp này không cần mã nguồn để thực hiện biên dịch lại như phương pháp 1, tuy nhiên sẽ chạy chậm hơn phương pháp 1 và yêu cầu thời gian để chèn mã phụ vào đầu
mỗi lần chạy N6 chạy nhanh hơn phương pháp 2 do không cần phải
dựng môi trường ảo hóa, nhưng cũng đánh đổi bằng sự linh hoạt khi không
thể fuzz trên các kiến trúc khác với kiến trúc hệ thống Tuy nhiên do có tốc
độ tốt và không cần mã nguồn, nó trở thành phương pháp ưu tiên nhất đổi
với fuzzing hộp xám.
Trang 332.2.5 Các thông số so sứnh của fuzzing
Ở phần này chúng tôi giải thích về ý nghĩa các thông số quan trọng thường
được sử dụng để đánh giá fuzzing, bao gồm độ phủ mã, số đường đi, thời gian
thục thi, số lần thử, bảng theo dấu, số lượng hạt giống, độ sâu biến doi.
e Độ phủ ma (Coverage): Dây là số lượng phần mã mà các mau thử đã
đi đến thành công Do lường sự phủ sóng của các mau thử trong quá trình
fuzzing Đây là tham số quan trọng nhất trong đánh giá fuzzing hộp xám
dựa trên độ phủ mã Mục tiêu là tăng cường độ phủ sóng này để khám phá được nhiều lỗi tiềm an hơn.
e Số đường đi (Unique Path): Số lượng các đường đi (path) khác nhau
mà các mau thử đã đi qua Mỗi đường di đại diện cho một chuỗi các nhánh (edge) hoặc các điểm rẽ nhánh trong mã nguồn Đếm số lượng đường đi
giúp đánh giá khả năng khám phá các đường đi khác nhau của chương
trình.
e Thời gian thực thi (Time Execs): Thời gian đã trôi qua trong quá trình
fuzzing, được tính bằng đơn vị giây Dây là thời gian thực tế đã dành cho
việc thực thi các mầu thử và tìm kiếm lỗi.
e Số lần thử (Execs Done): Đây là số lần chương trình thực thi một mẫu
thử được tạo ra sau khi biến đổi đầu vào và lấy thông tin độ phủ mã về.
Thông số này phản ảnh tốc độ thực thi của công cụ fuzzing và đồng thời là
độ hiệu quả của cơ chế lấy độ phủ mã mà công cụ sử dụng.
e Bảng theo dấu (Trace Bits): Là một mảng, hoặc một chuỗi các byte/bit
được sử dụng để dánh dấu đường đi của chương trình, mục tiêu là để tính độ
phủ mã cũng như số đường đi của chương trình sau khi chạy Mỗi byte/bit có
thể tương ứng với một nhánh (edge), một dòng (line), một hàm (function)
hay một khối (block), tùy thuộc và cơ chế tính độ phủ mã mà công cụ sử
Trang 34dụng Mỗi khi mau thử đi qua một nhánh/dòng/hàm/khối, byte/bit trong
bảng theo dấu tương ứng sẽ được đánh dấu là 1, hoặc được cộng giá trị lên
1 Sau khi kết thúc, công cụ fuzzing sẽ sử dụng bảng theo dấu để tính toán
độ phủ mã và đường đi của mau thử.
e Số lượng hạt giống (Corpus Count): Số lượng các đầu vào hiện có trong
hàng chờ (seed queue), là các đầu vào sẽ được sử dụng để biến đổi tạo ra mau thử Day là một thông số để đếm số lượng mau thử được cho là "tốt"
và được đưa vào lại hàng chờ để tiếp tục biến đổi.
e Độ sâu biến đổi (Max Depth): Số lan biến đổi nhiều nhất để tạo ra
một mau thử trong chương trình, tức là đến thời điểm đang chạy, số lần tối
đa biến đổi đầu vào gốc (seed) để tạo ra các mau thử Day là một thống số dùng để đánh giá mức độ khó trong quá trình fuzzing, hay một phần nào
đó là độ hiêu quả của đầu vào gốc.
2.2.6 Shared memory va Semaphore
2.2.6.1 Shared memory
Shared memory (chia sé bộ nhớ) là kĩ thuật cho phép nhiều tiến trình hoặc luồng trong cùng hệ thống truy cập và chia sẻ cùng một vùng bộ nhớ Các tiến
trình chia sẻ một vùng nhớ vật lý thông qua trung gian không gian địa chỉ của
chúng Một vùng nhớ chia sé tồn tại độc lập với các tiến trình, và khi một tiến
trình muốn truy xuất đến vùng nhớ này, tiến trình phải kết gắn vùng nhớ chung
đó vào không gian địa chỉ riêng của từng tiến trình, và thao tác trên đó như một
vùng nhớ riêng của mình (hình 2.3) Việc sử dụng shared memory thường được
thực hiện thông qua các hàm và cấu trúc dữ liệu đặc biệt được cung cấp bởi các thư viện hệ điều hành như POSIX hoặc Windows API Kĩ thuật này giúp cho
các tiến trình trao đổi, chia sẻ thông tin rất nhanh chóng và hiệu quả do không
cần sao chép dữ liệu qua các phương tiện truyền thông khác như tệp tin hoặc socket Điều này giúp tăng hiệu suất và giảm thời gian truyền thông giữa các
Trang 35tiến trình và là công cụ quan trọng trong việc xây dựng các ứng dụng đa tiến
trình như máy chủ web, hệ thống đa luồng, các ứng dụng da tiến trình chia sé
tài nguyên và dữ liệu chung Tuy nhiên, việc sử dung shared memory cần kết
hợp thêm các cơ chế đồng bộ hóa để tránh các lỗi về xung đột xuất hiện khi có
nhiều hơn một tiến trình cùng thao tác dữ liệu.
Trong ngôn ngữ C, shared memory thường được tương tác thông qua các
hàm như shm_open (để tao shared memory), mmap (để gan vùng nhớ chia sẻ
vào không gian địa chỉ riêng của từng tiến trình) và shm_ unlink (để hủy shared
memor khi không sử dụng nữa).
Process 1 memory map Process 2 memory map
Trang 362.2.0.2 Semaphore
Semaphore là một cơ chế được sử dụng để quản lý và đồng bộ hóa truy cập vào tài nguyên chung giữa các tiến trình Semaphore giúp kiểm soát quyền truy cập và đồng bộ hóa các hoạt động của các tiến trình để đảm bảo tính nhất quán
và an toàn trong môi trường đa tiến trình.
Semaphore có hai loại chính là binary semaphore va counting semaphore.
Binary semaphore chỉ có hai trạng thai là 0 va 1, được sử dung dé kiểm soát
quyền truy cập duy nhất vào một tài nguyên Trang thái 0 của binary semaphore chỉ ra rằng tài nguyên đang được sử dụng và tiến trình khác phải chờ đợi Trạng
thái 1 chỉ ra rằng tài nguyên không được sử dụng và tiến trình có thể truy cập
vao no.
Counting semaphore là một bién nguyên không âm có giá trị ban dau được
thiết lập bởi người dùng Nó cho phép kiểm soát truy cập đồng thời của nhiều
tiến trình vào một tài nguyên bằng cách giới hạn số lượng tiến trình được phép
truy cập vào tài nguyên đó.
Trong ngôn ngữ C, semaphore được triển khai bằng cách sử dụng các hàm
như sem_ init, sem_ wait, sem_ post và sem_ destroy Ham sem_ init được sử
dụng dé khởi tao semaphore, ham sem_ wait giảm giá tri của semaphore va chờ
đến khi nó trở thành không âm, hàm sem_ post tăng giá trị của semaphore và
hàm sem_ destroy được sử dụng để huỷ semaphore khi không còn cần sử dụng
nữa.
Khi một tiến trình cần truy cập vào một tài nguyên chung được chia sẻ bởi
nhiều tiến trình hoặc luồng và được quản lí, đồng bộ hóa sử dụng semaphore,
các bước chung sẽ như sau:
1 Tiến trình cần truy cập tài nguyên gọi hàm sem_ wait đến semaphore dùng
để quản lí tài nguyên đó.
` : v2 ` 2 we 2 ⁄£ sự : VÀ
2 Hàm sem_ wait tiên hành kiêm tra giá tri của semaphore Nêu giá tri hiện
Trang 37tại của semaphore > 0, ham sem_ wait trừ semaphore di 1, kết thúc ham và cho phép truy cập vào tai nguyên Nếu giá trị hiện tai của semaphore <= 0, tức là số lượng tiến trình thao tác với tài nguyên đạt mức giới hạn quy định, hàm sem_ wait sẽ chờ đến khi giá trị semaphore > 0 và tiếp tục.
3 Khi tiến trình thao tác xong, tiến trình gọi hàm sem_ post để tăng giá trị
semaphore lên 1 và trả lại quyền thao tác trên tài nguyên đó cho các tiến
trình sau.
2.3 Mô hình học tăng cường
2.3.1 Quy trinh quyét định Markov (Markov Decision Process
-MDP)
Quy trinh quyét dinh Markov (MDP) dé cap dén quy trinh ra quyét dinh
ngẫu nhiên sử dung khuôn khổ toán học để mô hình hóa quá trình ra quyết định
của một hệ thống động Nó được sử dụng trong các tình huống trong đó kết quả
là ngẫu nhiên hoặc được kiểm soát bởi người ra quyết định, quyết định tuần tự
theo thời gian MDP đánh giá những hành động mà người ra quyết định nên
thực hiện khi xem xét trạng thái và môi trường hiện tại của hệ thống Hầu hết các bài toán trong học tăng cường được xây dựng trên MDP MDP gồm bốn thành phần, bao gồm M =< 9,A,P,R >, với:
e S: Không gian những trạng thái ma tac nhân quan sát được khi tương tac
với môi trường.
e A: Tập hợp các hành động mà tác nhân có thể thực hiện với môi trường.
e P: Hàm chuyển tiếp, đưa ra xác suất dự đoán một trạng thái có thể xảy
ra với đầu vào là một hành động được thực hiện và trạng thái hiện tại của
môi trường.
Trang 38e R: Hàm tính phần thưởng, xác định phần thưởng khi môi trường chuyển
tiếp từ một trạng thái sang trạng thái kế tiếp, dưới tác động của một hành
động.
2.3.2 Tổng quan mô hành học tăng cường
Học tăng cường là một nhánh nghiên cứu của học máy, trong đó sẽ có một
tác nhân tương tác trong một môi trường đưa ra các hành động nhằm mục tiêu cuối cùng là tối đa hóa phần thưởng tích lũy đạt được về lâu dài.
Dựa trên MDP, một hệ thống học tăng cường cơ bản, được mô tả trong hình
2.4 |9], sẽ có hai thành phần chính bao gồm Tác nhân (Agent) và Môi trường (Environment) tương tác với nhau thông qua các thành phần con là Hanh động
(Action), Trạng thái (State), Phần thưởng (Reward).
Cụ thể, tác nhân và môi trường tương tác với nhau qua mội chuỗi các bước
thời gian Tại mỗi bước thời gian t, tác nhãn sẽ chọn một hành động a(t) € A,
dựa vào một chính sách z(a()|s(#)) - là yếu tố xác định lựa chọn hành động của
tác nhân tại thời điểm nhất định - và nhận được một vectơ trạng thái s(t) từ
môi trường Đồng thời, môi trường tạo ra một phần thưởng r(t) € tương ứng
với hành động được thực hiện bởi tác nhân, đồng thời thay đổi trạng thái của
chính nó, chuyển sang một trạng thái mới s( + 1) Phần thưởng giúp xác định
Trang 39hành động nao được đưa ra là tốt hay xấu đối với tác nhân, đồng thời là cơ
sở để thay đổi, cập nhật chính sách để phù hợp Nêu hành động được chọn bởi chính sách đem lại phần thưởng thấp, chính sách sẽ được thay đổi và tác nhân
sẽ lựa chọn các hành động khác cho tình huống tương tự trong tương lai Từ phần thưởng r(t) và trạng thái s(t + 1) thu được, tác nhân sẽ cập nhật chính
sách z(ø|s(f + 1)) và lặp lại quá trình.
Vì không biết chính xác thời điểm kết thúc cả quá trình lặp này nên tổng các phần thưởng sẽ là một chuỗi vô cùng các phần thưởng tại các thời điểm t khác nhau kể từ thời điểm t đầu tiên:
S
R= Sor
¡=0
Do đó, ta cần phải thêm một yếu tố để tổng các phần thưởng này có thể hội tụ,
đó là + - giá tri chiết khấu (điscount factor) cho phần thưởng Giá trị này đánh giá giá trị phần thưởng tương lai so với phần thưởng hiện tại, ảnh hưởng đến quyết định hành động.
2.3.3 Van đề khai thác va khám phá trong học tăng cường
Một vấn đề quan trọng và là một thách thức nảy sinh trong học tăng cường
là sự đánh đổi giữa khám phá và khai thác (explore va exploit) Để có thể đạt
được nhiều phần thưởng nhằm tối đa hóa phần thưởng tích lũy, tác nhân phải
xem xét và lựa chọn những hành động trong quá khứ mà hiệu quả trong việc
Trang 40tạo phần thưởng Đây được gọi là khai thác - đưa ra quyết định dựa trên thông
tin sẵn có Tuy nhiên, để có được những lựa chọn như vậy đòi hỏi tác nhân phải thử những hành động ngẫu nhiên để khám phá được những trạng thái mới từ
những hành động không được lựa chọn trong quá trình khai thác Kết luận, tác
nhận phải lựa chọn những hành động đã trải qua để tối ưu hóa phần thưởng
nhận được, đồng thời phải thử những hành động chưa biết để khám phá và lựa
chọn những hành động tốt hơn trong tương lai.
2.3.4 Ham giá trị - hành động (Q-value Function)
Hàm giá trị - hành động (Q-value Function) là một khái niệm quan trọng
trong học tăng cường, đánh giá giá trị tương ứng cho mỗi cặp trạng thái hành
động, cụ thể là xác định giá trị của hành động a ở trạng thái s theo chính sách
z Hàm giá trị hành động có vai trò quan trọng trong quyết định hành động tối
ưu trong môi trường tương tác Nó cho phép đánh giá và so sánh các hành động
khác nhau dựa trên giá trị dự kiến của chúng Hàm giá trị - hành động được tính theo phương trình Bellman và nguyên tắc cập nhật Q-learning:
Q(5,8) = Q(s,a) + afr + ymax(Q(si41, 0441) — Q(s,)]
Trong đó:
a: là tỷ lệ hoc (learning rate), xác định mức độ ảnh hưởng của thông tin mới
so với thông tin đã học trước đó.
r: là phần thưởng nhận được sau khi thực hiện hành động a trong trạng thái
+: là giá trị chiết khấu (discount factor)
max(Q(st41, 4141)): là giá trị lớn nhất của ham giá trị hành động trong trạng
thái s¿¿¡ (trạng thái tiếp theo) khi thực hiện hành động tối ưu.
Qua quá trình huấn luyện, hàm giá trị hành động sẽ được cập nhật theo thời
gian để đạt được giá trị tối ưu cho mỗi cặp trạng thái-hành động, giúp áp dụng