Linux Căn Bản – Bài 12: Quản lý phần mềm, tác vụ trên hệ thống Linux và tấn công leo thang đặc quyền đối với server Learn Linux

Xin chào,

Sau bài hôm nay, chúng ta sẽ tạm khép lại series Linux Căn Bản để đi đến giai đoạn 3 của lộ trình tự học Linux Pentest Căn Bản. Ở giai đoạn 3, chúng ta sẽ học về một số công cụ được sử dụng nhiều trên Kali Linux, mong các bạn sẽ tiếp tục theo dõi và ủng hộ nhé.

Trong bài hôm nay, chúng ta sẽ học về $PATH, quản lý phần mềm và tác vụ trên hệ thống đồng thời sẽ thực hiện tấn công leo thang đặc quyền với server Learn Linux.


1/ $PATH (Task 39)

Vì phần lớn kiến thức của task 39 đã được mình đề cập trong bài 8 rồi, nên trong bài hôm nay mình sẽ chỉ đề cập đến $PATH thôi.

$PATH có liên quan đến cách một câu lệnh được thực thi. Ở trong bài 8 chúng ta đã biết mỗi câu lệnh thực chất là một phần mềm được viết nên để thực hiện một tác vụ nào đó. Ví dụ câu lệnh ls sẽ liệt kê các directories và files đang chứa bên trong directory hiện tại, hoặc câu lệnh cat sẽ hiển thị nội dung của file, v.v. Cũng trong bài 8, chúng ta biết phần lớn các phần mềm này được chứa trong những directories như /usr/bin, /usr/sbin, /usr/local/bin/ hoặc /usr/local/sbin. Tuy nhiên, thực tế các files thực thi của các câu lệnh không nhất thiết phải nằm trong những directories trên mà có thể nằm ở bất kỳ đâu trong hệ thống.

Khi bạn thực thi một câu lệnh trên Linux shell, hệ thống sẽ không kiểm tra tất cả directories tồn tại trong hệ thống nhằm tìm ra câu lệnh bạn muốn chạy đang được chứa tại directory nào mà nó sẽ chỉ nhìn vào environment variable hay $PATH để biết chính xác những directories câu lệnh cần chạy có thể được chứa mà thôi.

Vấn đề này gần tương tự với hệ điều hành Windows, khi cần phải cài đặt một phần mềm ví dụ như Python chẳng hạn. Để chạy được Python trong giao diện dòng lệnh trên Windows mà không cần phải gọi chính xác nơi chứa phần mềm Python, hoặc bạn cần phải thêm path của Python vào Environment Variables trên Windows.

Trên Linux cũng khác mấy trên Windows, việc thêm directory vào $PATH sẽ giúp bạn có thể thực thi một câu lệnh dễ dàng mà không cần phải gọi chính xác nơi chứa câu lệnh đó.

Để kiểm tra những directories nào được lưu trữ trong $PATH, chúng ta sẽ sử dụng câu lệnh sau:

echo $PATH
H1.1

Mỗi directory được chứa bên trong của $PATH sẽ được cách nhau bởi dấu “:”. Khi bạn thực thi một câu lệnh nào đó, hệ thống Linux sẽ tìm câu lệnh cần chạy trong những directories trong $PATH theo thứ tự từ trái sang phải.

Nếu bạn có quyền sử dụng câu lệnh export, bạn có thể thêm directory vào bên trong $PATH. Directory được thêm vào sẽ xuất hiện ở vị trí đầu tiên bên trái. Để thêm directory vào $PATH ta dùng câu lệnh sau:

export PATH=<tên-directory>:$PATH

Ví dụ: Thêm directory /tmp vào $PATH

Ta sẽ dùng câu lệnh sau

export PATH=/tmp:$PATH

Sau đó chúng ta sẽ kiểm tra lại $PATH

echo $PATH
H1.2

Như bạn thấy directory /tmp đã xuất hiện bên trong $PATH với vị trí đầu tiên bên trái, nghĩa là mỗi khi bạn thực thi một câu lệnh, hệ thống sẽ tìm câu lệnh cần chạy trong directory /tmp đầu tiên sau đó mới tới các directories ở phía sau.

