Trước hết cần hiểu leo thang đặc quyền (privilege escalation) là gì? Hiểu đơn giản leo thang đặc quyền là từ một người dùng bằng cách nào đó chiếm được shell người dùng có đặc quyền cao trên hệ thống (root trên linux hoặc người dùng thuộc nhóm Administrators trên Windows). Buổi nay tôi sẽ tập trung vào phân tích các kỹ thuật privilege escalation trên môi trường linux mà thôi. Có thời gian sẽ làm bài trên môi trường Windows sau.

Privilege escalation là một trong những mục tiêu mà attacker thường cố gắng thực hiện trong mỗi cuộc tấn công vì có được root/administrator thì có thể làm được rất nhiều thứ hay ho hơn khi mà chỉ có được normal user(vd: để persistence backdoor, dump secret info mở rộng tấn công chéo sang các hệ thống khác, …). Hiểu được bằng cách nào có thể privilege escalation giúp ta có thể có các biện pháp phù hợp để phát hiện/giảm thiểu nguy cơ trong vận hành hệ thống hàng ngaỳ.

Có nhiều cách thức để thực hiện Privilege escalation, từ cao siêu như sử dụng các lỗ hổng zero day, các cve chưa được patch cho tới các cách đơn rất đơn giản là lợi dung sơ hở của người quản trị hệ thống. Dưới đây tôi sẽ cùng mọi người mổ sẻ chi tiết từng cách thức một. Hy vọng sẽ mang lại một số thông tin hữu ích mọi người.

Kernel exploits

Đây là cách thức mà attacker sử dụng các lỗ hổng trong nhân linux (kernel) để khai thác (exploit) để privilege escalation. Các lỗ hổng bị lợi dụng để exploit có thể là các lỗ hổng đã được công bố (cve) hoặc các lỗ hổng chưa được công bố (zero day). Một trong những ví dụ tiêu biểu là lỗ hổng Dirty COW công bố năm 2016 - với hệ thống bị mắc lỗi này chỉ với một payload và vài command là ta có thể escalate từ normal user lên root một cách dễ dàng. Tôi sẽ không nói nhiều về nó vì nó quá nổi tiếng rồi và không quá khó để tìm thấy các mã khai thác (PoC)trên github: PoC github link!

Điều kiện để có thể thực hiện khai thác các lỗ hổng loại này là:

  • Kernel chứa lỗ hổng

  • Khả năng tương thích để có thể exploit

  • Khả năng chuyển và build payload trên hệ thống để sử dụng

  • Khả năng thi hành được payload trên hệ thống

Như vậy để giảm thiểu việc bị exploit qua cách thức này là kết hợp các việc sau:

  • Giữ hệ thống luôn được update để đảm bảo hệ thống liên tụ được cập nhật các bản vá lỗi security.

  • Nếu không thự sự cần thiết nên loại bỏ các trương trình có thể bị lợi dụng để truyền file như ftp, sftp, scp, wget, curl,… Nếu bắt buộc sử dụng phải giới hạn lại thật chặt người dùng/ địa chỉ ip được phép sử dụng các chương trình này. Khuyến cáo tương tự với các trình biên dịch như gcc hoặc g++ thứ mà có thể attacker sử đụng để build payload tấn công. Làm tốt việc này sẽ giúp hạn chế việc transfer/build payload exploit kernel.

  • Giới hạn lại các thư mục/user có quyền write và execute. Đặc biệt như thư mục có nguy cơ public cao như web, các người dùng chạy dịch vụ như www-apache. Việc này sẽ hạn chế việc thực thi của payload khai thác.

Exploit các service đang chạy dưới quyền root

Tôi có đọc được một câu đại loại là “Exploiting any service which is running as root will give you Root!”

