Для удобства использования модуля, я собрал его в rpm’ки для el6/el7.
CentOS6 / RHEL6 (x86_64 only)
1 2 3 4 |
# cd /etc/yum.repos.d # wget https://ibuffed.com/pub/repo/el6/ibuffed-com.repo # yum install kmod-ugidctl # modprobe ugidctl |
CentOS7 / RHEL7
1 2 3 4 |
# cd /etc/yum.repos.d # wget https://ibuffed.com/pub/repo/el7/ibuffed-com.repo # yum install kmod-ugidctl # modprobe ugidctl |
Простой тест, показывающий как использовать /dev/ugidctl
- Открою устройство
- Получу ключ для доступа к ugidctl
- Скажу ugidctl’ю, что хочу прыгать по uid’ам и gid’ам 48,99,65535
- Сброшу привилегии стандартными вызовами setgroups(2)/setgid(2)/setuid(2)
- Попробую стать пользователем 48 (это apache в el6/el7) через ugidctl
- Попробую стать пользователем 99 (это nobody в el6/el7) через ugidctl
- Попробую вернуться к правам пользователя с uid’ом 65535, gid’ом 65535 и одной дополнительной группой 65535
Для краткости, опущу проверки ошибок, освобождение памяти и закрытие файловых дескрипторов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
/* * This file is released under the GPL. */ #include <sys/types.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <stdlib.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <grp.h> #include "ugidctl.h" int main(void) { int fd; struct ugidctl_key_rq *key; struct ugidctl_add_rq *add_uids; struct ugidctl_add_rq *add_gids; struct ugidctl_setid_rq *setid; struct ugidctl_setgroups_rq *setgids; uid_t uid; gid_t gid; // open device fd = open("/dev/ugidctl", O_RDONLY); // get access key key = malloc(sizeof(*key)); ioctl(fd, UGIDCTLIO_GETKEY, key); // allow setuid to 48,99 and 65535 add_uids = malloc(sizeof(*add_uids) + 3 * sizeof(uid_t)); add_uids->count = 3; add_uids->uid_list[0] = 99; add_uids->uid_list[1] = 48; add_uids->uid_list[2] = 65535; ioctl(fd, UGIDCTLIO_ADDUIDLIST, add_uids); // allow setgid/setgroups to 48,99 and 65535 add_gids = malloc(sizeof(*add_gids) + 3 * sizeof(gid_t)); add_gids->count = 3; add_gids->gid_list[0] = 99; add_gids->gid_list[1] = 48; add_gids->gid_list[2] = 65535; ioctl(fd, UGIDCTLIO_ADDGIDLIST, add_gids); // become user 65535 uid = 65535; gid = 65535; setgroups(1, &gid); setgid(gid); setuid(uid); system("id"); // init setuid/setgid/setgroups request structs setid = malloc(sizeof(*setid)); memcpy(setid->key, key->key, sizeof(key->key)); setgids = malloc(sizeof(*setgids) + 1 * sizeof(gid_t)); memcpy(setgids->key, key->key, sizeof(key->key)); // become user 48 setid->uid = 48; ioctl(fd, UGIDCTLIO_SETUID, setid); setid->gid = 48; ioctl(fd, UGIDCTLIO_SETGID, setid); setgids->count = 1; setgids->list[0] = 48; ioctl(fd, UGIDCTLIO_SETGROUPS, setgids); system("id"); // become user 99 setid->uid = 99; ioctl(fd, UGIDCTLIO_SETUID, setid); setid->gid = 99; ioctl(fd, UGIDCTLIO_SETGID, setid); setgids->count = 1; setgids->list[0] = 99; ioctl(fd, UGIDCTLIO_SETGROUPS, setgids); system("id"); // back to 65535 setid->uid = 65535; ioctl(fd, UGIDCTLIO_SETUID, setid); setid->gid = 65535; ioctl(fd, UGIDCTLIO_SETGID, setid); setgids->count = 1; setgids->list[0] = 65535; ioctl(fd, UGIDCTLIO_SETGROUPS, setgids); system("id"); return 0; } |
Результат работы теста:
1 2 3 4 5 6 |
# gcc -Wall -o ugidctl-test ugidctl-test.c # ./ugidctl-test uid=65545 gid=65535 groups=65535 uid=48(apache) gid=48(apache) groups=48(apache) uid=99(nobody) gid=99(nobody) groups=99(nobody) uid=65535 gid=65535 groups=65535 |