Điều này dẫn đến một rủi ro an ninh hệ thống. Ví dụ bạn thực thi câu lệnh ls với sudo, hacker biết được điều đó nên tạo một file mã độc giả ở với tên ls và chứa bên trong directory /tmp. Như vậy khi hệ thống tìm thấy file ls bên trong directory /tmp, nó sẽ chạy file đó và vô tình làm lây lan mã độc trong hệ thống hoặc cho phép hacker leo thang đặc quyền thành công.

2/ Quản lý phần mềm (Task 40)

Các hệ điều hành Linux hiện nay sử dụng một phần mềm gọi là package manager để quản lý những phần mềm được cài vào hệ thống Linux. Cụ thể, package manager sẽ có nhiệm vụ cài đặt, nâng cấp, cấu hình và xóa các phần mềm đã được cài đặt trước đó vào hệ thống Linux.

Các phần mềm cho các hệ điều hành Linux hiện nay sẽ được đóng gói thành các packages nhằm mục đích dễ phân phối và lưu trữ. Mỗi package sẽ bao gồm:

  • File thực thi (binary)
  • Các thông tin liên quan đến phần mềm (metadata). Ví dụ như: tên phần mềm, mô tả phần mềm, version.
  • Danh sách những phần mềm hoặc thư viện hỗ trợ cần thiết cho hoạt động của phần mềm (dependencies)

Các hệ điều hành Linux khác nhau đã tạo nên các định dạng package (package format) khác nhau. Ví dụ như:

  • .deb: Dành cho các hệ điều hành Linux Debian như: Kali Linux, Ubuntu, Parrot OS, Mint, v.v.
  • .rpm: Dành cho các hệ điều hành Linux của nhà Red Hat như: Red Hat, CentOS, Fedora, v.v.

Mỗi hệ điều hành Linux đều sẽ có một danh sách chứa những software repositories. Bạn có thể hiểu một cách đơn giản software repositories như là những nơi bạn có thể tải phần mềm online về máy của mình. Trên Kali Linux và Ubuntu, danh sách chứa software repositories có path là /etc/apt/sources.list.

Ở trên các hệ điều hành Linux Debian, người dùng được cung cấp nhiều lựa chọn để quản lý các packages. Ví dụ chúng ta có:

  • dpkg: Là một ứng dụng được dùng để quản lý, cài đặt, và xóa bỏ phần mềm ra khỏi hệ thống Linux. Điểm hạn chế của dpkg đó là nó không cài dependencies đi kèm với phần mềm, dẫn đến phần mềm bị lỗi và không thể hoạt động được.
    • Để cài đặt phần mềm ta dùng lệnh: dpkg -i <tên-phần-mềm>
    • Để xóa phần mềm ta dùng lệnh: dpkg –remove <tên-phần-mềm>
    • Để liệt kê phần mềm đã cài ta dùng lệnh: dpkg -l
  • apt hoặc apt-get: Lệnh apt hoặc apt-get vượt trội hơn dpkg ở chỗ, nó không chỉ cài đặt package mà còn cả những dependencies mà phần mềm cần để chạy ổn định. Thực tế, khi người dùng sử dụng apt hoặc apt-get để cài đặt một package, nó sẽ sử dụng dpkg để cài đặt phần mềm và apt hoặc apt-get sẽ lo phần dependencies. Đây cũng là câu lệnh được dùng phổ biến nhất để quản lý packages trên các hệ điều hành Linux Debian.
    • Để cài đặt phần mềm ta dùng lệnh: apt install <tên-phần-mềm>
    • Để xóa phần mềm ta dùng lệnh: apt remove <tên-phần mềm>
    • Để xóa toàn bộ những packages được dùng làm dependency của phần mềm cần xóa ta dùng lệnh: apt autoremove <tên-phần-mềm>
    • Để xóa tất cả những gì liên quan đến phần mềm cần xóa ta dùng lệnh: apt purge <tên-phần-mềm>
    • Để liệt kê những packages đã cài đặt ta dùng lệnh ta dùng lệnh: apt list

Sự khác biệt giữa apt và apt-get

