提权姿势modprobe_path修改文件权限

最近看内核exp时候一些题目的另一种解法可以通过modprobe_path方式读取flag,好像挺好玩的

定义

在内核运行一个未知类型的文件时,modprobe_path就会指向这个未知文件,当内核运行一个错误格式的文件后,内核会自动调用这个modprobe_path指向的文件,因为内核执行的权限是root权限,当我们将modprobe_path指向一个我们用于查看具有root权限的flag文件,那么就能得到flag

//源码定义如下:kernel/kmod.c
char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; 

实际调用如下:

//linux4.4.7 /kernel/kmod.c
static int call_modprobe(char *module_name, int wait)
{
	struct subprocess_info *info;
	static char *envp[] = {
		"HOME=/",
		"TERM=linux",
		"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
		NULL
	};

	char **argv = kmalloc(sizeof(char *[5]), GFP_KERNEL);
	if (!argv)
		goto out;

	module_name = kstrdup(module_name, GFP_KERNEL);
	if (!module_name)
		goto free_argv;

	argv[0] = modprobe_path;
	argv[1] = "-q";
	argv[2] = "--";
	argv[3] = module_name;	/* check free_modprobe_argv() */
	argv[4] = NULL;

	info = call_usermodehelper_setup(modprobe_path, argv, envp, GFP_KERNEL,
					 NULL, free_modprobe_argv, NULL);
	if (!info)
		goto free_module_name;

	return call_usermodehelper_exec(info, wait | UMH_KILLABLE); 
  //启动用户模式应用程序  info结构体里面包含了子进程信息和modprobe_path

free_module_name:
	kfree(module_name);
free_argv:
	kfree(argv);
out:
	return -ENOMEM;
}

使用

/ $ cat /proc/kallsyms | grep modprobe_path #不一定会有
ffffffff81e476e0 D modprobe_path

符号里面没有 modprobe_path 地址的时候可以通过一些函数的引用来找

比如__request_module

  • 通过shell命令(开启保护后需要root身份):grep __request_module /proc/kallsyms查看汇编即可得到字符串地址

    / $ grep __request_module /proc/kallsyms #user
    0000000000000000 T __request_module
    0000000000000000 t __request_module.cold.4
    / # grep __request_module /proc/kallsyms  #root
    ffffffff810833e0 T __request_module #addr
    ffffffff8108378b t __request_module.cold.4
    
  • 通过gef插件:(不用root身份就可以查看)

    gef➤  xinfo __request_module
    ────────────────────────────────── xinfo: 0xffffffff810833e0──────────────────────────────────
    Page: 0x00000000000000  →  0xffffffffffffffff (size=0xffffffffffffffff)
    Permissions: rwx
    Pathname: /home/hnhuangjingyu/kernel/SUCTF2019_sudrv/vmlinux
    Offset (from page): 0xffffffff810833e0  //得到的地址
    Inode: 0
    Segment: .text (0xffffffff81000000-0xffffffff81c01781)
    Offset (from segment): 0x833e0
    Symbol: __request_module
    

    这里直接使用gef进行观察

    gef➤  x/30i __request_module
       0xffffffff810833e0 <__request_module>:	push   rbp
       0xffffffff810833e1 <__request_module+1>:	mov    rbp,rsp
       0xffffffff810833e4 <__request_module+4>:	push   r15
       0xffffffff810833e6 <__request_module+6>:	push   r14
    //。。。。忽略。。。。。。。
       0xffffffff81083425 <__request_module+69>:	jne    0xffffffff810835a6 <__request_module+454>
       0xffffffff8108342b <__request_module+75>:	xor    r15d,r15d
       0xffffffff8108342e <__request_module+78>:	cmp    BYTE PTR [rip+0x11beeeb],0x0        # 0xffffffff82242320  //在这里!!!
       0xffffffff81083435 <__request_module+85>:	jne    0xffffffff8108345e 
       
     -------------------- -------------------- -------------------- --------------------
    gef➤  strings 0xffffffff82242320
    0xffffffff82242320:	"/sbin/modprobe"
    0xffffffff8224232f:	""
    0xffffffff82242330:	""
    

    那么就得到了modprobe_path = 0xffffffff82242320

mod_tree

mod_tree这个内核指针里面包含了模块指针的内存地址。通过它可以获取到ko文件的地址

/sbin # cat /proc/kallsyms | grep mod_tree
ffffffff811043e0 t __mod_tree_remove
ffffffff81105b00 t __mod_tree_insert
ffffffff81e09200 d mod_tree

使用实例:

题目2019 suctf sudrv -> https://blog.youkuaiyun.com/csdn546229768/article/details/124367307

### 使用 `modprobe` 加载 `ipmi_devintf` 模块的方法 在 Linux 系统中,加载 `ipmi_devintf` 模块通常需要确保系统支持 IPMI(Intelligent Platform Management Interface),并且相关模块已经正确安装。以下是关于如何使用 `modprobe` 加载 `ipmi_devintf` 模块以及可能遇到的问题和解决方案。 #### 1. 确保模块可用 在使用 `modprobe ipmi_devintf` 命令之前,需要确认该模块是否存在于系统的模块目录中。可以通过以下命令检查模块是否存在: ```bash ls /lib/modules/$(uname -r)/kernel/drivers/char/ipmi/ ``` 如果未找到 `ipmi_devintf.ko` 文件,则说明系统中缺少该模块,可能需要重新编译内核或安装相关的驱动程序[^1]。 #### 2. 加载 `ipmi_devintf` 模块 在确认模块存在后,可以使用以下命令加载模块: ```bash sudo modprobe ipmi_devintf ``` 此命令会自动处理模块的依赖关系,并加载所需的其他模块,例如 `ipmi_msghandler` 和 `ipmi_si`[^2]。 #### 3. 检查模块是否成功加载 加载模块后,可以通过以下命令验证模块是否已成功加载: ```bash lsmod | grep ipmi_devintf ``` 如果输出包含 `ipmi_devintf`,则表示模块已成功加载。 #### 4. 解决模块找不到的问题 如果执行 `modprobe ipmi_devintf` 时示“FATAL: Module ipmi_devintf not found”,可以按照以下步骤排查问题: - **确认模块路径**:确保模块文件位于 `/lib/modules/$(uname -r)/kernel/drivers/char/ipmi/` 目录下。 - **更新模块依赖文件**:运行以下命令以更新 `modules.dep` 文件,确保 `modprobe` 能够正确解析模块依赖关系: ```bash sudo depmod -a ``` - **检查内核版本**:确保当前运行的内核版本与模块编译时的内核版本一致。如果不一致,可能需要重新编译模块或升级内核[^3]。 #### 5. 验证设备节点 加载 `ipmi_devintf` 模块后,应检查是否生成了相应的设备节点。可以通过以下命令确认: ```bash ls /dev/ipmi* ``` 如果没有生成设备节点,可能是由于硬件不支持 IPMI 或者模块加载失败。此时可以尝试手动加载所有相关模块: ```bash sudo modprobe ipmi_msghandler sudo modprobe ipmi_devintf sudo modprobe ipmi_si ``` #### 6. 使用 `ipmitool` 测试功能 加载模块后,可以使用 `ipmitool` 工具测试 IPMI 功能是否正常工作。例如: ```bash sudo ipmitool sensor list ``` 如果工具能够正常返回传感器信息,则说明模块加载成功且功能正常。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值