Lab2. Buffer Overflows – Nguyễn Việt Hoàng | Báo cáo Môn an toàn thông tin Trường đại học sư phạm kỹ thuật TP. Hồ Chí Minh
Lệnh sudo sysctl –w kernel.randomize_va_space=0 là lệnh tắt tính năng Address Space Layout
Randomization (ASLR) trên hệ thống Linux. ASLR là một kỹ thuật bảo mật làm cho việc khai
thác các lỗ hổng phần mềm trở nên khó khăn hơn bằng cách sắp xếp ngẫu nhiên địa chỉ của các
khu vực dữ liệu quan trọng trong bộ nhớ của một quá trình. Tài liệu giúp bạn tham khảo, ôn tập và đạt kết quả cao. Mời bạn đọc đón xem!
Môn: An toàn thông tin (INSE330380)
Trường: Đại học Sư phạm Kỹ thuật Thành phố Hồ Chí Minh
Thông tin:
Tác giả:
Preview text:
Sinh viên: Nguyễn Việt Hoàng MSSV: 21110884 Lab2. Buffer Overflows Step 0. Preparation - Ubuntu 16.04 (32-bit) -
Source code: stack.c, exploit.c/exploit.py
Step 1. Disable address randomization
$sudo sysctl –w kernel.randomize_va_space=0
- Lệnh sudo sysctl –w kernel.randomize_va_space=0 là lệnh tắt tính năng Address Space Layout
Randomization (ASLR) trên hệ thống Linux. ASLR là một kỹ thuật bảo mật làm cho việc khai
thác các lỗ hổng phần mềm trở nên khó khăn hơn bằng cách sắp xếp ngẫu nhiên địa chỉ của các
khu vực dữ liệu quan trọng trong bộ nhớ của một quá trình. - Giải thích chi tiết:
+ sudo: Chạy lệnh với quyền root.
+ sysctl: Công cụ quản lý hệ thống được sử dụng để đọc và ghi các giá trị cấu hình hệ thống. + –w: Chế độ ghi.
+ kernel.randomize_va_space: Tên của biến cấu hình hệ thống kiểm soát ASLR.
+ 0: Giá trị của biến cấu hình hệ thống để tắt ASLR.
Step 2. Finding the address of the inject code
$gcc –z execstack –fno-stack-protector –g –o stack_dbg stack.c
gcc là tên của trình biên dịch GCC.
-z execstack là tùy chọn để bật khả năng thực thi ngăn xếp (stack execution).
-fno-stack-protector là tùy chọn để tắt bộ bảo vệ ngăn xếp (stack protector).
-g là tùy chọn để tạo ra tệp thực thi có thể gỡ lỗi.
-o stack_dbg là tùy chọn để đặt tên cho tệp thực thi là stack_dbg.
stack.c là tệp mã nguồn của chương trình. $touch badfile
touch là lệnh để tạo một tệp trống.
badfile là tên của tệp trống. $gdb stack_dbg
gdb là tên của trình gỡ lỗi GDB.
stack_dbg là tên của tệp thực thi. (gdb)b bof
b là lệnh để đặt điểm dừng (breakpoint) tại hàm bof(). (gdb)run
run là lệnh để chạy chương trình. (gdb)p $ebp
p là lệnh để in giá trị của biến $ebp.
$ebp là tên của biến trỏ khung ngăn xếp (stack frame pointer). ebp 0xbfffeab8 (gdb)p &buffer
p là lệnh để in giá trị của biến &buffer.
&buffer là một con trỏ đến một vùng đệm có kích thước 100 byte. buffer 0xbfffea4c (gdb)p 0xbfffeab8 - 0xbfffea4c
p là lệnh để in giá trị của biến &buffer.
Tính khoảng cách 2 địa chỉ $3 = 108
Return address = ebp + (108 + 4) = ebp + 112
- Các lệnh này được sử dụng để gỡ lỗi chương trình stack.c có lỗ hổng tràn ngăn xếp (stack overflow).
- Lỗ hổng tràn ngăn xếp xảy ra khi một chương trình ghi nhiều dữ liệu vào một vùng nhớ hơn
kích thước của vùng đó. Dữ liệu tràn có thể ghi đè lên các biến khác trên ngăn xếp, bao gồm cả
địa chỉ trả về (return address) của hàm. Khi hàm trả về, chương trình sẽ thực thi mã tại địa chỉ
trả về đã bị ghi đè, dẫn đến việc thực thi mã độc hại.
- Để gỡ lỗi lỗ hổng tràn ngăn xếp, chúng ta có thể sử dụng GDB để đặt điểm dừng tại hàm bof(),
nơi xảy ra lỗ hổng. Sau đó, chúng ta có thể in giá trị của biến $ebp để xác định vị trí của ngăn xếp.
- Nếu lỗ hổng tràn ngăn xếp xảy ra, chúng ta sẽ thấy rằng giá trị của $ebp đã bị thay đổi. Chúng ta
có thể sử dụng thông tin này để tìm hiểu thêm về cách thức hoạt động của lỗ hổng và viết mã khai thác lỗ hổng đó Step 3. Edit exploit.c
*((long *) (buffer + 112)) = 0xbfffeab8 0x80 – ;
memcpy(buffer + sizeof(buffer) – sizeof(shellcode), shellcode, sizeof(shellcode)); Step 4. Execute $ sudo ln -sf /bin/zsh /bin/sh
- Lệnh sudo ln -sf /bin/zsh /bin/sh là một lệnh trong hệ điều hành Linux và macOS. Nó được sử
dụng để tạo một liên kết mềm (soft link) từ tệp /bin/sh sang tệp /bin/zsh. Một liên kết mềm là
một tệp đặc biệt có chứa một đường dẫn đến một tệp khác. Khi một liên kết mềm được truy cập,
trình liên kết sẽ tìm kiếm tệp được liên kết và thực thi nó.
- Lệnh sudo ln -sf /bin/zsh /bin/sh sẽ tạo một liên kết mềm từ tệp /bin/sh sang tệp /bin/zsh. Điều
này có nghĩa là khi bạn chạy lệnh sh, bạn sẽ thực thi tệp zsh thay vì tệp sh gốc. - Giải thích chi tiết:
+ sudo: Là từ khóa chỉ định rằng bạn cần quyền root để thực thi lệnh này.
+ ln: Là lệnh được sử dụng để tạo một liên kết.
+ -s: Là tùy chọn chỉ định rằng bạn muốn tạo một liên kết mềm.
+ f: Là tùy chọn chỉ định rằng bạn muốn tạo liên kết ngay cả khi tệp đích đã tồn tại.
+ /bin/zsh: Là đường dẫn đến tệp zsh.
+ /bin/sh: Là đường dẫn đến tệp sh
$ gcc -DBUF_SIZE=100 -o stack -z execstack -fno-stack-protector stack.c
- Lệnh gcc -DBUF_SIZE=100 -o stack -z execstack -fno-stack-protector stack.c được sử dụng để
biên dịch chương trình C stack.c thành tệp thực thi stack với stack có thể thực thi và không có bộ bảo vệ stack. - Giải thích chi tiết:
+ -D: Định nghĩa một macro có tên BUF_SIZE với giá trị là 100.
+ -o: Chỉ định tên của tệp thực thi được tạo ra là stack.
+ -z execstack: Chỉ thị trình biên dịch tạo ra tệp thực thi với ngăn xếp có thể thực thi (executable stack).
+ -fno-stack-protector: Chỉ thị trình biên dịch không sử dụng bộ bảo vệ ngăn xếp (stack protector). $ sudo chown root stack
- Lệnh sudo chown root stack là một lệnh trong hệ điều hành Linux và macOS. Nó được sử dụng
để thay đổi quyền sở hữu của tệp hoặc thư mục stack thành người dùng root. Lệnh sudo chown
root stack sẽ thay đổi quyền sở hữu của tệp stack thành người dùng root. Điều này có nghĩa là
người dùng root sẽ có quyền truy cập đầy đủ vào tệp stack, bao gồm cả quyền ghi. - Giải thích chi tiết:
+ sudo: Là từ khóa chỉ định rằng bạn cần quyền root để thực thi lệnh này.
+ chown: Là lệnh được sử dụng để thay đổi quyền sở hữu của một tệp hoặc thư mục.
+ root: Là tên của người dùng mà bạn muốn thay đổi quyền sở hữu.
+ stack: Là đường dẫn đến tệp hoặc thư mục mà bạn muốn thay đổi quyền sở hữu. $ sudo chmod 4755 stack
- Lệnh sudo chmod 4755 stack là một lệnh trong hệ điều hành Linux và macOS. Nó được sử dụng
để thay đổi quyền của tệp stack. Lệnh sudo chmod 4755 stack sẽ thay đổi quyền của tệp stack thành:
+ Người dùng sở hữu tệp có quyền đọc, ghi và thực thi.
+ Nhóm sở hữu tệp có quyền đọc và thực thi.
+ Mọi người khác có quyền đọc và thực thi. - Giải thích chi tiết:
+ sudo: Là từ khóa chỉ định rằng bạn cần quyền root để thực thi lệnh này.
+ chmod: Là lệnh được sử dụng để thay đổi quyền của một tệp hoặc thư mục.
+ 4755: Là mã quyền được sử dụng để thay đổi quyền của tệp stack.
+ stack: Là đường dẫn đến tệp mà bạn muốn thay đổi quyền. $ gcc -o exploit exploit.c
- Lệnh gcc -o exploit exploit.c là một lệnh trong hệ điều hành Linux và macOS. Nó được sử dụng
để biên dịch mã C trong tệp exploit.c thành tệp thực thi có tên exploit - Giải thích chi tiết:
+ gcc: Là lệnh được sử dụng để biên dịch mã C.
+ -o: Chỉ định tên của tệp thực thi được tạo ra.
+ exploit: Là tên của tệp thực thi được tạo ra.
+ exploit.c: Là đường dẫn đến tệp mã C cần được biên dịch. $./exploit
- Thực thi tệp exploit, tạo ra badfile $./stack
- Thực thi tệp stack, chạy chương trình lỗ hổng
Step 5. Defeating Address Randomization (ASLR)
$sudo sysctl –w kernel.randomize_va_space=2
- Lệnh sudo sysctl –w kernel.randomize_va_space=2 là lệnh bật tính năng Address Space Layout
Randomization (ASLR) trên hệ thống Linux. ASLR là một kỹ thuật bảo mật làm cho việc khai
thác các lỗ hổng phần mềm trở nên khó khăn hơn bằng cách sắp xếp ngẫu nhiên địa chỉ của các
khu vực dữ liệu quan trọng trong bộ nhớ của một quá trình. - Giải thích chi tiết:
+ sudo: Chạy lệnh với quyền root.
+ sysctl: Công cụ quản lý hệ thống được sử dụng để đọc và ghi các giá trị cấu hình hệ thống. + –w: Chế độ ghi.
+ kernel.randomize_va_space: Tên của biến cấu hình hệ thống kiểm soát ASLR.
+ 2: Giá trị của biến cấu hình hệ thống để bật ASLR.
Step 6. Turn on the StackGuard Protection
- Để bật bảo vệ StackGuard, chúng ta cần biên dịch lại chương trình mà không có tùy chọn -fno-
stack-protector. Bảo vệ StackGuard là một tính năng bảo mật được cung cấp bởi trình biên dịch
GCC. Tính năng này giúp ngăn chặn các cuộc tấn công tràn ngăn xếp bằng cách thêm một số
kiểm tra bổ sung vào chương trình.
- Khi bạn biên dịch lại chương trình mà không có tùy chọn -fno-stack-protector, chương trình sẽ
được bảo vệ khỏi các cuộc tấn công tràn ngăn xếp. Và cho kết quả như hình bên dưới
Step 7. Turn on the Non-executable Stack Protection
$ gcc -o stack -fno-stack-protector -z noexecstack stack.c
- Để bật bảo vệ ngăn xếp không thực thi, chúng ta cần biên dịch lại chương trình sử dụng tùy
chọn -z noexecstack. Lệnh này sẽ biên dịch chương trình C stack.c thành tệp thực thi stack sử dụng tùy chọn -z noexecstack.
- Bảo vệ ngăn xếp không thực thi là một tính năng bảo mật được cung cấp bởi hệ điều hành. Tính
năng này giúp ngăn chặn các cuộc tấn công chèn mã bằng cách ngăn chặn việc ghi mã vào ngăn
xếp. Khi bạn biên dịch lại chương trình sử dụng tùy chọn -z noexecstack, ngăn xếp sẽ được đặt
thành chế độ chỉ đọc. Điều này có nghĩa là mã không thể được ghi vào ngăn xếp.
- Giải thích chi tiết về lệnh biên dịch:
+ gcc: Là lệnh được sử dụng để biên dịch mã C.
+ -o: Chỉ định tên của tệp thực thi được tạo ra.
+ stack: Là tên của tệp thực thi được tạo ra.
+ -fno-stack-protector: Tắt bảo vệ StackGuard.
+ -z noexecstack: Bật bảo vệ ngăn xếp không thực thi.
+ stack.c: Là đường dẫn đến tệp mã C cần được biên dịch.
- Khi chạy lệnh gcc -o stack -fno-stack-protector -z noexecstack stack.c, trình biên dịch GCC sẽ
biên dịch mã C trong tệp stack.c thành tệp thực thi có tên stack. Tệp thực thi stack sẽ được bảo
vệ khỏi các cuộc tấn công chèn mã.