apt-get từng được sử dụng rất phổ biến trong quá khứ, tuy nhiên ở các phiên bản mới của các hệ điều hành Linux Debian, người dùng được đề nghị nên sử dụng apt thay vì apt-get vì sự thân thiện, tiện lợi và những cải tiến về mặt thiết kế so với apt-get. Bạn nào muốn tìm hiểu chi tiết sự khác biệt có thể tham khảo bài viết sau.

Cập nhật và nâng cấp các packages trong hệ thống Linux

Chúng ta có thể dùng 3 câu lệnh sau để cập nhật và nâng cấp các phần mềm được cài đặt trong hệ thống Linux:

sudo apt update

Câu lệnh apt update sẽ tìm và cập nhật phiên bản mới nhất của của các packages trong list /etc/apt/sources.list.

Ví dụ, phiên bản nmap trong /etc/apt/sources.list là 2.1, khi chạy apt update, hệ thống thấy phiên bản nmap 2.2 đã được ra mắt, câu lệnh apt update sẽ cập nhật phiên bản nmap 2.2 vào list /etc/apt/sources.list. Câu lệnh apt update sẽ không cài đặt nmap 2.2 vào máy tính.

sudo apt upgrade

Câu lệnh apt upgrade sẽ dựa vào list /etc/apt/sources.list đã được cập nhật mà cài đặt các phiên bản mới nhất cho các phần mềm bên trong hệ thống Linux.

Ví dụ, apt upgrade sẽ cài đặt nmap 2.2 vào máy tính dựa vào giá trị được lưu bên trong list /etc/apt/sources.list

sudo apt dist-upgrade

Câu lệnh dist-upgrade, bên cạnh thực hiện chức năng của câu lệnh upgrade, nó còn kiêm luôn cả việc cập nhật phiên bản mới nhất cho cả những dependencies của các phần mềm được cập nhật nữa. Hoặc nếu có những dependencies xung đột với nhau câu lệnh dist-upgrade sẽ ra tay xóa bỏ những dependencies gây xung đột này.

3/ Quản lý tác vụ (Task 41)

Trên giao diện dòng lệnh, hệ thống Linux cung cấp cho ta vài công cụ để quản lý các tác vụ đang chạy trên hệ thống tương tự như Task Manager trên hệ điều hành Windows. Bạn nào muốn tìm hiểu thêm về process trong hệ điều hành Linux, có thể tham khảo link sau. Vì phần này liên quan đến cách thức của hệ điều hành nên mình sẽ không đi sâu nhé.

3a/ Lệnh ps

Lệnh ps có được sử dụng để hiện thị các tác vụ hiện đang chạy trong hệ thống. Đặc điểm của câu lệnh ps đó là nó không hiển thị thông tin của tác vụ theo thời gian thực mà chỉ xuất ra thông tin của tất cả processes đang có trong hệ thống ngay tại thời điểm câu lệnh ps được thực thi. Cú pháp của câu lệnh ps như sau:

ps <tùy-chọn-flag>

Khi sử dụng lệnh ps không kèm flag, bạn lệnh ps sẽ chỉ in ra những thông tin về process đang chạy câu lệnh ps và shell mà câu lệnh ps đang chạy. Ví dụ:

H3a.1

Trong đó:

  • PID (Process ID): Số định danh của process trong hệ thống. Mỗi process sẽ mang một PID và con số này là độc nhất. Nghĩa là sẽ không bao giờ cùng một lúc có 2 processes có cùng
  • TTY (TeleTYpewriter): Tên của thiết bị đầu cuối thực thi câu lệnh
  • TIME: Thời gian CPU cần để xử lý process trên tính theo phút và giây
  • CMD: Tên của câu lệnh đã bắt đầu process

Để in ra toàn bộ process đang chạy trong hệ thống chúng ta sẽ dùng câu lệnh sau:

ps -e
H3a.2

Để xuất ra tác vụ kèm theo PID của parent tác vụ và UID đang chạy tác vụ ta sử dụng câu lệnh sau

ps -ef
H3a.3

Trong đó:

  • UID: Tên user chạy tác vụ
  • PPID (Parent PID): ID của parent của tác vụ
  • C: Số chu kỳ của CPU được sử dụng bởi mỗi tác vụ
  • STIME: Thời điểm process bắt đầu

