11 KiB
euid, ruid, suid
{% hint style="success" %}
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Aprofunde sua experiência em Segurança Móvel com a 8kSec Academy. Domine a segurança de iOS e Android através de nossos cursos autônomos e obtenha certificação:
{% embed url="https://academy.8ksec.io/" %}
Variáveis de Identificação do Usuário
ruid
: O ID do usuário real denota o usuário que iniciou o processo.euid
: Conhecido como o ID do usuário efetivo, representa a identidade do usuário utilizada pelo sistema para determinar os privilégios do processo. Geralmente,euid
refleteruid
, exceto em casos como a execução de um binário SetUID, ondeeuid
assume a identidade do proprietário do arquivo, concedendo assim permissões operacionais específicas.suid
: Este ID do usuário salvo é fundamental quando um processo de alto privilégio (normalmente executando como root) precisa temporariamente renunciar a seus privilégios para realizar certas tarefas, apenas para depois recuperar seu status elevado inicial.
Nota Importante
Um processo que não opera sob root pode apenas modificar seu euid
para corresponder ao ruid
, euid
ou suid
atuais.
Compreendendo as Funções set*uid
setuid
: Ao contrário das suposições iniciais,setuid
modifica principalmenteeuid
em vez deruid
. Especificamente, para processos privilegiados, alinharuid
,euid
esuid
com o usuário especificado, frequentemente root, solidificando efetivamente esses IDs devido aosuid
que sobrepõe. Informações detalhadas podem ser encontradas na página do manual setuid.setreuid
esetresuid
: Essas funções permitem o ajuste sutil deruid
,euid
esuid
. No entanto, suas capacidades dependem do nível de privilégio do processo. Para processos não-root, as modificações são restritas aos valores atuais deruid
,euid
esuid
. Em contraste, processos root ou aqueles com a capacidadeCAP_SETUID
podem atribuir valores arbitrários a esses IDs. Mais informações podem ser obtidas na página do manual setresuid e na página do manual setreuid.
Essas funcionalidades não são projetadas como um mecanismo de segurança, mas para facilitar o fluxo operacional pretendido, como quando um programa adota a identidade de outro usuário alterando seu ID de usuário efetivo.
Notavelmente, enquanto setuid
pode ser uma escolha comum para elevação de privilégios para root (já que alinha todos os IDs a root), diferenciar entre essas funções é crucial para entender e manipular comportamentos de ID de usuário em diferentes cenários.
Mecanismos de Execução de Programas no Linux
Chamada de Sistema execve
- Funcionalidade:
execve
inicia um programa, determinado pelo primeiro argumento. Ele aceita dois argumentos de array,argv
para argumentos eenvp
para o ambiente. - Comportamento: Retém o espaço de memória do chamador, mas atualiza a pilha, heap e segmentos de dados. O código do programa é substituído pelo novo programa.
- Preservação do ID do Usuário:
ruid
,euid
e IDs de grupo suplementares permanecem inalterados.euid
pode ter mudanças sutis se o novo programa tiver o bit SetUID definido.suid
é atualizado a partir deeuid
após a execução.- Documentação: Informações detalhadas podem ser encontradas na página do manual
execve
.
Função system
- Funcionalidade: Ao contrário de
execve
,system
cria um processo filho usandofork
e executa um comando dentro desse processo filho usandoexecl
. - Execução de Comando: Executa o comando via
sh
comexecl("/bin/sh", "sh", "-c", command, (char *) NULL);
. - Comportamento: Como
execl
é uma forma deexecve
, opera de maneira semelhante, mas no contexto de um novo processo filho. - Documentação: Mais informações podem ser obtidas na página do manual
system
.
Comportamento de bash
e sh
com SUID
bash
:- Tem uma opção
-p
que influencia comoeuid
eruid
são tratados. - Sem
-p
,bash
defineeuid
pararuid
se eles inicialmente diferirem. - Com
-p
, oeuid
inicial é preservado. - Mais detalhes podem ser encontrados na página do manual
bash
. sh
:- Não possui um mecanismo semelhante ao
-p
embash
. - O comportamento em relação aos IDs de usuário não é explicitamente mencionado, exceto sob a opção
-i
, enfatizando a preservação da igualdade entreeuid
eruid
. - Informações adicionais estão disponíveis na página do manual
sh
.
Esses mecanismos, distintos em sua operação, oferecem uma gama versátil de opções para executar e transitar entre programas, com nuances específicas em como os IDs de usuário são gerenciados e preservados.
Testando Comportamentos de ID de Usuário em Execuções
Exemplos retirados de https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail, confira para mais informações
Caso 1: Usando setuid
com system
Objetivo: Compreender o efeito de setuid
em combinação com system
e bash
como sh
.
Código C:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
system("id");
return 0;
}
Compilação e Permissões:
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
Análise:
ruid
eeuid
começam como 99 (ninguém) e 1000 (frank), respectivamente.setuid
alinha ambos para 1000.system
executa/bin/bash -c id
devido ao symlink de sh para bash.bash
, sem-p
, ajustaeuid
para corresponder aruid
, resultando em ambos sendo 99 (ninguém).
Caso 2: Usando setreuid com system
Código C:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setreuid(1000, 1000);
system("id");
return 0;
}
Compilação e Permissões:
oxdf@hacky$ gcc b.c -o /mnt/nfsshare/b; chmod 4755 /mnt/nfsshare/b
Execução e Resultado:
bash-4.2$ $ ./b
uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Análise:
setreuid
define tanto ruid quanto euid para 1000.system
invoca bash, que mantém os IDs de usuário devido à sua igualdade, operando efetivamente como frank.
Caso 3: Usando setuid com execve
Objetivo: Explorar a interação entre setuid e execve.
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
execve("/usr/bin/id", NULL, NULL);
return 0;
}
Execução e Resultado:
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
Análise:
ruid
permanece 99, mas euid é definido como 1000, de acordo com o efeito do setuid.
Exemplo de Código C 2 (Chamando Bash):
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
execve("/bin/bash", NULL, NULL);
return 0;
}
Execução e Resultado:
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
Análise:
- Embora
euid
esteja definido como 1000 porsetuid
,bash
redefine euid pararuid
(99) devido à ausência de-p
.
Exemplo de Código C 3 (Usando 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;
}
Execução e Resultado:
bash-4.2$ $ ./e
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) euid=100
Referências
Aprofunde sua experiência em Segurança Móvel com a 8kSec Academy. Domine a segurança de iOS e Android através de nossos cursos autoguiados e obtenha certificação:
{% embed url="https://academy.8ksec.io/" %}
{% hint style="success" %}
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Suporte ao HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para os repositórios do HackTricks e HackTricks Cloud.