提权姿势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.csdn.net/csdn546229768/article/details/124367307

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值