3b/ Lệnh top

Câu lệnh top cũng là một công cụ được sử dụng để quản lý các tác vụ trên hệ điều hành Linux. Khác với câu lệnh ps, câu lệnh top sẽ cập nhật thông tin tác vụ đang chạy trên hệ thống theo thời gian thực cho đến khi nào bạn dừng lệnh mới thôi. Cú pháp của câu lệnh top như sau:

top <tùy-chọn-flag>

Khi ta chạy câu lệnh top, tất cả các process đang chạy trong hệ thống sẽ được hiện ra như sau:

H3b.1

Với top, bạn có thể tùy chọn những thông tin bạn muốn hiện ra. Ví dụ khi lệnh top đang chạy, bạn nhấn phím “f”. Lúc này thông tin của tất cả các cột sẽ hiện ra. Các tên cột có dấu “*” phía trước là những thông tin đang được hiển thị.

H3b.2

Để di chuyển lên hoặc xuống các bạn sẽ dùng 2 phím mũi tên lên hoặc xuống. Để chọn hoặc bỏ chọn hiện thị một cột các bạn nhấn phím space (phím khoản trống). Và để thoát ra, các bạn dùng phím “q” hoặc “ECS”.

4/ Tấn công leo thang đặc quyền (priv escalation) server Learn Linux (Task 43)

Task 43 yêu cầu chúng ta như sau

H4.1

Trong CTF, những flag file là những file chứa một đoạn chìa khóa, được dùng để chứng minh rằng pentester đã thành công kiểm soát được hoàn toàn hệ thống mục tiêu. Thường sẽ có 2 flag files, một được chứa trong HOME directory của một trong những account người dùng bình thường, và một sẽ được chứa trong HOME directory của root account.

Trong trường hợp của phòng Learn Linux, sẽ chỉ có một flag file, và file của chúng ta nằm ở HOME directory của root account. HOME directory của root account sẽ chỉ có duy nhất root account được phép truy cập. Điều này có nghĩa là chúng ta sẽ phải tìm cách để leo thanh đặc quyền (priv escaltion) lên root account.

Tuy nhiên chúng ta sẽ bị giới hạn trong việc chỉ được phép sử dụng kiến thức đã học trong phòng Learn Linux mà thôi. Thông thường, một số cách phổ biến nhất để leo thang đặc quyền đó là:

  1. Kernel exploit: Lợi dụng một lỗ hổng trong kernel hoặc hệ điều hành để leo thang đặc quyền
  2. SUID: Lợi dụng SUID để leo thang đặc quyền như ta đã thực hành với vim và nano ở bài 11
  3. Cron tasks: Lợi dụng những tác vụ được thiết lập chạy tự động bởi root để leo thang đặc quyền
  4. Sudo rights: Lợi dụng những công cụ được cấp phép sử dụng để leo thang đặc quyền
  5. Tìm mật khẩu của account root được chứa bên trong các file quan trọng như web database, log file, v.v

Ở đây, cách 1, 2 và 3 sẽ được loại qua một bên, do các kỹ thuật này không được hướng dẫn trong phòng Learn Linux. SUID là phần mình tự thêm vào chứ nó không nằm trong phần kiến thức có sẵn của phòng Learn Linux.

Vậy nghĩa là chúng ta chỉ còn cách 4 và 5, với sudo rights mình đã thử chạy câu lệnh bên dưới trong cả 4 account shiba

sudo -l 

và chúng ta có kết quả như sau

H4.2

Lưu ý: Password của các account shiba nằm tại các task sau:

  • shiba1: pass là shiba1
  • shiba2: task 11
  • shiba3: task 21
  • shiba4: task 33

Vì chúng ta không có quyền thực thi câu lệnh sudo, nên coi như sudo rights không sử dụng được. Tuy nhiên chúng ta lại thấy có sự xuất hiện của một account tên là nootnoot. Account nootnoot cũng có quyền chạy câu lệnh sudo. Đây có thể là account có phân quyền cao hơn chúng ta. Vậy việc đầu tiên chúng ta cần làm là tìm cách leo thang đặc quyền lên account nootnoot.

