source
This commit is contained in:
		
							parent
							
								
									cfeabf075d
								
							
						
					
					
						commit
						b61bf36c55
					
				
							
								
								
									
										9
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					# FIX: module verification failed: signature and/or required key missing - tainting kernel
 | 
				
			||||||
 | 
					CONFIG_MODULE_SIG=n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					obj-m += sumo.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all:
 | 
				
			||||||
 | 
						make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
 | 
				
			||||||
 | 
					clean:
 | 
				
			||||||
 | 
						make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
 | 
				
			||||||
							
								
								
									
										35
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								README.md
									
									
									
									
									
								
							@ -1,3 +1,34 @@
 | 
				
			|||||||
# sumo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Sumo is a Linux Kernel module that grants root access credentials to any user-space process by PID.
 | 
					Sumo is a Linux Kernel module that grants root access credentials to any user-space process by PID.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# TL;DR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*.bashrc*
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					make                 # build
 | 
				
			||||||
 | 
					sudo insmod sumo.ko  # install
 | 
				
			||||||
 | 
					./whoami             # test
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# How it works
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In it's `init()` function, *sumo* kernel module creates `/proc/sumo` file and waits for PID to be written. Afterwards, it fetches instance of a `task_struct` [kernel structure](https://medium.com/@boutnaru/linux-kernel-task-struct-829f51d97275) associated with the given PID and modifies its values accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```text
 | 
				
			||||||
 | 
					sumo         __        SUdo
 | 
				
			||||||
 | 
					         ,;.'--'.      MOdule 
 | 
				
			||||||
 | 
					          /"/=,=(
 | 
				
			||||||
 | 
					          \(  __/
 | 
				
			||||||
 | 
					       ___/    (____
 | 
				
			||||||
 | 
					     .'     -  -    '.
 | 
				
			||||||
 | 
					    /         v       \
 | 
				
			||||||
 | 
					 __/    ,     |    \   '-/'_
 | 
				
			||||||
 | 
					{z, ,__/__,__/\__,_ )__(   z}
 | 
				
			||||||
 | 
					 \>'   (            \_ `--c/
 | 
				
			||||||
 | 
					    _.-'\_      ,   / \_
 | 
				
			||||||
 | 
					   (      `.______.'    '.
 | 
				
			||||||
 | 
					   \    ,   \    ( __     )
 | 
				
			||||||
 | 
					    \    )-'-\__/-'  |   /
 | 
				
			||||||
 | 
					     |   |          /  .'
 | 
				
			||||||
 | 
					     /  ,)         (   \_
 | 
				
			||||||
 | 
					    oooO'           '--Ooo
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										194
									
								
								sumo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								sumo.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,194 @@
 | 
				
			|||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/version.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/proc_fs.h>
 | 
				
			||||||
 | 
					#include <linux/fs.h>
 | 
				
			||||||
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
 | 
					#include <linux/seq_file.h>
 | 
				
			||||||
 | 
					#include <linux/sched.h>
 | 
				
			||||||
 | 
					#include <linux/capability.h>
 | 
				
			||||||
 | 
					#include <linux/cred.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SUMO \
 | 
				
			||||||
 | 
					R"(sumo:         __        SUdo   )""\n"\
 | 
				
			||||||
 | 
					R"(          ,;.'--'.      MOdule )""\n"\
 | 
				
			||||||
 | 
					R"(           /'/=,=(             )""\n"\
 | 
				
			||||||
 | 
					R"(           \(  __/             )""\n"\
 | 
				
			||||||
 | 
					R"(        ___/    (____          )""\n"\
 | 
				
			||||||
 | 
					R"(      .'     -  -    '.        )""\n"\
 | 
				
			||||||
 | 
					R"(     /         v       \       )""\n"\
 | 
				
			||||||
 | 
					R"(  __/    ,     |    \   '-/'_  )""\n"\
 | 
				
			||||||
 | 
					R"( {z, ,__/__,__/\__,_ )__(   z} )""\n"\
 | 
				
			||||||
 | 
					R"(  \>'   (            \_ `--c/  )""\n"\
 | 
				
			||||||
 | 
					R"(     _.-'\_      ,   / \_      )""\n"\
 | 
				
			||||||
 | 
					R"(    (      `.______.'    '.    )""\n"\
 | 
				
			||||||
 | 
					R"(    \    ,   \    ( __     )   )""\n"\
 | 
				
			||||||
 | 
					R"(     \    )-'-\__/-'  |   /    )""\n"\
 | 
				
			||||||
 | 
					R"(      |   |          /  .'     )""\n"\
 | 
				
			||||||
 | 
					R"(      /  ,)         (   \_     )""\n"\
 | 
				
			||||||
 | 
					R"(     oooO'           '--Ooo    )""\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MTAG "sumo: "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					MODULE_AUTHOR("djmil");
 | 
				
			||||||
 | 
					MODULE_DESCRIPTION("Grant root access right to the process by PID");
 | 
				
			||||||
 | 
					//MODULE_INFO(intree, "Y");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_task_uids_gids_to_zero(struct task_struct *task)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct cred *_cred;
 | 
				
			||||||
 | 
					  //struct real_cred *_real_cred;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Safely access cred and real_cred using rcu_dereference
 | 
				
			||||||
 | 
					  _cred = (struct cred *)rcu_dereference(task->cred);
 | 
				
			||||||
 | 
					  //_real_cred = (struct cred *)rcu_dereference(task->real_cred);
 | 
				
			||||||
 | 
						if (_cred == NULL) {
 | 
				
			||||||
 | 
						  pr_err(MTAG "Task creds are null %d\n", task->pid);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Update UIDs to zero
 | 
				
			||||||
 | 
					  _cred->uid.val = 0;
 | 
				
			||||||
 | 
					  _cred->euid.val = 0;
 | 
				
			||||||
 | 
					  _cred->fsuid.val = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Update GIDs to zero
 | 
				
			||||||
 | 
					  _cred->gid.val = 0;
 | 
				
			||||||
 | 
					  _cred->egid.val = 0;
 | 
				
			||||||
 | 
					  _cred->fsgid.val = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pr_debug(MTAG "PID %d: all UIDs and GIDs set to zero\n", task->pid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void change_process_capabilities(struct task_struct *task)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct cred *_cred;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Acquire a new set of credentials
 | 
				
			||||||
 | 
					  _cred = (struct cred *)rcu_dereference(task->cred);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Add ptrace+other capabilities
 | 
				
			||||||
 | 
					  _cred->cap_inheritable.cap[0] = 0xffffffff;
 | 
				
			||||||
 | 
					  _cred->cap_inheritable.cap[1] = 0xffffffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _cred->cap_permitted.cap[0] = 0xffffffff;
 | 
				
			||||||
 | 
					  _cred->cap_permitted.cap[1] = 0xffffffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _cred->cap_effective.cap[0] = 0xffffffff;
 | 
				
			||||||
 | 
					  _cred->cap_effective.cap[1] = 0xffffffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _cred->cap_bset.cap[0] = 0xffffffff;
 | 
				
			||||||
 | 
					  _cred->cap_bset.cap[1] = 0xffffffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _cred->cap_ambient.cap[0] = 0xffffffff;
 | 
				
			||||||
 | 
					  _cred->cap_ambient.cap[1] = 0xffffffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pr_debug(MTAG "PID %d: capabilities changed\n", task->pid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t proc_pid_write(struct file *file, const char __user *buffer,
 | 
				
			||||||
 | 
					  size_t count, loff_t *ppos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  unsigned long long  pid;
 | 
				
			||||||
 | 
					  struct pid         *pid_struct = 0;
 | 
				
			||||||
 | 
					  struct task_struct *task;
 | 
				
			||||||
 | 
					  int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Read the target PID from the user buffer
 | 
				
			||||||
 | 
					  if (count < 0) {
 | 
				
			||||||
 | 
					    pr_err(MTAG "read failed. size %lu\n", count);
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *ppos = count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = kstrtoull_from_user(buffer, count, 10, &pid);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							pr_err(MTAG "read PID failed %d\n", ret);
 | 
				
			||||||
 | 
							return count;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_info(MTAG "Got PID %llu\n", pid);
 | 
				
			||||||
 | 
						*ppos = count;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					  pid_struct = find_get_pid(pid);
 | 
				
			||||||
 | 
					  if (pid_struct == NULL) {
 | 
				
			||||||
 | 
					    pr_err(MTAG "find_get_pid() failed\n");
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Find the task_struct corresponding to the given PID
 | 
				
			||||||
 | 
					  task = pid_task(pid_struct, PIDTYPE_PID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (task == NULL) {
 | 
				
			||||||
 | 
					    pr_err(MTAG "Could not find process with PID %llu\n", pid);
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (task->cred == NULL /*|| task->real_cred*/) {
 | 
				
			||||||
 | 
					    pr_err(MTAG "task->cred == NULL\n");
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    rcu_read_lock();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    set_task_uids_gids_to_zero(task);
 | 
				
			||||||
 | 
					    change_process_capabilities(task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rcu_read_unlock();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static struct proc_ops proc_fops = {
 | 
				
			||||||
 | 
					  //.proc_read  = porc_pid_read,
 | 
				
			||||||
 | 
					    .proc_write = proc_pid_write,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static struct file_operations proc_fops = {
 | 
				
			||||||
 | 
					    .owner      = THIS_MODULE,
 | 
				
			||||||
 | 
					  //.read       = proc_pid_read,
 | 
				
			||||||
 | 
					    .write      = proc_pid_write,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct proc_dir_entry *ent = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sumo_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  pr_info(SUMO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create `/proc/sumo` file
 | 
				
			||||||
 | 
					  ent = proc_create("sumo", 0666, NULL, &proc_fops); 
 | 
				
			||||||
 | 
					  if (ent)
 | 
				
			||||||
 | 
					    pr_info(MTAG "Created /proc/sumo\n");
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    pr_err(MTAG "Unable to created /proc/sumo\n");
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sumo_exit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (ent) 
 | 
				
			||||||
 | 
					    proc_remove(ent);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module_init(sumo_init);
 | 
				
			||||||
 | 
					module_exit(sumo_exit);
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user