Linux

Giới thiệu

Hệ điều hành mã nguồn mở

Cấu trúc:

  • Hardware Layer − Phần cứng bao gồm tất cả các thiết bị ngoại vi (RAM/ HDD/ CPU, v.v.).

  • Kernel – Đây là thành phần cốt lõi của Hệ điều hành, tương tác trực tiếp với phần cứng, cung cấp các dịch vụ cấp thấp cho các thành phần lớp trên.

  • Shell − Một giao diện với kernel, ẩn sự phức tạp của các chức năng kernel khỏi người dùng. Shell nhận lệnh từ người dùng và thực thi các chức năng kernel.

  • Tiện ích − Các chương trình tiện ích cung cấp cho người dùng hầu hết các chức năng của hệ điều hành.

  • Linux Distro (Bản phân phối) = nhân linux + các phần mềm bổ sung

File và Filesystem

File khi mở sẽ ánh xạ đến một giá trị gọi là file descriptor, tương tự như HANDLE trong Windows

Các loại file: - File thông thường, chứa các bytes dữ liệu, tổ chức thành 1 mảng

Thư mục và liên kết

File đặc biệt: Block device file (tập tin đề cập đến một thiết bị), Character device file(thường không có địa chỉ, cung cấp quyền truy cập vào dữ liệu dưới dạng luồng, thường là các ký tự), Named pipes(dùng để giao tiếp giữa các tiến trình), Sockets(dùng để giao tiếp mạng),

Lênh thường dùng: ls, cd, cp, mv, mkdir, rm, rmdir, touch, cat, grep, ..

Process và lập lịch

  • Tệp chứa hàng loạt thông tin mô tả cách chương trình chạy và lưu trữ trên memory. File thực thi trên linux cũng có header, mã máy, entrypoint, symbols(giống thông tin lưu trong file pdb) và bảng relocations, thư viện tĩnh, thư viện động. …

  • Thông tin về process đang chạy trong /proc, mỗi process id ứng với một thư mục

Ví dụ, vào 1 đường dẫn /proc/<PID>, ta sẽ tìm thấy những tệp cơ bản sau:

/proc/<PID>/cmdline: Các đối số commandline đã sử dụng để khởi chạy tiến trình

/proc/<PID>/status: Thông tin trạng thái chi tiết, bao gồm memory sử dụng và các số liệu thống kê của tiến trình

/proc/<PID>/fd: Symlink đến các files đã mở bởi tiến trình

Trong tất cả các đường dẫn, ta sẽ thấy 1 cấu trúc thư mục tương tự, và những file quan trọng nhất có thể liệt kê là:

cmdline: commandline của tiến trình

environ: các biến môi trường

fd: file descriptors

limits: chứa thông tin về các giới hạn của tiến trình

mounts: thông tin liên quan

Ta cũng sẽ thấy 1 vài liên kết trong những đường dẫn này:

cwd: 1 link đến current working directory của tiến trình

exe: link đến file có thể thực thi của tiến trình

root: link đến work directory của tiến trình

  • Signal: Cơ chế gửi tín hiệu, thông báo từ kernel đến process, từ process nọ sang process kia hoặc từ 1 process đến chính nó. Khi nhận được signal, hàm callback của process có thể xử lý hoặc bỏ qua(ngoại trừ SIGNKILL và SIGNSTOP)

Thường có

SIGINT 2 (Ctrl+C)

SIGQUIT 3 (Ctrl+D)

  • Câu lệnh thường dùng:

    • ps(liệt kê), top(thông tin chi tiết)

    • w: xem các user còn đang login đang làm gì

    • free: hiển thị thông tin bộ nhớ.

    • uptime: thời gian sống của hệ thống

    • pstree: hiển thị cây tiến trình

    • pgrep, pkill: tìm hoặc gửi signal đến tiến trình dựa theo tên và các thuộc tính khác

    • nice, renice, snice: thay đổi priority của tiến trình

  • Lập lịch bằng crontab:

Người dùng thiết lập các việc cần làm trong các file văn bản đặc biệt của cron (gọi là crontab file)

  • “crontab –e”: tạo hoặc chỉnh file crontab, giống “vi” “

  • crontab –l”: hiển thị file crontab

  • “crontab –r”: xóa file crontab

Thực hiện

  • Tạo crontab mới: crontab –e

  • Soạn như soạn thảo “vi”:

  • Khởi động lại dịch vụ cron để cập nhật lệnh mới: service crond restart

  • Theo dõi sự cập nhật của file times.log xem dịch vụ chạy đúng không: tail –f /tmp/times.log

User, Group và Phân quyền

Người dùng thường được phân thành 2 loại chính: root(superuser) và user(normal user)

Trong linux có thể có nhiều group khác nhau và một user có thể thuộc nhiều group. Mỗi group sẽ quy định user thuộc group đó có những quyền như thế nào

Mỗi tệp được liên kết với một user sở hữu, group sỡ hữu và một tập hợp các bit phân quyền r,w,x.

Câu lệnh thường dùng: sudo -i, useradd, usermod, userdel, passwd, group add

Phân quyền: chgrp, chown, chmod

Các File cấu hình hệ thống và các loại Log

Các file cấu hình hệ thống:

  • .bashrc: chạy khi có một shell(terminal) chạy lên mà có thể tương tác trực tiếp với người dùng (người dùng mở)

  • .bash_profile(.profile): tự động chạy khi có một phiên login shell

  • .bash_logout: chạy khi phiên login shell kết thúc

  • /etc/ld.so.preload: khai báo biến LD_PRELOAD, chứa một thư viện sẽ luôn được tải bởi mọi tiến trình sau này. Thường rootkit usermode trên linux sẽ khai báo LD_PRELOAD trong file .bash_profile hoặc file ld.so.preload

Các loại log:

  • /var/log/auth.log

/var/log/secure*:

Chứa thông tin nhật kí xác thực, bất kì hoạt động nào liên quan đến xác thực như sudo, su, ssh, …

Cấu trúc log: time + đối tượng đưa ra log + nội dung log

Nhiều dòng có pam_unix, Pluggable Authentication Modules (PAM) là module xác thực của linux.

  • /var/log/cmdlog.log: Lưu trữ tất cả các lệnh mà user gõ vào terminal. Log này chứa thời gian gõ lệnh, user thực hiện và nội dung. Không phải là log mặc định

  • .bash_history: chứa lịch sử các lệnh đã chạy, không chứa username và time

xem log

  • /var/log/daemen.log: chứa các thông tin về việc hệ thống đang chạy như thế nào và các tiến trình ứng dụng

  • /var/log/boot.log: lưu trữ tất cả thông tin liên quan đến khởi động và mọi thông báo được ghi lại trong quá trình khởi động bao gồm tập lệnh khởi tạo hệ thống, /etc/init.d/bootmisc.sh…

  • /var/log/dmesg log và /var/log/kern.log

Log về kernel

  • /var/log/syslog hoặc /var/log/message: Log hệ thống thông thường chứa các thông tin mặc định của hệ thống, thường được lưu trong

Để xem file log chúng ta có thể sử dụng một số phương pháp phổ biến sau:

  • vi: Chúng ta có thể sử dụng trình soạn thảo vi để kiểm tra file log.

  • tail: Nếu chúng ta muốn xem nội dung của file log theo thời gian thực ứng dụng đang ghi vào đó, hãy sử dụng tail -f.

  • grep: Nếu chúng ta biết chính xác những gì đang tìm kiếm trong file log hãy sử dụng lệnh grep để grep một từ khóa.

  • cat: Hiển thị toàn bộ nội dung file log.

ELF (Executable and Linking Format)

Chương trình thực thi trên Linux chủ yếu là các file ELF. Định dạng này được sử dụng để lưu trữ các tệp nhị phân, thư viện và core dumps trên đĩa trong Linux và các hệ thống Unix-based

Xem thông tin cơ bản về tệp ELF: file /bin/bash

Cấu trúc: 2 phần chính gồm ELF header và ELF data(Program headers, Section headers, Data)

ELF header: 32 byte, xác định định dạng tệp, bắt đầu bằng 4 unique bytes: 0x7F, 0x45, 0x4c, 0x46. Hiển thị ELF: readelf -h /bin/sh

Program Headers: Cung cấp thông tin về các segment của tệp thực thi sẽ được tải vào bộ nhớ trong quá trình thực thi chương trình.

  • Chỉ ra loại segment như code, data hoặc thông tin dynamic linking

  • Chỉ định virtual memory address nơi segment được tải vào bộ nhớ

  • Chỉ định offset nơi segment data được đặt

  • Kích thước và Quyền của các segment

  • Hiển thị program header: readelf /bin/bash -l

Section Headers: Bảng Section header rất quan trọng trong thời gian liên kết để tạo tệp thực thi

Các phần chung:

  • Text Section(.text) chứa hướng dẫn thực thi của chương trình

  • Data Section(.data) lưu trữ các biến toàn cục và biến tĩnh đã được khởi tạo

  • BSS Section(.bss) dành không gian cho các biến toàn cục và biến tĩnh chưa được khởi tạo

  • Symbol Table Section chứa các symbols (functions, variables) và thông tin liên quan

Commands:

Hiển thị Section Headers: readelf -S /bin/sh

Tạo file thực thi:

gcc example.c -o example

Tạo tập tin có thể liên kết:

gcc example.c -0 example.o

Tạo thư viện chia sẻ:

gcc -shared example1.o example2.o -o libexample.so

Sử dụng custom library này cần thêm vào /usr/lib, /usr/local/bin

Các kỹ thuật nâng cao

  1. Inject process

  • Có những trường hợp cần hook(chặn) các system call, thay đổi tham số đầu vào

  • Linux cung cấp cơ chế ptrace cho phép tiến trình cha có thể quan sát và kiểm soát việc thực thi của một chương trình con

  • Mặc định k đc phép 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 hiển thị là 0 thì phải xác minh

  • Hàm ptrace có cấu trúc:

long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

Request: request đến pid, có thể đọc/ghi/alloc data, thực thi code

  • Có 2 cách thường dùng để inject code:

Alloc + write shellcode và thực thi code này

Alloc + write shell có chức năng load thư viên .so (thường sử dụng nếu inject code 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 )

  1. Hook share libary:

  • 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 Appinit_dlls trong registry của Windows). Thường dùng để debug nhưng cũng có thể lợi dụng để hook một hàm có sẵn

  • Vd: LD_PRELOAD trỏ đến VT.so(có định nghĩa một 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 stdio.h sẽ được gọi thay vì 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 windows

  • Nhận biết: echo $LD_PRELOAD

cat /etc/ld.so.preload

  • Thực hành: Ẩn file loil8.txt qua lệnh ls

o Build: gcc -Wall -fPIC -shared -o hook_so.so hook_so.c –ldl

o Run: export LD_PRELOAD=”/home/…/hook_ls.so”

Last updated