Săn lùng Rootkit: Hướng dẫn thực hành điều tra bộ nhớ RAM Linux với Volatility 3

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Bóng ma lúc 2 giờ sáng: Tại sao điều tra ổ đĩa thất bại

Tôi thấy mình đang ngồi khom lưng trước màn hình terminal lúc 2 giờ sáng, chứng kiến một máy chủ web Ubuntu hoạt động như thể bị “ma nhập”. Mức sử dụng CPU lên tới 98% trên tất cả các lõi, nhưng lệnh top lại báo cáo mức tải trung bình (load average) gần như bằng không. Tôi đã lục soát kỹ /var/log/auth.log/var/log/syslog, nhưng chúng hoàn toàn sạch sẽ—sạch sẽ đến mức đáng ngờ.

Kẻ tấn công rất tỉ mỉ. Chúng đã xóa sạch log và triển khai một rootkit để che giấu sự hiện diện khỏi các công cụ tiêu chuẩn như lsps. Đây không phải là trò đùa của một script kiddie; đây là một mối đe dọa thường trực đang ẩn mình hoàn toàn trong bộ nhớ volatile (bộ nhớ tạm thời) của hệ thống.

Khi một cuộc xâm nhập đạt đến mức độ tàng hình này, việc kiểm tra ổ cứng là một ngõ cụt. Điều tra ổ đĩa (disk forensics) cho bạn thấy quá khứ, nhưng điều tra bộ nhớ (memory forensics) mới tiết lộ những gì đang diễn ra ngay bây giờ. Volatility 3 là công cụ hàng đầu for công việc này. Nó cho phép chúng ta vượt qua hệ điều hành đã bị xâm nhập để xem chính xác kernel đang làm gì, bất kể kẻ tấn công muốn chúng ta thấy điều gì.

Xây dựng phòng thí nghiệm phân tích

Chúng ta sẽ sử dụng Volatility 3 trong bài hướng dẫn này. Mặc dù Volatility 2 đã phục vụ cộng đồng trong một thập kỷ, nó gặp khó khăn với các kernel Linux hiện đại và phụ thuộc vào Python 2 đã lỗi thời. Volatility 3 nhanh hơn đáng kể và xử lý các tệp biểu tượng (symbol files) ít gặp lỗi hơn nhiều.

1. Thiết lập bộ công cụ

Luôn thực hiện phân tích trên một máy sạch. Chạy các công cụ điều tra trên một máy chủ bị nhiễm mã độc có nguy cơ đánh động mã độc hoặc làm hỏng bằng chứng. Bắt đầu bằng cách cài đặt các gói phụ thuộc cốt lõi:

sudo apt update
sudo apt install -y python3 python3-pip git
git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3
pip3 install -r requirements.txt

2. Trích xuất hình ảnh RAM

Bạn cần một bản chụp nhanh (snapshot) của RAM trước khi có thể đi sâu vào phân tích. Đối với các mục tiêu Linux, tôi khuyên dùng AVML (Acquire Volatile Memory Dump) của Microsoft. Đây là một tệp thực thi tĩnh (static binary), vì vậy bạn không cần phải cài đặt thêm thư viện trên máy mục tiêu. Điều này giúp giữ cho dấu vết điều tra của bạn ở mức tối thiểu và ngăn chặn “hiệu ứng người quan sát” (observer effect) làm thay đổi bằng chứng.

Chạy các lệnh sau trên máy mục tiêu để tạo tệp mem.dump:

# Tải xuống tệp thực thi độc lập
wget https://github.com/microsoft/avml/releases/download/v0.14.0/avml
chmod +x avml

# Trích xuất hình ảnh bộ nhớ 16GB hoặc 32GB
sudo ./avml mem.dump

Sau khi hoàn tất, hãy chuyển tệp mem.dump đó sang máy trạm phân tích của bạn bằng SFTP hoặc ổ đĩa bảo mật.

Rào cản Symbol: Giải mã dữ liệu

Các kernel Linux rất đa dạng, điều này làm cho việc phân tích bộ nhớ trở nên phức tạp. Không giống như Windows, nơi Volatility có thể lấy các symbol từ máy chủ của Microsoft, Linux yêu cầu một tệp biểu tượng trung gian (Intermediate Symbol File – ISF) khớp chính xác với phiên bản kernel của bạn (ví dụ: 5.15.0-71-generic).

Hầu hết các kỹ sư đều vấp ngã ở bước này. Đầu tiên, hãy kiểm tra xem Volatility có thể nhận dạng được hình ảnh bộ nhớ hay không:

python3 vol.py -f mem.dump banner.Banner

