euid, ruid, suid

Tip

AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:HackTricks Training AWS Red Team Expert (ARTE)
GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training GCP Red Team Expert (GRTE) Azure ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks μ§€μ›ν•˜κΈ°

μ‚¬μš©μž 식별 λ³€μˆ˜

  • ruid: μ‹€μ œ μ‚¬μš©μž IDλŠ” ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹œμž‘ν•œ μ‚¬μš©μžλ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • euid: 유효 μ‚¬μš©μž ID둜 μ•Œλ €μ Έ 있으며, μ‹œμŠ€ν…œμ΄ ν”„λ‘œμ„ΈμŠ€ κΆŒν•œμ„ ν™•μΈν•˜λŠ” 데 μ‚¬μš©ν•˜λŠ” μ‚¬μš©μž 신원을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 일반적으둜 euidλŠ” ruid와 μΌμΉ˜ν•˜μ§€λ§Œ, SetUID λ°”μ΄λ„ˆλ¦¬ μ‹€ν–‰κ³Ό 같은 κ²½μš°μ—λŠ” euidκ°€ 파일 μ†Œμœ μžμ˜ 신원을 μ·¨ν•˜μ—¬ νŠΉμ • μž‘μ—… κΆŒν•œμ„ λΆ€μ—¬ν•©λ‹ˆλ‹€.
  • suid: 이 μ €μž₯된 μ‚¬μš©μž IDλŠ” 높은 κΆŒν•œμ˜ ν”„λ‘œμ„ΈμŠ€(일반적으둜 root둜 μ‹€ν–‰)κ°€ νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ μΌμ‹œμ μœΌλ‘œ κΆŒν•œμ„ 포기해야 ν•  λ•Œ μ€‘μš”ν•˜λ©°, 이후 λ‹€μ‹œ 초기 μƒμŠΉλœ μƒνƒœλ₯Ό νšŒλ³΅ν•©λ‹ˆλ‹€.

μ€‘μš” μ°Έκ³  사항

root둜 μ‹€ν–‰λ˜μ§€ μ•ŠλŠ” ν”„λ‘œμ„ΈμŠ€λŠ” ν˜„μž¬ ruid, euid λ˜λŠ” suid와 μΌμΉ˜ν•˜λ„λ‘ euidλ₯Ό μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

set*uid ν•¨μˆ˜ μ΄ν•΄ν•˜κΈ°

  • setuid: 초기 κ°€μ •κ³ΌλŠ” 달리, setuidλŠ” 주둜 ruidκ°€ μ•„λ‹Œ euidλ₯Ό μˆ˜μ •ν•©λ‹ˆλ‹€. 특히, κΆŒν•œμ΄ μžˆλŠ” ν”„λ‘œμ„ΈμŠ€μ˜ 경우, μ§€μ •λœ μ‚¬μš©μž(μ’…μ’… root)와 ν•¨κ»˜ ruid, euid, suidλ₯Ό μ •λ ¬ν•˜μ—¬ μ΄λŸ¬ν•œ IDλ₯Ό κ°•ν™”ν•©λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ setuid man pageμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • setreuid 및 setresuid: μ΄λŸ¬ν•œ ν•¨μˆ˜λŠ” ruid, euid, suid의 λ―Έμ„Έ 쑰정을 ν—ˆμš©ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ κ·Έ κΈ°λŠ₯은 ν”„λ‘œμ„ΈμŠ€μ˜ κΆŒν•œ μˆ˜μ€€μ— 따라 λ‹¬λΌμ§‘λ‹ˆλ‹€. λΉ„-root ν”„λ‘œμ„ΈμŠ€μ˜ 경우, μˆ˜μ •μ€ ν˜„μž¬ ruid, euid, suid의 κ°’μœΌλ‘œ μ œν•œλ©λ‹ˆλ‹€. 반면, root ν”„λ‘œμ„ΈμŠ€λ‚˜ CAP_SETUID κΆŒν•œμ΄ μžˆλŠ” ν”„λ‘œμ„ΈμŠ€λŠ” μ΄λŸ¬ν•œ ID에 μž„μ˜μ˜ 값을 ν• λ‹Ήν•  수 μžˆμŠ΅λ‹ˆλ‹€. 더 λ§Žμ€ μ •λ³΄λŠ” setresuid man page와 setreuid man pageμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ κΈ°λŠ₯은 λ³΄μ•ˆ λ©”μ»€λ‹ˆμ¦˜μ΄ μ•„λ‹ˆλΌ ν”„λ‘œκ·Έλž¨μ΄ λ‹€λ₯Έ μ‚¬μš©μžμ˜ 신원을 μ±„νƒν•˜κΈ° μœ„ν•΄ 유효 μ‚¬μš©μž IDλ₯Ό λ³€κ²½ν•˜λŠ” 것과 같은 μ˜λ„λœ μž‘μ—… 흐름을 μ΄‰μ§„ν•˜κΈ° μœ„ν•΄ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

