Hook & Inject
Linux Malware
Last updated
Linux Malware
Last updated
Tương tự như file PE, file ELF có header và các section.
E_ident:
Name
Value
Purpose
EI_MAG0
0
File identification
EI_MAG1
1
File identification
EI_MAG2
2
File identification
EI_MAG3
3
File identification
EI_CLASS
4
File class
EI_DATA
5
Data encoding
EI_VERSION
6
File version
EI_PAD
7
Start of padding bytes
EI_NIDENT
16
Size of e_ident[]
E_type:
Name
Value
Meaning
ET_NONE
0
No file type
ET_REL
1
Relocatable file
ET_REL
2
Executable file
ET_DYN
3
Shared object file
ET_DYN
4
Core file
ET_LOPROC
0xff00
Processor-specific
ET_LOPROC
0xffff
Processor-specific
E_entry: VA của entrypoint.
E_phoff: offset trên file của program header table
E_shoff: offset trên file của section header table
E_ehsize: elf header’s size
E_phentsize: trả về kích thước 1 entry trong program header table, tất cả entry có cùng 1 kích thước.
E_phnum: số lượng entries trong program header table.
E_shentsize: a section header’s size in bytes.
E_shnum: số lượng entries trong section header table.
Việc map file từ disk lên memory tương tự windows:
Những segment có trường p_type là PT_LOAD sẽ được load lên mem, tương tự cách load từng section lên mem của file PE. Các segment khác được khai báo trong header sẽ là 1 phần của section PT_LOAD.
Có thể đọc thông tin file ELF bằng công cụ readelf:
Do nhu cầu thực tế, có những trường hợp cần chặn(hook) các system call, cần thay đổi tham số đầu vào… Thay vì lập trình kernel rất phức tạp, linux cung cấp cơ chế ptrace, theo đó 1 tiến trình cha có thể quan sát và kiểm soát việc thực thi của 1 tiến trình con.
Mặc định linux không cho phép sử dụng ptrace. Muốn sử dụng ptrace, ta phải set cấu hình trong file /proc/sys/kernel/yama/ptrace_scope
0: tất cả process đều có thể debug.
1: chỉ parent process có thể debug child process
2: chỉ process admin có thể debug
3: không cho phép ptrace.
Nếu chiếm được quyền root, hacker có thể lợi dụng set lại cấu hình ptrace để có thể debug/inject mọi process.
Nhận biết: cat /proc/sys/kernel/yama/ptrace_scope
-> Nếu giá trị hiển thị là 0 thì phải xác minh.
Hàm ptrace có cấu trúc như sau:
Request: request đến pid, có thể là đọc/ghi/alloc data, thực thi code, …Tham khảo thêm tại http://man7.org/linux/man-pages/man2/ptrace.2.html
Tương tự như inject code trên windows, có 2 cách thường dùng để inject code:
Alloc + write shellcode và thực thi code này.
Alloc + write shellcode có chức năng load thư viện .so => sử dụng phương pháp này nếu đoạn code cần inject có nhiều chức năng phức tạp; hoặc dành cho script kiddie, chỉ cần code file .so bình thường rồi copy shellcode có chức năng load file .so là xong. Không yêu cầu kỹ năng viết shellcode.
Linux cung cấp biến môi trường LD_PRELOAD, dùng để chỉ định 1 share library sẽ được ưu tiên gọi lên trước(tương đương với đường dẫn Appinit_dlls trong registry của Windows). Người ta thường dùng tính năng này để debug, nhưng cũng có thể lợi dụng để hook 1 hàm có sẵn
Ví dụ LD_PRELOAD trỏ đến thư viện VT.so, trong thư viện này có định nghĩa 1 hàm puts (cùng tên với hàm puts trong stdio.h). Khi 1 chương trình gọi puts, hàm puts trong VT.so sẽ được gọi thay vì hàm puts trong của stdio.h. Trong hàm puts mới, lấy địa chỉ hàm puts cũ bằng cách dùng dlsym, tương tự getprocaddress trong windows
Nhận biết:
echo $LD_PRELOAD
cat /etc/ld.so.preload
Practice: ẩn file hainh45.txt qua lệnh ls
Source: hook_ls.c
Build: gcc -Wall -fPIC -shared -o hook_so.so hook_so.c –ldl
Run: export LD_PRELOAD=”/home/…/hook_ls.so”
-> Ls và hưởng thụ thành quả
Chương trình này sử dụng ptrace()
để attach với một tiến trình đang chạy, cho phép can thiệp và thay đổi trạng thái hiện tại của tiến trình đó. Bằng cách xem xét file /proc/PID/maps
, chương trình tìm kiếm một vùng nhớ có quyền thực thi, ví dụ như r-xp
. Khi tìm thấy một vùng nhớ như vậy, chương trình sẽ ghi đè nội dung của vùng nhớ đó bằng shellcode của thông qua PTRACE_POKETEXT
. Tiếp theo, chương trình sẽ chỉnh sửa các registers và đặt giá trị của thanh ghi rip
bằng địa chỉ của vùng nhớ tìm thấy trong file maps. Cuối cùng, tiếp tục thực thi tiến trình với PTRACE_CONT
.
Cụ thể, các bước thực hiện bao gồm:
PTRACE_ATTACH
với tiến trình mục tiêu thông qua PID được cung cấp qua dòng lệnh.
Lấy thông tin các register hiện tại sử dụngPTRACE_GETREGS
.
Phân tích file /proc/PID/maps
để tìm một địa chỉ có thể thực thi (r-xp
).
Ghi đè shellcode vào địa chỉ tìm được sử dụng PTRACE_POKETEXT
.
Thiết lập lại các register, với địa chỉ rip
được chỉnh sửa để trỏ vào vùng nhớ chứa shellcode.
Tiếp tục thực thi tiến trình mục tiêu (PTRACE_CONT
).
Qua đó, shellcode được ghi vào một vùng nhớ có thể thực thi và được thực thi khi tiến trình tiếp tục chạy, cho phép thực hiện các hành động tuỳ ý.
© 2024,Pham Quoc Trung. All rights reserved.