Nhiều sysadmin hay có thói quen sử dụng luôn root để chạy một số service (vd: webserver, mail server, …). Điều này tiềm ần nguy cơ rất lớn vì một khi service đó bị exploit thì attacker coi như có quyền root và có thể thực hiện bất cứ điều gì trên hệ thống. Một vài lỗ hổng khá nổi tiếng thuộc loại này như EternalBlue, SambaCry, …

Cách để giảm thiểu nguy cơ này là luôn nhớ nguyên tắc hạn chế tối đa chạy service dưới quyền của user root. Đặc biệt là các loại service public như web, database, file server.

Lỗi phân quyền SUID sai

  • Để hiểu được lỗi này, trước hết cần hiểu SUID là gì?

SUID (hay Set user ID), thường được sử dụng trên các file thực thi (executable files). Quyền này cho phép file được thực thi với các đặc quyền (privileges) của chủ sở hữu file đó.

Ví dụ: nếu một file được sở hữu bởi user root và đuợc set SUID bit, thì bất kể ai thực thi file, nó sẽ luôn chạy với các đặc quyền của user root.

Cách thức để nhận dạng các file này là khi xem permissions của file, ở phần User, nhãn x sẽ được chuyển sang nhãn s.

SUID

Để gán SUID cho 1 file, có 2 cách: chmod u+s [tên file] hoặc: chmod 4555 [ tên file] (thêm 4 vào trước permissons)

Lưu ý: Nếu file chưa có quyền thực thi (executing file as program), SUID sẽ là chữ S. Để nhãn S trở thành s bạn phải cấp quyền thực thi cho file.

  • Lợi dụng phân quyền SUID sai để privilege escalation

Cách thức thông thường để privilege escalation bằng phương pháp này việc đầu tiên cần làm là tìm kiếm các file/programe có owner là root và được gán cờ SUID. Sau đó cố tìm cách inject malicious payload vào các file/programe này, để khi nó được thi hành thì gọi/chạy luôn đoạn malicious payload theo ý của attacker với quyền root. Lúc này coi như là attacker có thể thực hiện theo ý định của mình.

VD: Để minh họa cho lỗi này tôi cố tình gán quyền SUID cho command /usr/bin/find trên linux và lợi dụng tính năng cho phép execute subscript của find để thi hành một malicious command dưới quyền root.

Để thực hiện ý tưởng ban đầu tôi gán quyền SUID cho command find

Chmod uid

Sau khi gán quyền SUID tôi kiểm tra lại thì tôi đã thấy phần owner permision có dạng xxs xxx xxx, owner của find vẫn như ban đầu là root và tất cả mọi user đều có quyền chạy lệnh find. Như vậy theo lý thuyết khi một user bất kỳ chạy lệnh find thì OS sẽ đối xử như là user root chạy lệnh find.

Sau đó tôi sẽ lợi dụng truyền vào command whoami vào tính năng thực thi subscript của lệnh find. Do file có owner là root nên lúc này đoạn command được inject vào sẽ được chạy với quyền root.

Perm uid

Ok. Như vậy là chỉ chút sơ ý gán quyền SUID sai thôi thì bất cứ normal user nào ta cũng có thể escalate lên root một cách dễ dàng.

Cách khắc phục lỗi này đơn giản là ta phải rà soát lại các file/command được gán quyền SUID bằng command sau

find / -perm -u=s -type f 2>/dev/null

Loại bỏ các file/các command cho phép execute subscript như find, sed, awk, … các editor như vi, nano, …, các sript thuộc sở hữu của root mà các other user có quyền write + execute. Các loại file/chương trình này tuyệt đối không được phép có quyền SUID.

Sai lầm trong cấu hình Sudo

sudo là một trương trình cho phép gán quyền cho một user bất kỳ chạy một chương trình với đặc quyền của một người dùng khác, default là super user - root. Mà bình thường tôi cũng chỉ thấy mọi người dùng default thôi (có lẽ vì nhiều quản trị viên chưa hiểu hết ý nghĩa của việc dùng sudo). Chính việc sử dụng với tùy chọn default này tạo ra lỗ hổng có thể privilege escalation.

