Tải bản đầy đủ (.pdf) (12 trang)

môn kiểm thử xâm nhập báo cáo bài thực hành lỗ hổng buffer overflow

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.13 MB, 12 trang )

<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">

<b>HỌC VIỆN CƠNG NGHỆ BƯU CHÍNH VIỄN THƠNG KHOA AN TỒN THƠNG TIN </b>

<b>MƠN: KIỂM THỬ XÂM NHẬP BÁO CÁO BÀI THỰC HÀNH </b>

<b>Lỗ hổng Buffer Overflow </b>

Họ và tên sinh viên: Lưu Văn Hưng Mã số sinh viên: B20DCAT088 Lớp: D20CQAT04-B

Nhóm mơn học: Nhóm 04_D20

Họ và tên giảng viên: Đinh Trường Duy

Hà Nội 04/2024

</div><span class="text_page_counter">Trang 2</span><div class="page_container" data-page="2">

<b>Mục lục </b>

Bài thực hành: Lỗ hổng Buffer Overflow ... 3

I. Mục đích. ... 3

II. Yêu cầu đối với sinh viên:... 3

III. Nội dung thực hành ... 3

1. Chuẩn bị lab ... 3

2. Khởi động lab ... 3

3. Shellcode. ... 5

4. Chương trình độc hại. ... 6

5. Nhiệm vụ 1: Khai thác lỗ hổng bảo mật. ... 7

6. Nhiệm vụ 2: Ngẫu nhiên hóa địa chỉ. ...10

7. Nhiệm vụ 3: Stack Guard. ...11

8. Nhiệm vụ 4: Ngăn xếp không thực thi ...11

9. Kết thúc bài lab: Checkwork ...12

</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">

<b>Bài thực hành: Lỗ hổng Buffer Overflow </b>

• Tìm hiểu về Stack, Function, Buffer Overflow và các cơ chế bảo vệ của hệ thống.

<b>III. Nội dung thực hành </b>

<i><b>1. Chuẩn bị lab 2. Khởi động lab </b></i>

Chạy lệnh: labtainer -r bufoverflow trong terminal của Labtainer

• Kết quả trả về một bash shell. Các chương trình được mơ tả dưới đây sẽ nằm trong thư mục chính.

• Tắt các cơ chế bảo vệ có liên quan:

• Ngẫu nhiên hóa khơng gian địa chỉ. Một số hệ thống dựa trên Linux sử dụng ngẫu nhiên hóa khơng gian địa chỉ (ASLR) để 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 đốn các địa chỉ chính xác trở nên khó khăn; đốn địa chỉ là một trong những bước quan trọng

</div><span class="text_page_counter">Trang 4</span><div class="page_container" data-page="4">

của các cuộc tấn công tràn bộ đệm. Trong bài lab này, ta tắt các tính năng này bằng các lệnh sau:

<b>sudo sysctl -w kernel.randomize_va_space=0 </b>

• Trình bảo vệ StackGuard. Trình biên dịch GCC thực hiện một cơ chế bảo mật được gọi là "Stack Guard" để ngăn chặn lỗi tràn bộ đệm. Khi có biện pháp bảo vệ này, lỗi tràn bộ đệm sẽ không hoạt động. Ta có thể tắt tính năng bảo vệ này nếu biên dịch chương trình bằng cách sử dụng tùy chọn -fno-stack-protector. Ví dụ: để biên dịch một chương trình example.c với Stack Guard bị tắt, ta có thể sử dụng lệnh sau:

<b>gcc -m32 -fno-stack-protector example.c </b>

Tùy chọn -m32 được sử dụng để tạo các tệp thực thi 32 bit cho bài lab.

Ngăn xếp không thể thực thi (Non-Executable Stack). Ubuntu từng cho phép các ngăn xếp thực thi, nhưng điều này hiện đã thay đổi: mã nhị phân của chương trình (và thư viện được chia sẻ) phải khai báo xem chúng có yêu cầu ngăn xếp thực thi hay không, tức là cần đánh dấu một trường trong header chương trình. Kernel hoặc trình liên kết động sử dụng đánh dấu này để quyết định xem có nên làm cho ngăn xếp của chương trình đang chạy này có thể thực thi hay không. Việc đánh dấu này được thực hiện tự động trong các phiên bản gcc gần đây và theo mặc định, ngăn xếp được đặt là khơng thể thực thi. Để thay đổi điều đó, hãy sử dụng tùy chọn sau khi biên dịch chương trình:

</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5">

Đối với ngăn xếp thực thi:

<b>$ gcc -m32 -z execstack -o test test.c </b>

Đối với ngăn xếp không thực thi:

<b>$ gcc -m32 -z noexecstack -o test test.c </b>

<i><b> 3. Shellcode. </b></i>

Shellcode này chỉ là phiên bản hợp ngữ của chương trình trên. Chương trình sau đây chỉ ra cách khởi chạy một shell bằng cách thực thi một mã shell được lưu trữ trong bộ đệm. Hãy biên dịch để chạy đoạn mã sau và xem liệu một shell có được gọi hay không.

Lưu ý: Trong bài lab này, ta đã đặt lại chương trình bin/sh bằng một shell cũ hơn và khơng an tồn. Nó sẽ kế thừa các quyền setuid được gán với chương trình stack. Các shell hiện đại sẽ sử dụng uid thật của tiến trình làm id của chúng, do

</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">

đó, việc lấy root shell từ các chương trình setuid trở nên khó khăn hơn. Tuy nhiên, mã shell phức tạp hơn có thể chạy chương trình sau để chuyển id người dùng thực thành root. Bằng cách này, ta sẽ có một tiến trình root thực sự.

Biên dịch mã (đừng quên tùy chọn execstack):

<b>$ gcc -m32 -z execstack -o call_shellcode call_shellcode.c </b>

<i><b>4. Chương trình độc hại. </b></i>

</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7">

Biên dịch chương trình trên và chuyển quyền thành set-root-uid. Có thể thực hiện điều này bằng cách biên dịch chương trình với tài khoản root và chmod tệp thực thi thành 4755 (đừng quên bao gồm các tùy chọn execstack và -fno-stack-protector để tắt ngăn xếp không thực thi và bảo vệ StackGuard):

<i><b>5. Nhiệm vụ 1: Khai thác lỗ hổng bảo mật. </b></i>

Dưới đây là một mã khai thác đã hồn thành một phần có tên là “exploit.c”. Mục tiêu của đoạn mã này là xây dựng nội dung cho “badfile”. Trong mã này đã có mã shellcode. Sinh viên cần code phần cịn lại.

Tìm vị trí shellcode:

Giá trị của lea: 0x199 tương ứng 409 bytes.

</div><span class="text_page_counter">Trang 8</span><div class="page_container" data-page="8">

Giá trị của lea: 0x199 tương ứng 409 bytes.

int shell_offset = sizeof(buffer) – sizeof(shellcode); for(int i=0; i<sizeof(shellcode); i++)

</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">

Sau khi chúng ta hồn thành chương trình trên, biên dịch và chạy nó. Điều này sẽ tạo ra nội dung cho "badfile". Sau đó chạy ngăn xếp chương trình dễ bị tấn công.

</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">

<i><b>6. Nhiệm vụ 2: Ngẫu nhiên hóa địa chỉ. </b></i>

Bật ngẫu nhiên hố địa chỉ, ta có thể thấy sẽ mất rất nhiều thời gian và số lần thử để có thể có một cuộc tấn cơng thành cơng. Nếu may mắn ta sẽ vào được root #, nếu không, nhấn Ctrl + C để thoát.

<b>sudo /sbin/sysctl -w kernel.randomize_va_space=2 </b>

</div><span class="text_page_counter">Trang 11</span><div class="page_container" data-page="11">

<i><b>7. Nhiệm vụ 3: Stack Guard. </b></i>

Trước khi thực hiện nhiệm vụ này, hãy nhớ tắt ngẫu nhiên địa chỉ trước, nếu không bạn sẽ khơng biết phương pháp bảo vệ nào giúp có được sự bảo vệ.

Trong các nhiệm vụ trước đây, ta đã tắt cơ chế bảo vệ "Stack Guard" trong GCC khi biên dịch chương trình. Trong nhiệm vụ này, sinh viên có thể cân nhắc lặp lại nhiệm vụ 1 với sự hiện diện của Stack Guard. Để làm điều đó, nên biên dịch chương trình mà khơng có tùy chọn -fno-stack-protector. Đối với nhiệm vụ này, hãy biên dịch lại chương trình có lỗ hổng stack.c. Để sử dụng Stack Guard, thực hiện lại nhiệm vụ 1 và báo cáo các quan sát của mình. Sinh viên có thể báo cáo bất kỳ thông báo lỗi nào đã quan sát được.

Trong GCC 4.3.3 và các phiên bản mới hơn, Stack Guard được bật theo mặc định. Do đó, cần phải vơ hiệu hóa Stack Guard bằng cách sử dụng tùy chọn đã đề cập trước đó. Trong các phiên bản trước đó, nó đã bị tắt theo mặc định. Nếu sử dụng phiên bản GCC cũ hơn, có thể khơng phải tắt Stack Guard.

<i><b>8. Nhiệm vụ 4: Ngăn xếp không thực thi </b></i>

Bật tính năng bảo vệ ngăn xếp khơng thực thi.

</div><span class="text_page_counter">Trang 12</span><div class="page_container" data-page="12">

<i><b>9. Kết thúc bài lab: Checkwork </b></i>

</div>

×