Linux SUID, SGID và Sticky Bit: Nắm Vững Quyền Đặc Biệt để Bảo Mật Hệ Thống

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Bắt Đầu Nhanh: Phát Hiện và Thiết Lập Quyền Đặc Biệt trong 5 Phút

Bạn đang duyệt một thư mục bằng ls -l và nhận thấy điều gì đó bất thường — một chữ s ở chỗ thường là x, hoặc một chữ t xuất hiện cuối chuỗi quyền. Đây là các bit quyền đặc biệt của Linux: SUID, SGID và Sticky Bit. Hầu hết sysadmin đều nhận ra các ký hiệu này. Nhưng rất ít người thực sự hiểu điều gì xảy ra bên dưới khi những bit đó được kích hoạt.

Đây là cách tìm chúng ngay lập tức:

# SUID — chú ý chữ 's' ở vị trí execute của owner
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 Apr 16  2024 /usr/bin/passwd

# Tìm tất cả file SUID trên hệ thống
find / -perm -4000 -type f 2>/dev/null

# Tìm tất cả file SGID
find / -perm -2000 -type f 2>/dev/null

# Tìm thư mục có Sticky Bit
find / -perm -1000 -type d 2>/dev/null

Các giá trị số rất đơn giản:

  • SUID = 4 — thêm vào trước quyền, ví dụ chmod 4755
  • SGID = 2 — ví dụ chmod 2755
  • Sticky Bit = 1 — ví dụ chmod 1777

Ký hiệu symbolic cũng hoạt động tương tự:

# Đặt SUID cho file thực thi
chmod u+s /path/to/binary

# Đặt SGID cho thư mục dùng chung
chmod g+s /shared/project

# Đặt Sticky Bit cho thư mục có thể ghi
chmod +t /shared/uploads

Tìm Hiểu Sâu: Từng Bit Thực Sự Hoạt Động Như Thế Nào

SUID — Tạm Thời Trở Thành Chủ Sở Hữu File

Đây là bài toán kinh điển: một người dùng thông thường có thể chạy passwd và đổi mật khẩu, nhưng /etc/shadow lại thuộc sở hữu của root và không ai khác đọc được. Vậy điều đó hoạt động như thế nào?

ls -l /etc/shadow
# ---------- 1 root shadow 1234 Jun  1 10:00 /etc/shadow

ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 Apr 16 2024 /usr/bin/passwd

Chữ s ở vị trí execute của owner trong passwd chính là SUID. Khi binary này chạy, kernel tạm thời đặt effective UID của process thành chủ sở hữu file — trong trường hợp này là root — thay vì UID của người dùng đang gọi. Chương trình chạy với quyền nâng cao trong suốt thời gian thực thi. Khi thoát, những quyền đó biến mất.

Về bảo mật: mỗi binary SUID root đều là mục tiêu leo thang đặc quyền tiềm năng. Chỉ cần một lỗi có thể khai thác — buffer overflow, path injection — và kẻ tấn công sẽ có được root shell. Hãy giữ danh sách SUID trên production càng ngắn càng tốt, và biết chính xác lý do mỗi entry có mặt ở đó.

SGID — Kế Thừa Group Thực Sự Giải Quyết Vấn Đề Nhóm

SGID hoạt động khác nhau tùy thuộc vào việc nó nhắm vào file hay thư mục.

Trên file thực thi: Cùng khái niệm với SUID, nhưng dùng group của file thay vì owner. GID hiệu lực của process trở thành group của file.

ls -l /usr/bin/write
# -rwxr-sr-x 1 root tty 14328 Jan 20 2024 /usr/bin/write
# 's' ở vị trí execute của group = SGID

Trên thư mục: Trường hợp thư mục mới là lúc SGID thực sự có giá trị trong triển khai thực tế. Mọi file được tạo bên trong thư mục SGID sẽ tự động kế thừa group của thư mục, bất kể primary group của người tạo là gì.

# Tạo thư mục project dùng chung cho nhóm devteam
sudo groupadd devteam
sudo mkdir /projects/webapp
sudo chown :devteam /projects/webapp
sudo chmod 2775 /projects/webapp

ls -ld /projects/webapp
# drwxrwsr-x 2 root devteam 4096 Jun  2 09:00 /projects/webapp

# Mọi file tạo ở đây sẽ tự động thuộc devteam
touch /projects/webapp/app.py
ls -l /projects/webapp/app.py
# -rw-rw-r-- 1 youruser devteam 0 Jun  2 09:01 app.py

Nếu không có SGID, mỗi developer tạo file với primary group của riêng họ. Không ai khác có thể ghi vào mà không cần chạy chmod thủ công sau mỗi lần tạo file. SGID trên thư mục loại bỏ hoàn toàn sự bất tiện đó.

Sticky Bit — Bảo Vệ Thư Mục Ghi Chung

Vấn đề mà Sticky Bit giải quyết: nếu /tmp có thể ghi bởi mọi người (điều đó là bắt buộc), thì điều gì ngăn user bob xóa file tạm của alice?

ls -ld /tmp
# drwxrwxrwt 18 root root 4096 Jun  2 09:30 /tmp
# Chữ 't' ở cuối — Sticky Bit

Khi Sticky Bit được đặt, quyền ghi vào thư mục không còn đồng nghĩa với việc bạn có thể xóa file của người khác. Chỉ có chủ sở hữu file, chủ sở hữu thư mục hoặc root mới có thể xóa file trong thư mục đó.

# alice tạo một file tạm
touch /tmp/alice_session.sock

# bob cố xóa file đó — bị từ chối
rm /tmp/alice_session.sock
# rm: cannot remove '/tmp/alice_session.sock': Operation not permitted

Sử Dụng Nâng Cao: Các Kịch Bản Production Thực Tế

Kết Hợp SGID và Sticky Bit cho Thư Mục Nhóm

Chúng tôi đã triển khai cài đặt này trên server Ubuntu 22.04 production. Kết quả: không có một ticket nào liên quan đến quyền từ các developer trong nhiều tháng. Không ai cần nhớ chạy chown hay chmod sau khi tạo file — kế thừa group và bảo vệ xóa file hoạt động tự nhiên.

# SGID(2) + Sticky(1) = 3 — kết hợp cả hai
sudo mkdir /var/shared/team-data
sudo chown root:devteam /var/shared/team-data
sudo chmod 3775 /var/shared/team-data

ls -ld /var/shared/team-data
# drwxrwsr-t 2 root devteam 4096 Jun  2 10:00 /var/shared/team-data
# 's' = SGID (group kế thừa), 't' = Sticky Bit (chỉ owner mới xóa được)

SUID trên Binary Admin Tùy Chỉnh — Cách Làm Đúng

Bạn có thể muốn người dùng không phải root khởi động lại một service cụ thể. SUID có vẻ là câu trả lời — nhưng có một vấn đề: Linux cố ý bỏ qua SUID trên shell script. Bạn cần một C wrapper đã được biên dịch.

# SUID trên shell script bị bỏ qua hoàn toàn
chmod u+s /usr/local/bin/restart-nginx.sh  # Không có tác dụng gì

# Cách đúng: một C wrapper tối giản
cat << 'EOF' > /tmp/restart-nginx.c
#include <unistd.h>
int main() {
    setuid(0);
    execl("/bin/systemctl", "systemctl", "restart", "nginx", NULL);
    return 1;
}
EOF

gcc -o /usr/local/bin/restart-nginx /tmp/restart-nginx.c
chown root:webadmin /usr/local/bin/restart-nginx
chmod 4750 /usr/local/bin/restart-nginx
# Chỉ thành viên nhóm 'webadmin' mới chạy được, thực thi với quyền root

Thành thật mà nói, một quy tắc sudo có mục tiêu thường gọn hơn bất kỳ binary SUID tùy chỉnh nào trong hầu hết các trường hợp. Hãy dùng SUID tiết kiệm — càng ít file SUID trên hệ thống, diện tích tấn công càng nhỏ.

Baseline và Diff cho Kiểm Toán Bảo Mật

# Tạo baseline trước khi thay đổi hệ thống
find / -perm /6000 -type f 2>/dev/null | sort > /root/suid_baseline.txt

# Sau khi cài package hoặc vá lỗi, so sánh
find / -perm /6000 -type f 2>/dev/null | sort > /root/suid_current.txt
diff /root/suid_baseline.txt /root/suid_current.txt
# Dòng mới = binary SUID/SGID mới được thêm vào hệ thống

Chạy lệnh này sau mỗi lần cập nhật package quan trọng. Một binary SUID mới xuất hiện bất ngờ là điều đáng điều tra ngay — đừng giả định package manager đặt nó ở đó có chủ ý.

Mẹo Thực Tế: Tăng Cường Bảo Mật Hệ Thống

Loại Bỏ Các Bit SUID/SGID Không Cần Thiết

Server không cần hầu hết các binary SUID đi kèm với bản phân phối hướng desktop. Hãy kiểm tra và loại bỏ những gì không cần thiết:

# Xóa SUID khỏi file
chmod u-s /usr/bin/at

# Xóa SGID
chmod g-s /usr/bin/newgrp

# Các ứng viên cần xem xét thường gặp trên headless server:
ls -l /usr/bin/at       # Lịch trình batch job
ls -l /usr/bin/newgrp   # Chuyển đổi group
ls -l /usr/bin/chsh     # Thay đổi login shell
ls -l /usr/bin/chfn     # Thay đổi thông tin user

Dùng Tùy Chọn Mount nosuid trên Phân Vùng Dữ Liệu

Bất kỳ phân vùng nào không cần SUID executables — thư mục upload, /tmp, phân vùng home của user — đều có thể dùng tùy chọn mount nosuid. Nó vô hiệu hóa hoàn toàn bit SUID và SGID trên phân vùng đó, ngay cả khi ai đó cố tình cài file độc hại vào:

# /etc/fstab
/dev/sdb1  /data   ext4  defaults,nosuid,noexec  0  2
/dev/sdc1  /home   ext4  defaults,nosuid         0  2

# Remount trực tiếp không cần khởi động lại
sudo mount -o remount,nosuid /data

Tham Khảo Nhanh: Khi Nào Dùng Từng Bit

  • SUID trên file thực thi: Chỉ khi chương trình thực sự cần chạy với quyền của owner. Mỗi binary SUID root đều là vector leo thang đặc quyền tiềm năng.
  • SGID trên thư mục: Thư mục nhóm dùng chung khi việc sở hữu group nhất quán là quan trọng. An toàn, thực tế và hữu ích trong nhiều trường hợp.
  • Sticky Bit trên thư mục: Bất kỳ thư mục dùng chung nào có thể ghi bởi tất cả hoặc theo group. Tiêu chuẩn cho /tmp, thư mục upload và vùng làm việc tạm.
  • SUID trên shell script: Linux bỏ qua nó — hãy dùng quy tắc sudo hoặc C wrapper đã biên dịch.

Đang làm pentest hay giải CTF? Tìm thấy find, vim, cp hoặc bash với SUID root thực chất là leo thang đặc quyền miễn phí — find -exec /bin/sh \; hoặc tính năng shell escape có sẵn của vim đưa bạn đến đó trong vài giây. Trên hệ thống production, đó là cấu hình sai cần phát hiện trước khi người khác làm.

Share: