Task 7: The LD_PRELOAD environmentvariable and Set-UID Programs

Một phần của tài liệu THỰC tập cơ sở CHUYÊN NGHÀNH AN TOÀN PHẦN mềm NGHIÊN cứu ENVIROMENT VARIABLE AND SET UID (ENVIROMENT VARIABLE AND SET UID LAB) (Trang 32 - 38)

Programs

Trong task này, chúng tôi nghiên cứu cách các chương trình Set-UID đối phóó́ với một số biến môi trường. Một số biến môi trường, bao gồm LD_PRELOAD, LD_LIBRARY PATH và LD_* khác ảnh hưởng đến hành vi của trình liên kết động. Trình liên kết động là một phần của hệ điều hành (OS) tải (liên tục từ bộ nhớ lưu trữ đến RAM) và liên kết các thư viện được chia sẻ cần thiết bởi một tệp thực thi tại thời điểm chạy.

Trong Linux, ld.so hoặc ld-linux.so, là trình liên kết động (mỗi loại cho các kiểu nhị phân khác nhau). Trong Linux, LD_LIBRARY PATH là một tập hợp các thư mục được phân tách bằng dấu hai chấm, nơi các thư viện sẽ được tìm kiếm đầu tiên, trước tập thư mục tiêu chuẩn. LD_PRELOAD chỉ định danh sách các thư viện được chia sẻ bổ sung, do người dùng chỉ định, sẽ được tải trước tất cả các thư viện khác. Trong task này, chúng ta sẽ chỉ nghiên cứu LD PRELOAD.

Đầu tiên, ta sẽ xây dựng một thư viện liên kết động. Trước hết, tạo một chương trình cóó́ tên mylib.c, nóó́ cóó́ chức năng đơn giản là ghi đè hàm function sleep() vào libc của hệ thống. Thực hiện biên dịch và chạy chương trình trên bằng các lệnh.

gcc -fPIC - g -c mylib.c (trong đóó́ -fPIC cóó́ nghĩa là phát ra mã độc lập về vị trí, thích hợp cho liên kết động và tránh bất kỳ giới hạn nào về kích thước của bảng bù toàn cục, -g cóó́ nghĩa là tạo ra thông tin gỡ lỗi và -c cóó́ nghĩa là biên dịch tệp nhưng không liên kết).

Bảng bù đắp toàn cục, hoặc GOT( Global Offset Table), là một phần của bộ nhớ chương trình máy tính được sử dụng để cho phép mã chương trình máy tính được biên dịch dưới dạng tệp ELF để chạy chính xác, không phụ thuộc vào địa chỉ bộ nhớ nơi mã hoặc dữ liệu của chương trình được tải trong thời gian chạy.

gcc -shared -o filename mylib.o -lc (trong đóó́ -shared tạo ra một đối tượng được chia sẻ cóó́ thể được liên kết với các đối tượng khác để tạo thành một tệp thực thi, -o tệp

Sau đóó́, ở cùng thư mục task7 này tạo ra một chương trình gọi hàm sleep(), biên dịch và thực thi chương trình ấy. Và khi ta thực thi chương trình này với một user thường, ta cóó́ thể thấy chương trình gọi hàm sleep() được định nghĩa bởi chương trình này myprogcompiled và in ra dòng chữ mà ta đã code trong chương trình.

Khi chạy cùng một chương trình trong các tình huống khác nhau như được chỉ định trong tài liệu, ta nhận thấy rằng trong một số tình huống nhất định, thư viện chứa

hàm sleep() của ta không được gọi và thay vào đóó́, hàm sleep() do hệ thống xác định đã được thực thi. Để hiểu được hành vi này, ta cần chỉnh sửa chương trình của mình và thêm một lệnh gọi hệ thống để thực thi env | grep LD để xem các biến môi trường của quy trình. Như ta đã đề cập đến grep LD vì cách duy nhất mà bất kỳ chương trình nào tải thư viện đã xác định của tôi cũng thực thi hàm sleep() là bằng biến môi trường LD_PRELOAD. Chương trình myprogram.c được chỉnh sửa như sau.

Trường hợp 1: Sau khi đã tiến hành chỉnh sửa thêm lệnh system(“env | grep

LD”); ta tiến hành biên dịch và thực thi lại chương trình cũng là bằng user thường. Lúc này output của chương trình lần này là dòng in ra hàm sleep() và các biến môi trường của chương trình chứa chuỗi “LD”. Như ta đã thấy, tiến trình này sử dụng LD_PRELOAD như một trong những biến môi trường của nóó́.

thừa biến LD_PRELOAD và do đóó́ nóó́ không tải thư viện và hàm sleep() do hệ thống xác định khi chương trình sleep().

Trường hợp 3: Vì chương trình đã là chương trình SET-UID root, ta chỉ cần đăng

nhập vào tài khoản user root và xác định biến LD_PRELOAD. Khi chạy chương trình, ta thấy rằng function sleep() do người dùng định nghĩa được thực thi và biến LD_PRELOAD hiện diện. Điều này xảy ra bởi vì ta đang ở trong tài khoản root và chủ sở hữu của function cũng là root. Điều này làm cho quá trình cóó́ cùng real ID và effective ID, do đóó́ biến LD_PRELOAD không bị loại bỏ.

Tiếp theo, ta tạo một tài khoản user mới quochoang dựa trên tài khoản root.

Trường hợp 4: Ta tiến hành tạo một bản sao myprocompiled1 của

Hành vi này chỉ ra rằng biến LD_PRELOAD hiện diện nếu real ID và effective ID giống nhau và bị loại bỏ nếu chúng khác nhau. Điều này là do cơ chế bảo mật của chương trình SET-UID. Trong trường hợp đầu tiên, thứ ba và thứ tư, vì chủ sở hữu và tài khoản user thực thi tệp là giống nhau, biến LD_PRELOAD luôn cóó́ mặt và thư viện do người dùng xác định được tải trước. Trong khi đóó́, trong trường hợp thứ hai, effective ID là của user root và real ID là của user seed, biến LD_PRELOAD bị loại bỏ và thay vào đóó́ thư viện liên kết động lib.c, hàm sleep() do hệ thống xác định sẽ được gọi, đây là biện pháp đối phóó́ của hệ thống UNIX đối với các cuộc tấn công.

Một phần của tài liệu THỰC tập cơ sở CHUYÊN NGHÀNH AN TOÀN PHẦN mềm NGHIÊN cứu ENVIROMENT VARIABLE AND SET UID (ENVIROMENT VARIABLE AND SET UID LAB) (Trang 32 - 38)