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 35 - 42)

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 íilename 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 lưu trữ kết quả đầu ra trong tệp.)

Tiếp theo, chúng tôi đề cập đến tệp đầu ra thực thi này là giá trị của biến LD_PRELOAD. Điều này làm cho bất kỳ chương trình nào phải tải thư viện này trước khi thực thi chương trình.

3 5

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.

[11/04/21]seed@VM:—/.../task07$ cat mylib.c #include <stdio.h>

void sleep (int s){

printf("I am not sleepỉngXn" ) ;

}[11/04/21]seed@VM:—/..,/taskĐ7$ gcc -fPIC -g -c mylib. gcc: error: mylib..: No such file or directory

gcc: tatal error: no input files compilation terminated.

[11/04/21]seed@VM:—/.../task07$ gcc -fPIC -g -c mylib.c

[11/04/21]seed@VM:-/.../task07$ gcc -shared -o lỉbmylib

.so.1.0.1 mylib.o -lc

[11/04/21]seed@VM:~/.../task07$ subl myprogram.c

[11/04/21]sẹed@VM:—/.../task07$ export LD_PRELOAD=./lib

mylib.so.1.0.1

[11/04/21]seed@VM:~/.../task07$ I

[11/04/21]seed@VM:~/.../task07$ gcc myprogram.c -0 mypr

ogcompiled

myprogram.c: In tunction 'main':

myprogram.c:2:2: warnỉng: implicit declaration of tunct

ion 'sleep' [-Wimplicit-function-declaration] sleep{1);

myprogram.c:3:2: warnỉng: implicit declaration of tunct

ion 'System' [-Wimplicit-function-declaration]

systẽm("env I grep LD");

[11/04/21]seed@VM:-/.../task07$ ./myprogcompiled

I am not sleeping

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

3 6

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ó.

[11/04/21]seed@VM:~/.../task07$ gcc myprogram.c -0 mypr

ogcompiled

myprogram.c: In tunction 'main':

myprogram.c:2:2: warnỉng: implicit declaration of tunct ion 'sleep' [-Wimplicit-function-declaration]

sleep(1);

A

myprogram.c:3:2: warnỉng: implicit declaration of tunct ion 'System' [-Wimplicit-function-declaration]

systẽm("env I grep LD");

A

[11/04/21]seed@VM:~/.../task07$ ./myprogcompiled

I am not sleeping

LD PRELOAD=./libmylib.so.1.0.1

LD_LIBRARY_PATH=/home/seed/sou rce/boost_l_64_0/stage/li

b:/home/seed/sou rce/boost_l 64 o/stage/lib:

OLDPWD=/home/seed/Documents/task07

Trường hợp 2: Ta đặt chương trình này thành chương trình root SET-UID và cho chương trình chạy lại. Output cho thấy rằng thư viện chứa hàm sleep() của chương trình không được gọi và cũng cho thấy rằng biến môi trường của quá trình đó không chứa biến

3 7

LD_PRELOAD. Điều này cho thấy rằng tiến trinh con SET-UID đã được tạo không kế

3 8

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().

[ 11/05/21 ] seed(3VM:-/.../task7$ sudo chown root myprogco mpiled

[11/05/21]seed@VM:~/.../task7$ sudo chmod 4755 myprogco mpiled

[11/05/21]seed@VM:~/.../task7$ 11 myprogcompiled -rwsr-xr-x 1 root seed 7388 Nov 5 08:05 myprogcompiled [11/05/21]seed@VM:~/.../task7$ ./myprogcompiled ‘,0LDPWD=/home/seed/Documents/task7

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ỏ.

[11/05/21]seed@VM:~/.../task7$ sudo su - root<aVM:~# Is

root<aVM:—# cd /home/seed/Documents/task7/ root<aVM: / home/seed/Documents/task7# Is

1ibmylib.so.1.0.1 mylib.o myprogram.c

mylib.c myprogcompiled

rootcaVM:/home/seed/Documents/task7# export LD PRELOAD=. /Libmylib.so.1.0.1

root<aVM:/home/seed/Documents/task7# ./myp rogcompiled I am not sleeping!

LD_PREL0AD=./libmylib.so.1.0.1

OLDPWD=/home/seed/Documents/task7

LD LIBRARY_PATH=/home/seed/sou rce/boost_l_64 O/stage/Li b:/home/seed/sou rce/boost_l_64_0/stage/lib:

root<aVM:/home/seed/Documents/task7# 11 myprogcompiled -rwsr-xr-x 1 root seed 7388 Nov 5 08:05 myprogcompiled

*

3 9

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.

[11/05/21]seedgVM:~/.../task7$ sudo adduser quochoang Adding User 'quochoang' ...

Adding new group 'quochoang' (1001) ...

Adding new User 'quochoang' (1001) with group 'quochoan g ■ . . .

Creating home directory '/home/quochoang■ ... Copying files from '/etc/skel' ...

Entẽr new UNIX password: Retype new UNIX password:

passwd: password updated successtully Changing the User intormation for quochoang Enter the new value, or press ENTER for the detautt

Full Name []: test quochoang Room Number [] :

Work Phone [] : Home Phone ĩ] : othe r [] :