Để lấy ví dụ cho trường hợp này giả sử vì yêu cầu công việc tôi cần cho phép một người dùng seko chạy /usr/bin/python3 với quyền root vì anh ta có chạy một trương trình python 3 mà nó yêu cầu phải ghi vào một số thư mục mà chỉ user root mới có quyền ghi vào. Như suy luận thông thường tôi sẽ sử dụng sudo để cho anh ta chạy python3 với quyền root và nghĩ yên tâm vì anh ta chỉ có thể xài python3 mà không thể làm gì khác. Để làm việc này tôi sẽ thêm vào file sudo như sau:

visudo

Dễ dàng kiểm tra lại việc mình đã làm chính xác chưa bằng lệnh sau:

check sudo

Vẫn là ok đến khi thấy việc tôi sử dụng sudo như thế này - rất dễ cho việc escalate root bằng đoạn mã rất đơn giản sau:

python escalte

Qua ví dụ này ta cần rút ra kinh nghiệm rằng phải khá thận trọng khi sử dụng sudo trong công việc hàng ngày, tránh để bị lợi dụng nó làm công cụ để leo thang đặc quyền.

Sai lầm trong cấu hình cronjob chạy dưới quyền root

Cronjob là một công cụ quá tiện lợi và quen thuộc trên linux. Tôi cá rằng ai mà đã từng làm việc trên môi trường linux đều ít nhất cũng đã sử dụng nó một lần. Dĩ nhiên việc sử dụng cronjob đúng cách chả có gì là sai. Tuy nhiên trong nhiều trường hợp việc sử dụng cronjob không đúng cách vô tình mang tới nguy cơ bị lợi dụng để leo thang đặc quyền.

Để minh họa cho dễ hiểu tôi lấy ví dụ như sau:

Gỉa sử tôi có một script /tmp/backup.sh để thực hiện việc backup dịch vụ. Do thói quen thông thường tôi hay chmod 777 /tmp/backup.sh (Trên thực tế khá nhiều sysadmin hay có thói quen dùng lệnh chmod ntn để đảm bảo thừa còn hơn thiếu :3).

Để backup định kỳ tôi tạo conjob với quyền người dùng root như sau

0 12 * * * bash /tmp/backup.sh &> /dev/null

Trên thực tế xét về mặt kỹ thuật, việc lợi dụng cronjob để thực hiện hành vi leo thang đặc quyền cơ bản thường dựa trên vài sơ hở sau:

  • crondjob thi hành một file dưới quyền root mà file này cho phép người dùng khác write nó. Lợi dụng quyền ghi để sửa đổi file thực hiện hành vi leo thang đặc quyền
  • crond file (/etc/crontab) cho phép người dùng thông thường có quyền ghi. Lợi dụng việc này để thi hành macilious code.
  • Thư mục /etc/cron.d cho phép normal user được phép sửa đổi cronjob thi hành malicious code leo thang đặc quyền

Như vậy nhìn vào các nguyên nhân trên để giảm thiểu nguy cơ lợi dụng cronjob để leo thang đặc quyền ta cần phải chú ý:

  • file/trương trình cronjob thực thi tốt nhất không nên để quyền ghi
  • file cron (/etc/crontab) ngoài root không được cho phép người khác có quyền ghi
  • Thư mục /etc/crond ngoài root không được phép cho người khác có quyền tạo file

OK, Trên đây là một số nội dung mà mình biết về linux privilege escalation. Khi nào biết được các kỹ thuật mới mình sẽ update sau. Có sai sót các bạn hãy góp ý ở phần comment giúp mình. Rất hy vọng các ae sysadmin/dev sẽ không mắc phải những lỗi stupid mà phía trên mình đã liệt kê, tạo ra các rủi do không đáng có cho hệ thống mà mình đang vận hành.