Hiện tại chúng ta có các cách 1, 2, 3 và 4 không sử dụng được. Điều đó đồng nghĩa, chúng ta sẽ thử nghiệm cách thứ 5 trong danh sách bên trên. Vậy với kiến thức đã được hướng dẫn trong phòng Learn Linux, những directories hay files nào cần được kiểm tra?

Có một nơi mà mình sẽ kiểm tra đầu tiên đó là directory /var/log. Directory /var/log là nơi chứa log (nhật ký) từ hệ điều hành, những dịch vụ và những ứng dụng đang chạy trong hệ thống. Chúng ta sẽ kiểm tra thử directory /var/log biết đầu sẽ tìm được manh mối gì đó từ những gì đã được log lại.

ls -la /var/log
H4.3

Các bạn để ý kỹ sẽ thấy có một file thuộc quyền sở hữu của account shiba2 nhưng tên file lại là password của account shiba4. Vì trong cả danh sách directories và files của /var/logs chỉ có file này thuộc sở hữu của một account người dùng bình thường, nên mình sẽ kiểm tra thử file này.

Để đọc được file, chúng ta cần chuyển về account shiba2. Lí do là vì chỉ có account shiba2 và những account thuộc group của shiba2 mới có quyền đọc file này mà thôi. Bạn nào quên kiến thức về phân quyền có thể xem lại tại bài sau nhé.

Chúng ta sẽ chuyển về account shiba2, mật khẩu ở task 11, nếu bạn nào quên.

su shiba2
H4.4

Chúng ta sẽ kiểm tra file /var/log/test1234.

cat /var/log

Và chúng ta đã tìm được mật khẩu của nootnoot account được lưu bên trong file test1234. Với định dạng:

<tên-account>:<mật-khẩu>

Sử dụng username và password bên trong file test1234 để đăng nhập nootnoot

su nootnoot

Đến đây có bạn sẽ hỏi là account nootnoot liệu có phải là account root không? Để trả lời câu hỏi này, chúng ta hãy kiểm tra file /etc/passwd.

cat /etc/passwd
H4.5

Như chúng ta thấy nootnoot và root là 2 accounts hoàn toàn khác nhau nhé.

Sau khi đăng nhập vào nootnoot chúng ta sẽ kiểm tra xem những câu lệnh nào được phép sử dụng

sudo -l
H4.6

Các bạn thấy kết quả này quen không? Chúng ta đã gặp trường hợp này 1 lần khi leo thang đặc quyền ở server Pickle Rick. Lần này chỉ khác ở chỗ là các câu lệnh của chúng ta thực thi đôi khi sẽ yêu cầu mật khẩu, nhưng là mật khẩu của nootnoot chứ không phải mật khẩu của root. Vì chúng ta đã có mật khẩu của nootnoot rồi, nên việc còn lại khá dễ dàng. Chúng ta leo thang lên root bằng câu lệnh sau:

sudo su 
H4.8

Vậy là chúng ta đã leo thang đặc quyền lên root thành công. Việc còn lại là xem nội dung bên trong flag file có path là /root/root.txt

cat /root/root.txt

5/ Học gì sau series Linux Căn Bản

Vậy là chúng ta đã tạm thời kết thúc series Linux Căn Bản. Hi vọng series này đã phần nào cung cấp được cho các bạn những kiến thức căn bản về hệ thống Linux và giao diện dòng lệnh CLI.

Trong series này vì muốn kiến thức giới hạn ở mức dễ nhất cho những bạn mới bắt đầu nên mình đã lược bỏ đi khá nhiều chi tiết quan trọng. Những bạn nào muốn tìm hiểu thêm về hệ điều hành Linux, có thể tham khảo bài viết sau nhé.


Source:

https://opensource.com/article/17/6/set-path-linux
https://itsfoss.com/package-manager/
https://linuxhint.com/debian_package_managers/#:~:text=dpkg%20is%20the%20Linux%20Debian,or%20specific%20information%20on%20them.
https://phoenixnap.com/kb/apt-vs-apt-get
http://www.linuxandubuntu.com/home/using-ps-and-top-to-monitor-linux-processes
https://linuxize.com/post/ps-command-in-linux/

Leave a comment