Is the intormation correct? [Y/n] Y

Trường hợp 4: Ta tiến hành tạo một bản sao myprocompiled1 của myprogcompiled để hạn chế nhầm lẫn.

Tiếp theo, ta đặt chủ sở hữu của tệp này là quochoang (một tài khoản người dùng khác không phải root) và đặt nó thành chương trình SET-UID. Sau đó, ta đăng nhập vào tài khoản user quochoang và đặt lại biến LD_PRELOAD. Khi chạy lại chương trình, chúng ta thấy rằng hàm sleep() do người user định nghĩa được gọi và biến LD_PRELOAD cũng có trong tiến trình hiện tại.

-rwxrwxr- X 1 seed seed 7928 Nov 5 08:02 'LỉbmyHb . so . 1.

u ■ X

- rw - rw - r - -

1 seed seed 7 3

Nov 5 08:01 mylib.c - rw - rw - r - - 1 seed seed 2588 Nov 5 08 : 02 mylib.o

-rwxr- X r- X 1 seed seed 7388 Nov 5 08:48 myprocompiled1

-rwsr-X r-X 1 root seed 7388 Nov 5 08:05 myprogcompiled

- rw - rw - r - - 1 seed seed 8 2

Nov 5 08:05 mỹp rog ram.c [11/05/21]seed(8VM:~/.../task7$ cp myprogcompiled myproc

ompiled1

[11/05/21]seed@VM:~/.../task7$ Is -1 total 36

[11/05/21]seedộVM:-/.../task7$ sudo chown quochoang myp rocompiledl

[11/05/21]seed@VM:-/.../task7$ sudo chmod 4755 myprocom piledl

[11/05/21]seedộVM:-/.../task7$ Is -1 total 36

-rwxrwxr- X 1 seed seed 7928 Nov 5 08 : 02 libmylib.

so.1.0.1

- rw - rw - r - - 1 seed seed 73 Nov 5 08:01 mylỉb.c - rw - rw - r - - 1 seed seed 2588 Nov 5 08:02 mylib.o - rwsr-xr-x 1 quochoang seed 7388 Nov 5 08:48 mỹp rocomp

4 0

mgg>VM: /home/seed/Documents/task7 ÍT! £ M>)) 8:59 AM <í>

[ 11/05/21 ] seedcaVM: ~/.../task7$ su quochoang Passwo rd:

quochoang@VM:/home/seed/Documents/task7$ export LDPREL

ÓAD=./libmylib.so.1.0.1

quochoang@VM:/home/seed/Documents/task7$ env I grep LD

LD_PRELOAD=./libmylib.so.1.0.1

LD_LIBRARY_PATH=/home/seed/source/boost_l_64_0/stage/li

b:/home/seed/sou rce/boost_l_64_0/stage/lib:

quochoang@VM:/home/seed/Documents/task7$ Is -l myprocom

piledl

-rwsr-xr-x 1 quochoang seed 7388 Nov 5 08:48 myprocomp iledl

quochoang@VM:/home/seed/Documents/task7$ ./myprocompile

dl I am not sleeping! LD PRELOAD=./libmylib.so.1.0.1 LD LIBRARY PATH=/home/seed/source/boost_l_64_0/stage/li b:/home/seed/sou rce/boost_l_64_0/stage/lib: 0LDPWD=/home/seed/Documents/task7

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.

ịi ® ỂỈ I0 1 O UI 4 1

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 35 - 42)

Tải bản đầy đủ (DOCX)

(50 trang)
w