Nếu banner hiển thị phiên bản kernel nhưng các plugin khác thất bại, bạn phải cung cấp các symbol. Đối với các bản phân phối tiêu chuẩn như Ubuntu, bạn có thể sử dụng công cụ dwarf2json để chuyển đổi các symbol gỡ lỗi (debug symbols) sang định dạng mà Volatility hiểu được. Trong hướng dẫn này, chúng ta giả định rằng bạn đã đặt tệp JSON kết quả vào thư mục volatility3/symbols/linux/.

Cuộc điều tra: Lần theo dấu vết

Khi môi trường đã sẵn sàng, cuộc săn lùng bắt đầu. Tôi thường tìm kiếm ba thứ: điểm xâm nhập (entry point), cơ chế duy trì sự hiện diện (persistence mechanism) và kết nối ngược về máy chủ điều khiển (C2 callback).

1. Săn lùng các tiến trình ẩn

Kẻ tấn công thường ẩn các tiến trình bằng cách hủy liên kết chúng khỏi danh sách task_struct trong kernel. Trong khi pslist hiển thị những gì kernel nghĩ là đang chạy, thì psscan sẽ tìm thấy các “bóng ma”.

python3 vol.py -f mem.dump linux.pslist.PsList
python3 vol.py -f mem.dump linux.psscan.PsScan

So sánh hai kết quả đầu ra. Nếu một tiến trình xuất hiện trong psscan nhưng không có trong pslist, bạn đã tìm thấy một tiến trình ẩn. Hãy tìm các cái tên khả nghi như kworker_unbound hoặc các tiến trình chạy dưới quyền root mà không có lý do chính đáng để tồn tại.

2. Phân tích dữ liệu mạng

Một máy chủ bị xâm nhập hầu như luôn liên lạc ngược lại với máy chủ điều khiển. Ngay cả khi kẻ tấn công ẩn socket khỏi lệnh netstat trên hệ thống đang chạy, dữ liệu kết nối vẫn được ghi lại trong RAM.

python3 vol.py -f mem.dump linux.netstat.NetStat

Tìm kiếm các kết nối đến các cổng số cao như 4444 hoặc 31337. Kiểm tra các địa chỉ IP nằm ngoài dải CDN hoặc dải quản lý đã biết của bạn. Nếu bạn tìm thấy kết nối đến một IP khả nghi, hãy ghi lại ID tiến trình (PID) ngay lập tức.

3. Phát hiện mã độc được chèn vào

Mã độc nâng cao thường chèn shellcode vào các tiến trình hợp lệ như nginx hoặc systemd. Plugin malfind giúp xác định các vùng nhớ vừa có quyền ghi (writable) vừa có quyền thực thi (executable). Đây là một dấu hiệu cảnh báo cực kỳ nguy hiểm.

python3 vol.py -f mem.dump linux.malfind.Malfind

Nếu malfind đánh dấu một vùng nhớ, nó sẽ cung cấp một bản hex dump. Hãy tìm các tiêu đề ELF hoặc các dải NOP (một chuỗi dài các byte 0x90). Đây là những dấu hiệu rõ ràng của một payload đang chờ để thực thi.

4. Phơi bày các Hook ở mức Kernel

Những rootkit nguy hiểm nhất thường “hook” (đánh chặn) Bảng lời gọi hệ thống (System Call Table). Chúng chặn các lời gọi như read để ẩn tệp hoặc getdents để ẩn thư mục.

python3 vol.py -f mem.dump linux.check_syscall.Check_syscall

Nếu một syscall trỏ đến một địa chỉ bộ nhớ nằm ngoài nhân kernel gốc (vmlinux), Volatility sẽ làm nổi bật nó. Đây chính là “bằng chứng thép” của một vụ xâm nhập ở mức kernel.

Tư duy điều tra số

Phân tích thành công không chỉ là chạy các câu lệnh; đó là việc kể lại một câu chuyện. Tôi có thể bắt đầu với một kết nối mạng khả nghi dẫn tôi đến một PID cụ thể. Sau đó, tôi sử dụng malfind trên PID đó để xem mã được chèn vào. Cuối cùng, tôi sử dụng plugin lsof để xem tiến trình đó đã chạm vào những tệp nào trước khi kẻ tấn công xóa chúng.

python3 vol.py -f mem.dump linux.lsof.Lsof --pid <PID_KHA_NGHI>

Điều tra bộ nhớ cung cấp cho bạn khả năng quan sát mà một hệ điều hành đã bị xâm nhập cố gắng từ chối bạn. Nó biến những nghi ngờ mơ hồ thành bằng chứng kỹ thuật xác thực. Dữ liệu này là những gì bạn cần để khôi phục cơ sở hạ tầng và đảm bảo kẻ tấn công không thể quay trở lại.

Share: