--- title: 2021q3 Homework1 (quiz1) tags: Linux image: --- # 2021q3 Homework1 (quiz1) contributed by < starlinking > [toc] ## 0. 環境 (Ubuntu 20.04 VM running up) ```b$ uname -a $ uname -r 5.4.0-80-generic $ sudo apt install linux-headers-`uname -r` $ dpkg -L linux-headers-5.4.0-80-generic | grep "/lib/modules" /lib/modules /lib/modules/5.4.0-80-generic /lib/modules/5.4.0-80-generic/build $ tree -L 2 hideproc/ hideproc/ ├── main.c └── Makefile $ make make -C /lib/modules/`uname -r`/build M=/home/star/workspace/linux/hideproc modules make[1]: Entering directory '/usr/src/linux-headers-5.4.0-80-generic' CC [M] /home/star/workspace/linux/hideproc/main.o LD [M] /home/star/workspace/linux/hideproc/hideproc.o Building modules, stage 2. MODPOST 1 modules CC [M] /home/star/workspace/linux/hideproc/hideproc.mod.o LD [M] /home/star/workspace/linux/hideproc/hideproc.ko make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-80-generic' $ tree -L 2 hideproc/ hideproc/ ├── hideproc.ko ├── hideproc.mod ├── hideproc.mod.c ├── hideproc.mod.o ├── hideproc.o ├── main.c ├── main.o ├── Makefile ├── modules.order └── Module.symvers $ sudo insmod hideproc.ko $ dmesg [ 3006.672989] hideproc: module verification failed: signature and/or required key missing - tainting kernel [ 3006.673303] @ _hideproc_init $ pidof cron 661 $ echo "add 661" | sudo tee /dev/hideproc add 661 $ pidof cron $ echo "del 661" | sudo tee /dev/hideproc del 661 $ pidof cron 661 $ sudo rmmod hideproc $ dmesg [ 3543.712336] @ _hideproc_exit ``` ## 1. 解釋程式碼運作原理,包含 ftrace 的使用 :::info Ftrace堪稱Linux官方tracer,一般只要有echo, cat指令的嵌入式環境,就可以開始。為了後續方便學習 Linux 核心,我們可以安裝 ftrace cmdline 工具 - trace-cmd。 `sudo apt install trace-cmd` ::: * trace-cmd cheatsheet ``` usage: trace-cmd [COMMAND] ... ``` | use case | cmd | | -----------------------------------------| -------------------------- | | How to know what functions we can trace? | sudo trace-cmd list -f | | How to trace a function? | sudo trace-cmd record -p function -l do_page_fault | | How to trace a process? | sudo trace-cmd record -p function -P 25314 | ``` -p run command with plugin enabled -l filter function name -P pid ``` * _hideproc_init * init_hook * hook_install: install the function hooks * _hideproc_exit * hook_remove(&hook): remove function hooks >enable hook_remove function (==remove line 66 and 76==) ```c=66 #if 0 void hook_remove(struct ftrace_hook *hook) { int err = unregister_ftrace_function(&hook->ops); if (err) printk("unregister_ftrace_function() failed: %d\n", err); err = ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0); if (err) printk("ftrace_set_filter_ip() failed: %d\n", err); } #endif ``` > 增加幾行code,釋放相關資源,避免下次insmod hideproc.ko,出現錯誤,將dev_major宣告為全域變數。 ```bash $ dmesg [ 9128.397812] sysfs: cannot create duplicate filename '/class/hideproc' [ 9128.397814] CPU: 0 PID: 17645 Comm: insmod Tainted: G OE 5.4.0-80-generic #90-Ubuntu [ 9128.397815] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 9128.397816] Call Trace: [ 9128.397821] dump_stack+0x6d/0x8b [ 9128.397824] sysfs_warn_dup.cold+0x17/0x27 [ 9128.397827] sysfs_create_dir_ns+0xb8/0xd0 [ 9128.397829] kobject_add_internal+0xbd/0x2b0 [ 9128.397830] kset_register+0x4c/0x70 [ 9128.397832] __class_register+0xd8/0x190 [ 9128.397833] __class_create+0x51/0x80 [ 9128.397836] ? hook_remove.cold+0x26/0x26 [hideproc] [ 9128.397837] _hideproc_init+0x6c/0x1c5 [hideproc] [ 9128.397839] do_one_initcall+0x4a/0x200 [ 9128.397841] ? _cond_resched+0x19/0x30 [ 9128.397844] ? kmem_cache_alloc_trace+0x177/0x240 [ 9128.397846] do_init_module+0x62/0x260 [ 9128.397847] load_module+0x11e6/0x1320 [ 9128.397850] __do_sys_finit_module+0xbe/0x120 [ 9128.397851] ? __do_sys_finit_module+0xbe/0x120 [ 9128.397853] __x64_sys_finit_module+0x1a/0x20 [ 9128.397854] do_syscall_64+0x57/0x190 [ 9128.397856] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 9128.397857] RIP: 0033:0x7f1f4b2e989d [ 9128.397858] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c3 f5 0c 00 f7 d8 64 89 01 48 [ 9128.397859] RSP: 002b:00007ffc3ea5ab58 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 9128.397860] RAX: ffffffffffffffda RBX: 0000557bf07c57a0 RCX: 00007f1f4b2e989d [ 9128.397860] RDX: 0000000000000000 RSI: 0000557beeb2f358 RDI: 0000000000000003 [ 9128.397861] RBP: 0000000000000000 R08: 0000000000000000 R09: 00007f1f4b3bd260 [ 9128.397861] R10: 0000000000000003 R11: 0000000000000246 R12: 0000557beeb2f358 [ 9128.397862] R13: 0000000000000000 R14: 0000557bf07c5760 R15: 0000000000000000 [ 9128.397864] kobject_add_internal failed for hideproc with -EEXIST, don't try to register things with the same name in the same directory. ``` ```c=234 static void _hideproc_exit(void) { printk(KERN_INFO "@ %s\n", __func__); /* FIXME: ensure the release of all allocated resources */ hook_remove(&hook); device_destroy(hideproc_class, MKDEV(dev_major, MINOR_VERSION)); class_destroy(hideproc_class); cdev_del(&cdev); unregister_chrdev_region(MKDEV(dev_major, MINOR_VERSION), MINOR_VERSION); } ``` > 可以連續 insert, remove hideproc 核心模組! ```bash $ dmesg [ 1209.535616] @ _hideproc_init [ 1299.288350] @ _hideproc_exit [ 1323.978583] @ _hideproc_init [ 1545.173048] @ _hideproc_exit [ 1547.666741] @ _hideproc_init [ 1549.172767] @ _hideproc_exit ``` :::danger 整個程式碼運作原理還未完全理解,需要再花一點時間內化,再補上。 ::: ## 2. 本程式僅在 Linux v5.4 測試,若你用的核心較新,請試著找出替代方案 ``` TODO: 先更新kernel版本,再試試! ``` ## 3. 本核心模組只能隱藏單一 PID,請擴充為允許其 PPID 也跟著隱藏,或允許給定一組 PID 列表,而非僅有單一 PID ## 4. 指出程式碼可改進的地方,並動手實作 ## Resource(s) * Youtube * https://www.youtube.com/watch?v=93uE_kWWQjs * https://jvns.ca/blog/2017/03/19/getting-started-with-ftrace/ * https://xcellerator.github.io/posts/linux_rootkits_02/ * https://xcellerator.github.io/posts/linux_rootkits_04/