특히, setuidλŠ” root둜의 κΆŒν•œ μƒμŠΉμ„ μœ„ν•œ 일반적인 방법일 수 μžˆμ§€λ§Œ(λͺ¨λ“  IDλ₯Ό root둜 μ •λ ¬ν•˜λ―€λ‘œ), μ΄λŸ¬ν•œ ν•¨μˆ˜ κ°„μ˜ 차이λ₯Ό μ΄ν•΄ν•˜κ³  λ‹€μ–‘ν•œ μ‹œλ‚˜λ¦¬μ˜€μ—μ„œ μ‚¬μš©μž ID λ™μž‘μ„ μ‘°μž‘ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.

λ¦¬λˆ…μŠ€μ—μ„œ ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ λ©”μ»€λ‹ˆμ¦˜

execve μ‹œμŠ€ν…œ 호좜

  • κΈ°λŠ₯: execveλŠ” 첫 번째 μΈμˆ˜μ— μ˜ν•΄ κ²°μ •λœ ν”„λ‘œκ·Έλž¨μ„ μ‹œμž‘ν•©λ‹ˆλ‹€. 두 개의 λ°°μ—΄ 인수, 인수용 argv와 ν™˜κ²½μš© envpλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
  • λ™μž‘: 호좜자의 λ©”λͺ¨λ¦¬ 곡간을 μœ μ§€ν•˜μ§€λ§Œ μŠ€νƒ, νž™ 및 데이터 μ„Έκ·Έλ¨ΌνŠΈλ₯Ό μƒˆλ‘œ κ³ μΉ©λ‹ˆλ‹€. ν”„λ‘œκ·Έλž¨μ˜ μ½”λ“œλŠ” μƒˆ ν”„λ‘œκ·Έλž¨μœΌλ‘œ λŒ€μ²΄λ©λ‹ˆλ‹€.
  • μ‚¬μš©μž ID 보쑴:
  • ruid, euid 및 μΆ”κ°€ κ·Έλ£Ή IDλŠ” λ³€κ²½λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • μƒˆ ν”„λ‘œκ·Έλž¨μ— SetUID λΉ„νŠΈκ°€ μ„€μ •λœ 경우 euid에 λ―Έμ„Έν•œ λ³€ν™”κ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ‹€ν–‰ ν›„ suidλŠ” euidμ—μ„œ μ—…λ°μ΄νŠΈλ©λ‹ˆλ‹€.
  • λ¬Έμ„œ: μžμ„Έν•œ μ •λ³΄λŠ” execve man pageμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

system ν•¨μˆ˜

  • κΈ°λŠ₯: execve와 달리 system은 forkλ₯Ό μ‚¬μš©ν•˜μ—¬ μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό μƒμ„±ν•˜κ³  ν•΄λ‹Ή μžμ‹ ν”„λ‘œμ„ΈμŠ€ λ‚΄μ—μ„œ λͺ…령을 μ‹€ν–‰ν•©λ‹ˆλ‹€.
  • λͺ…λ Ή μ‹€ν–‰: shλ₯Ό 톡해 λͺ…령을 μ‹€ν–‰ν•˜λ©°, execl("/bin/sh", "sh", "-c", command, (char *) NULL);λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
  • λ™μž‘: execl은 execve의 ν•œ ν˜•νƒœλ‘œ, μƒˆλ‘œμš΄ μžμ‹ ν”„λ‘œμ„ΈμŠ€μ˜ λ§₯λ½μ—μ„œ μœ μ‚¬ν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€.
  • λ¬Έμ„œ: μΆ”κ°€ μ •λ³΄λŠ” system man pageμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

