euid, ruid, suid
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Змінні ідентифікації користувача
ruid: реальний ідентифікатор користувача позначає користувача, який ініціював процес.euid: Відомий як ефективний ідентифікатор користувача, він представляє ідентичність користувача, яку система використовує для визначення привілеїв процесу. Як правило,euidвідображаєruid, за винятком випадків, таких як виконання бінарного файлу з SetUID, колиeuidприймає ідентичність власника файлу, надаючи таким чином певні операційні дозволи.suid: Цей збережений ідентифікатор користувача є важливим, коли процес з високими привілеями (зазвичай працює як root) тимчасово повинен відмовитися від своїх привілеїв для виконання певних завдань, а потім знову відновити свій початковий підвищений статус.
Важлива примітка
Процес, що не працює під root, може змінювати свій euid лише на відповідність поточному ruid, euid або suid.
Розуміння функцій set*uid
setuid: На відміну від початкових припущень,setuidв основному змінюєeuid, а неruid. Конкретно, для привілейованих процесів він вирівнюєruid,euidіsuidз вказаним користувачем, часто root, ефективно закріплюючи ці ідентифікатори через переважаючийsuid. Детальні відомості можна знайти на setuid man page.setreuidтаsetresuid: Ці функції дозволяють тонке налаштуванняruid,euidіsuid. Однак їх можливості залежать від рівня привілеїв процесу. Для процесів, що не є root, зміни обмежуються поточними значеннямиruid,euidіsuid. У свою чергу, процеси root або ті, що мають можливістьCAP_SETUID, можуть призначати довільні значення цим ідентифікаторам. Більше інформації можна отримати з setresuid man page та setreuid man page.
Ці функціональні можливості не призначені як механізм безпеки, а для полегшення запланованого операційного потоку, наприклад, коли програма приймає ідентичність іншого користувача, змінюючи свій ефективний ідентифікатор користувача.
Варто зазначити, що хоча setuid може бути звичайним способом підвищення привілеїв до root (оскільки він вирівнює всі ідентифікатори до root), важливо розрізняти ці функції для розуміння та маніпулювання поведінкою ідентифікаторів користувача в різних сценаріях.
Механізми виконання програм у Linux
execve Системний виклик
- Функціональність:
execveініціює програму, визначену першим аргументом. Він приймає два масиви аргументів,argvдля аргументів іenvpдля середовища. - Поведение: Він зберігає простір пам’яті виклику, але оновлює стек, купу та сегменти даних. Код програми замінюється новою програмою.
- Збереження ідентифікатора користувача:
ruid,euidта додаткові групові ідентифікатори залишаються незмінними.euidможе мати тонкі зміни, якщо нова програма має встановлений біт SetUID.suidоновлюється зeuidпісля виконання.- Документація: Детальну інформацію можна знайти на
execveman page.
system Функція
- Функціональність: На відміну від
execve,systemстворює дочірній процес за допомогоюforkі виконує команду в цьому дочірньому процесі за допомогоюexecl. - Виконання команди: Виконує команду через
shзexecl("/bin/sh", "sh", "-c", command, (char *) NULL);. - Поведение: Оскільки
execlє формоюexecve, він працює подібно, але в контексті нового дочірнього процесу. - Документація: Додаткову інформацію можна отримати з
systemman page.
Поведение bash та sh з SUID
bash:- Має опцію
-p, що впливає на те, як обробляютьсяeuidтаruid. - Без
-pbashвстановлюєeuidнаruid, якщо вони спочатку відрізняються. - З
-pпочатковийeuidзберігається. - Більше деталей можна знайти на
bashman page. sh:- Не має механізму, подібного до
-pвbash. - Поведінка щодо ідентифікаторів користувача не згадується явно, за винятком опції
-i, що підкреслює збереження рівностіeuidтаruid. - Додаткова інформація доступна на
shman page.
Ці механізми, які відрізняються за своєю роботою, пропонують різноманітні варіанти для виконання та переходу між програмами, з конкретними нюансами в тому, як управляються та зберігаються ідентифікатори користувачів.
Тестування поведінки ідентифікаторів користувача в виконаннях
Приклади взято з https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail, перевірте його для отримання додаткової інформації
Випадок 1: Використання setuid з system
Мета: Розуміння впливу setuid у поєднанні з system та bash як sh.
C Код:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
system("id");
return 0;
}
Компиляція та дозволи:
oxdf@hacky$ gcc a.c -o /mnt/nfsshare/a;
oxdf@hacky$ chmod 4755 /mnt/nfsshare/a
bash-4.2$ $ ./a
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Аналіз:
ruidтаeuidпочинають з 99 (nobody) та 1000 (frank) відповідно.setuidвирівнює обидва до 1000.systemвиконує/bin/bash -c idчерез символічне посилання з sh на bash.bash, без-p, коригуєeuid, щоб відповідатиruid, в результаті чого обидва стають 99 (nobody).
Випадок 2: Використання setreuid з system
C Code:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setreuid(1000, 1000);
system("id");
return 0;
}
Компиляція та дозволи:
oxdf@hacky$ gcc b.c -o /mnt/nfsshare/b; chmod 4755 /mnt/nfsshare/b
Виконання та Результат:
bash-4.2$ $ ./b
uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Аналіз:
setreuidвстановлює як ruid, так і euid на 1000.systemвикликає bash, який підтримує ідентифікатори користувачів через їхню рівність, фактично діючи як frank.
Випадок 3: Використання setuid з execve
Мета: Дослідження взаємодії між setuid та execve.
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
execve("/usr/bin/id", NULL, NULL);
return 0;
}
Виконання та Результат:
bash-4.2$ $ ./c
uid=99(nobody) gid=99(nobody) euid=1000(frank) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Аналіз:
ruidзалишається 99, але euid встановлено на 1000, відповідно до ефекту setuid.
C Код Приклад 2 (Виклик Bash):
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
execve("/bin/bash", NULL, NULL);
return 0;
}
Виконання та Результат:
bash-4.2$ $ ./d
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Аналіз:
- Хоча
euidвстановлено на 1000 за допомогоюsetuid,bashскидає euid наruid(99) через відсутність-p.
C Code Example 3 (Using bash -p):
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
char *const paramList[10] = {"/bin/bash", "-p", NULL};
setuid(1000);
execve(paramList[0], paramList, NULL);
return 0;
}
Виконання та Результат:
bash-4.2$ $ ./e
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) euid=100
Посилання
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
HackTricks