SUID와 ν•¨κ»˜ν•˜λŠ” bash 및 sh의 λ™μž‘

  • bash:
  • euid와 ruid의 처리 방식에 영ν–₯을 λ―ΈμΉ˜λŠ” -p μ˜΅μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€.
  • -pκ°€ μ—†μœΌλ©΄, bashλŠ” euidκ°€ ruid와 λ‹€λ₯Ό 경우 euidλ₯Ό ruid둜 μ„€μ •ν•©λ‹ˆλ‹€.
  • -pκ°€ 있으면, 초기 euidκ°€ λ³΄μ‘΄λ©λ‹ˆλ‹€.
  • 더 λ§Žμ€ μ„ΈλΆ€μ •λ³΄λŠ” bash man pageμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • sh:
  • bash의 -p와 μœ μ‚¬ν•œ λ©”μ»€λ‹ˆμ¦˜μ΄ μ—†μŠ΅λ‹ˆλ‹€.
  • μ‚¬μš©μž ID와 κ΄€λ ¨λœ λ™μž‘μ€ λͺ…μ‹œμ μœΌλ‘œ μ–ΈκΈ‰λ˜μ§€ μ•ŠμœΌλ©°, -i μ˜΅μ…˜ ν•˜μ—μ„œ euid와 ruid의 동등성을 κ°•μ‘°ν•©λ‹ˆλ‹€.
  • μΆ”κ°€ μ •λ³΄λŠ” sh man pageμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ λ©”μ»€λ‹ˆμ¦˜μ€ μž‘λ™ 방식이 λ‹€λ₯΄λ©°, ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜κ³  μ „ν™˜ν•˜λŠ” 데 λ‹€μ–‘ν•œ μ˜΅μ…˜μ„ μ œκ³΅ν•˜λ©°, μ‚¬μš©μž IDκ°€ κ΄€λ¦¬λ˜κ³  λ³΄μ‘΄λ˜λŠ” 방식에 νŠΉμ •ν•œ λ‰˜μ•™μŠ€κ°€ μžˆμŠ΅λ‹ˆλ‹€.

μ‹€ν–‰μ—μ„œ μ‚¬μš©μž ID λ™μž‘ ν…ŒμŠ€νŠΈ

μ˜ˆμ œλŠ” https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jailμ—μ„œ κ°€μ Έμ™”μœΌλ©°, μΆ”κ°€ 정보λ₯Ό ν™•μΈν•˜μ„Έμš”.

사둀 1: systemκ³Ό ν•¨κ»˜ setuid μ‚¬μš©

λͺ©ν‘œ: systemκ³Ό bashλ₯Ό sh둜 μ‘°ν•©ν–ˆμ„ λ•Œ setuid의 효과λ₯Ό μ΄ν•΄ν•©λ‹ˆλ‹€.

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은 shμ—μ„œ bash둜의 심볼릭 링크둜 인해 /bin/bash -c idλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€.
  • bashλŠ” -p 없이 euidλ₯Ό ruid와 μΌμΉ˜μ‹œν‚€λ―€λ‘œ λ‘˜ λ‹€ 99 (nobody)κ°€ λ©λ‹ˆλ‹€.

μΌ€μ΄μŠ€ 2: systemκ³Ό ν•¨κ»˜ setreuid μ‚¬μš©

C μ½”λ“œ:

#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λ₯Ό ν˜ΈμΆœν•˜λ©°, μ‚¬μš©μž ID의 λ™λ“±μ„±μœΌλ‘œ 인해 이λ₯Ό μœ μ§€ν•˜μ—¬ 사싀상 frank둜 μž‘λ™ν•©λ‹ˆλ‹€.

사둀 3: execve와 ν•¨κ»˜ setuid μ‚¬μš©

λͺ©ν‘œ: 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λŠ” setuid의 νš¨κ³Όμ— 따라 1000으둜 μ„€μ •λ©λ‹ˆλ‹€.

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κ°€ setuid에 μ˜ν•΄ 1000으둜 μ„€μ •λ˜μ—ˆμ§€λ§Œ, bashλŠ” -pκ°€ μ—†κΈ° λ•Œλ¬Έμ— ruid(99)둜 euidλ₯Ό μž¬μ„€μ •ν•©λ‹ˆλ‹€.

C μ½”λ“œ 예제 3 (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

References

Tip

AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:HackTricks Training AWS Red Team Expert (ARTE)
GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training GCP Red Team Expert (GRTE) Azure ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks μ§€μ›ν•˜κΈ°