
Framework de manipulation de machines virtuelles
Mofos est un outil conçu pour créer, exécuter et gérer des machines virtuelles. Il s'appuie sur Libvirt/QEMU/KVM et Python, ce qui le rend compatible avec toute distribution Linux. Fortement inspiré de Qubes OS (https://www.qubes-os.org/), Mofos vise à reproduire nombre de ses fonctionnalités.
L'outil a été largement testé sur Debian avec des machines virtuelles basées sur Debian. Bien que d'autres distributions Linux devraient fonctionner, une configuration supplémentaire peut être nécessaire. Plus de détails à venir.
Mofos propose un ensemble de fonctionnalités axées sur la gestion sécurisée des machines virtuelles, notamment :
Une machine mofos se compose de deux disques combinés à l'aide d'overlayfs. Le premier disque, appelé couche inférieure, est un disque modèle en lecture seule, tandis que le second disque stocke toutes les modifications apportées par la machine virtuelle. Ce disque modèle est partagé entre plusieurs machines virtuelles. Par conséquent, créer une nouvelle machine virtuelle ne nécessite que le clonage d'un disque vide déjà partitionné pour contenir les données modifiées. Cette approche garantit que les nouvelles machines virtuelles peuvent être créées rapidement, tout en permettant de mettre à jour le modèle indépendamment. Toute mise à jour du modèle prendra effet sur les machines virtuelles dépendantes lors de leur prochain redémarrage.
Selon la distribution Linux, le Makefile peut être utilisé pour générer un paquet deb ou installer directement les fichiers.```
make deb
apt install ./mofos-VERSION.deb
Lors de l'installation via `apt`, divers paramètres vous seront demandés. Les options par défaut peuvent généralement être acceptées. Le seul paramètre qui requiert votre attention est l'adresse de sous-réseau utilisée par le réseau libvirt mofos (par défaut : `192.168.90.0/24`).
OU
Installez les dépendances suivantes :
- guestfs-tools
- libnotify-bin
- libvirt
- libvirt-clients
- libvirt-daemon
- make
- python3-click
- python3-click-completion
- python3-colorama
- python3-cryptography
- python3-dbus
- python3-jinja2
- python3-lxml
- python3-prettytable
- python3-pyroute2
- python3-tqdm
- qemu-system-common
- qemu-system-modules-spice
- socat
- spice-client-gtk
- sudo
- virtinst
- virt-install
- virtiofsd
- virt-manager
- virt-viewer```
make install_files
Selon la distribution, les fichiers Python copiés dans /usr/lib/python3/dist-packages peuvent ne pas être détectés par l'interpréteur Python et doivent être placés ailleurs. Par exemple, sur Fedora, les fichiers Python doivent être copiés dans /usr/lib/python3.11/site-packages.
[!WARNING] Attention, depuis Debian trixie,
xpran'est plus empaqueté, vous devez l'installer manuellement depuis ses dépôts personnalisés. Voir https://github.com/Xpra-org/xpra/wiki/Download#-for-debian-based-distributions pour des instructions détaillées.
Mofos utilise la session système QEMU/KVM, donc pour permettre à la commande virsh d'accéder aux machines virtuelles et aux ressources associées, définissez la variable d'environnement LIBVIRT_DEFAULT_URI sur qemu:///system :```console
export LIBVIRT_DEFAULT_URI=qemu:///system
### Considérations de sécurité
L'utilisation de sessions système QEMU/KVM améliore l'isolation entre les machines virtuelles hôte et invitées en exécutant les instances qemu sous un utilisateur dédié (`libvirt-qemu`) et en appliquant des profils de sécurité spécifiques à chaque instance.
Cependant, par défaut, les utilisateurs ordinaires ne peuvent pas interagir avec le socket système `libvirtd` pour gérer les machines, les réseaux et d'autres ressources. Pour obtenir l'accès, les utilisateurs doivent soit être membres du groupe Unix libvirt, soit utiliser sudo. Historiquement, des vulnérabilités d'élévation de privilèges locaux ont exploité l'appartenance au groupe libvirt pour obtenir les privilèges root.
Pour atténuer ces risques, ce dépôt fournit un profil AppArmor renforcé pour le processus `libvirtd` sur les systèmes utilisant AppArmor. Ce profil restreint considérablement les endroits où `libvirtd` peut écrire des fichiers et les programmes qu'il peut exécuter.
De plus, des règles `polkit` sont incluses pour mieux contrôler les actions autorisées pour les membres du groupe `libvirt`.
Notez que les profils AppArmor sont empaquetés dans le paquet `deb` mais ne sont pas installés par la cible `install_files` du Makefile et doivent donc être installés séparément.
## Configuration de Mofos
Mofos nécessite un fichier de configuration situé dans `$HOME/.config/mofos/config.toml` avec des paramètres minimaux pour fonctionner correctement. Un exemple de configuration minimale se trouve dans `/usr/share/mofos/config.minimal.toml`, tandis qu'une configuration plus complète est documentée dans `/usr/share/mofos/config.sample.toml`.
L'erreur suivante indique que le fichier de configuration n'a pas été trouvé :```
[-] Copy the sample configuration file from /usr/share/mofos/config.minimal.toml to ~/.config/mofos/config.toml
L'erreur suivante indique que l'utilisateur actuel n'est pas membre du groupe libvirt :``` [-] libvirtError("authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'")
Les principaux paramètres de configuration à personnaliser dans les fichiers de configuration sont les suivants :
- key (chemin): Le fichier de clé privée SSH utilisé pour accéder aux machines virtuelles. Il est recommandé de créer une clé dédiée à cet effet.
- user (chaîne): Le nom d'utilisateur pour l'accès SSH aux machines virtuelles.
- root_password (valeur hachée): Le mot de passe root haché à définir lors de l'installation d'un nouveau modèle.
- root_ssh_pubkey (chaîne): La clé publique SSH à installer dans le répertoire de l'utilisateur root lors de l'installation du modèle.
De plus, les paramètres suivants doivent être configurés pour l'installation du modèle :
- ntp
- dns (facultatif si un proxy est fourni)
- proxy
## Installer un modèle
### Configurer le pare-feu
Étant donné que le processus d'installation repose sur le netboot PXE, une connexion Internet active est requise. Les règles de pare-feu suivantes doivent être configurées :```
sysctl net.ipv4.ip_forward=1
iptables -t nat -I POSTROUTING -s 192.168.90.0/24 -j MASQUERADE
iptables -t nat -I POSTROUTING -s 192.168.91.0/24 -j MASQUERADE
Ou avec nftables :``` sysctl net.ipv4.ip_forward=1 nft insert inet nat postrouting iifname "install-*" masquerade nft insert inet nat postrouting iifname "mof0" masquerade
Lorsque le paramètre `ip_forward` est défini sur 1, la chaîne FORWARD doit être configurée pour empêcher les autres appareils du réseau d'utiliser l'hôte comme routeur.
Dans l'ensemble, les règles suivantes sont recommandées :```
iptables -I INPUT -i mof0 -p udp --sport 68 --dport 67 -j ACCEPT -m comment --comment "mofos dhcp"
iptables -I INPUT -i mof0 -p udp --dport 69 -j ACCEPT -m comment --comment "mofos tftp"
iptables -I OUTPUT -o mof0 -j ACCEPT -m comment --comment "host -> mofos"
iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD -i mof0 -j ACCEPT -m comment --comment "mofos ->"
iptables -t nat -I POSTROUTING -s 192.168.90.0/24 -j MASQUERADE
iptables -t nat -I POSTROUTING -s 192.168.91.0/24 -j MASQUERADE
Ou avec nftables :```
table inet filter {
chain input {
type filter hook input priority 0; policy drop
iifname "install-*" ip daddr 255.255.255.255 udp sport 68 udp dport 67 accept comment "mofos dhcp"
iifname "mof0" ip daddr 255.255.255.255 udp sport 68 udp dport 67 accept comment "mofos dhcp"
iifname "install-*" udp dport 69 accept comment "mofos tftp"
}
chain forward {
type filter hook forward priority 0; policy drop
ct state established,related accept;
ct state invalid drop;
iifname "mof0" counter accept
iifname "install-*" counter accept
}
chain output {
type filter hook output priority 0; policy drop
oifname "mof0" counter accept
}
} table inet nat { chain postrouting { type nat hook postrouting priority 100 iifname "mof0" masquerade iifname "install-*" masquerade } }
Il est recommandé de restreindre les règles de masquerade et de transfert en fonction de vos besoins spécifiques, afin d'empêcher les machines virtuelles de mofos d'accéder à l'ensemble du réseau hôte.
L'isolation entre les machines virtuelles est automatiquement appliquée par un hook libvirt, qui nécessite nft pour fonctionner correctement.
### Installation```
mofos template create debian-template
Remarque : pour chaque commande, l'option --debug peut être utilisée pour obtenir des informations techniques détaillées en cas de comportement inattendu. Plus précisément pour cette commande, le drapeau --debug force également l'affichage d'une fenêtre graphique pour visualiser la progression de l'installation. Alternativement, l'installation peut être surveillée à l'aide de virt-manager.
Actuellement, seul le modèle Debian 12 est pris en charge pour l'installation. Le dictionnaire Python ci-dessous spécifie l'image d'installation à utiliser :```python NETBOOT = { "debian-stable-amd64": { "variant": "debian11", "url": "https://deb.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz", } }
La variante est définie sur `debian11` car, dans Debian 12, la variante `osinfo` pour Debian 12 n'est pas encore installable via libvirt.
Pour installer une autre distribution, modifiez le dictionnaire situé dans `/usr/lib/python3/dist-packages/mofos/settings.py`.
Lorsque la commande ci-dessus est exécutée, Mofos télécharge les fichiers netboot et met en cache l'archive `tar.gz` dans `$HOME/.cache/template-installer`. Actuellement, si l'archive netboot existe déjà, Mofos ne la téléchargera pas à nouveau. Cela peut provoquer des erreurs si l'archive en cache est obsolète. Si de telles erreurs surviennent lors de l'installation, la suppression de l'archive en cache forcera Mofos à télécharger une version mise à jour, ce qui devrait résoudre le problème.
Ensuite, l'archive est extraite dans `/tmp`, et libvirt est configuré pour servir son contenu via TFTP.
La machine virtuelle modèle est ensuite créée et configurée pour démarrer via PXE, installant la distribution spécifiée à l'aide du fichier preseed fourni (par défaut `/usr/share/mofos/templates/debian/preseed.cfg.j2`). Ce fichier est un modèle `jinja2` ; avant de le copier dans le répertoire racine TFTP, les variables des fichiers de configuration (`ntp`, `proxy`, `dns`, `root_password`) sont injectées.
À la fin de l'installation, le script `postinstall` est placé dans le répertoire TFTP et exécuté sur le modèle. Par défaut, le script situé à `/usr/share/mofos/templates/postinstall.sh.j2` est utilisé. Ce modèle `jinja2` injecte la clé publique SSH à configurer sur le modèle.
En plus de configurer la clé publique SSH de root, les opérations suivantes sont effectuées :
- Désactiver le service SSH standard et activer un SSHD sur des sockets virtuels (vsock).
- Vider le fichier `/etc/resolv.conf`.
- Configurer le délai d'attente de GRUB à 0 seconde.
- Installer un hook initramfs qui monte l'overlayfs lorsqu'une partition étiquetée `overlay` est détectée.
Une fois l'installation terminée, la machine virtuelle libvirt est récupérée et compressée dans un fichier `qcow2` local enregistré dans le répertoire courant.```
$ mofos template create debian-template
[*] Installing debian-template
[*] Configure the SSH host key of the template
[*] Waiting for the installation to be complete
[*] Installation is complete
[*] Downloading the resulting qcow2 disk
[*] Compressing the disk
[*] Save template's public ssh host key
[+] Template installation finished
[+] Template disk is debian-template-disk.qcow2
En plus du fichier qcow2, ce processus crée également une entrée dans le fichier $HOME/.local/share/mofos/ssh.json contenant le nom de la machine et sa clé SSH publique :```json
{
"disk": {
"debian-template-disk.qcow2": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrbOdOPENEj2KeHrYLdorQe9Ez1b9Bu5agZmgNDMayy"
}
}
Ce fichier est automatiquement utilisé pendant le processus d'importation.
### Importation
L'étape suivante consiste à importer le fichier modèle `qcow2` créé dans Mofos.```
$ mofos template import debian-template debian-template-disk.qcow2 http://debian.org/debian/11
[*] Uploading debian-template-disk.qcow2 to mofos pool
[*] Creating the virtual machine debian-template
[*] Configuring the template metadata
[*] Configuring the SSH key
[+] debian-template successfully imported
Pour l'instant, la variante osinfo est obligatoire. Elles se trouvent dans le fichier :
/usr/lib/python3/dist-packages/mofos/settings.py.
Une fois importé, le modèle peut être consulté dans la commande mofos ls :```
$ mofos ls
+----+-----------------+---------+-------------+-------+-----+--------------+
| Id | Name | State | Description | Alias | Cid | IPv4 address |
+----+-----------------+---------+-------------+-------+-----+--------------+
| | debian-template | shutoff | | | | |
+----+-----------------+---------+-------------+-------+-----+--------------+
À partir de ce point, le modèle peut être démarré et accessible pour modification si nécessaire.```
$ mofos start debian-template
$ mofos ls
+----+-----------------+---------+-------------+-------+-----+----------------+
| Id | Name | State | Description | Alias | Cid | IPv4 address |
+----+-----------------+---------+-------------+-------+-----+----------------+
| 3 | debian-template | running | | | 3 | 192.168.90.202 |
+----+-----------------+---------+-------------+-------+-----+----------------+
---``` $ mofos ssh debian-template --user root root@linux:~#
## Créer le disque vide de la couche supérieure
La commande suivante crée une couche supérieure vide avec l'étiquette spécifiée sur la seule partition du disque :```
$ mofos template create-overlay-disk
Par défaut, ce disque est configuré à 50 Go mais n'occupe initialement qu'environ 100 Mo. Cette taille peut être personnalisée dans le fichier de configuration.
Remarque : Il est recommandé de toujours arrêter un modèle avant de manipuler les machines virtuelles de Mofos. Bien que l'exécution simultanée d'un modèle et de ses machines virtuelles soit prise en charge, elle peut entraîner une instabilité.``` $ mofos new test [] New virtual machine name is test [+] Virtual machine test successfully created [] Triggering post install actions [] Create SSH known_hosts entries for test [] Waiting for test to be up [+] test is ready $ mofos ssh test -u root Last login: Mon Jun 2 11:09:51 2025 from UNKNOWN root@linux:~#
Gardez à l’esprit que les connexions SSH sont établies via des sockets virtuelles, vous ne pouvez donc pas vous connecter directement en SSH à la machine nouvellement créée. Vous devez plutôt utiliser la commande `mofos ssh`. Vous pouvez également créer une configuration SSH spécifiant un `ProxyCommand `pour accéder au port SSH de la machine :```
$ mofos inventory --format ssh
Host debian-template
User user
PasswordAuthentication no
IdentityFile /home/user/.ssh/id_ed25519
ProxyCommand /usr/bin/mofos proxy-cmd %h
CanonicalizeHostname=no
Host test
User user
PasswordAuthentication no
IdentityFile /home/user/.ssh/id_ed25519
ProxyCommand /usr/bin/mofos proxy-cmd %h
CanonicalizeHostname=no
I notice that the input content for chunk 41 is missing — the message ends with "INPUT:" and no Markdown content follows. There is no text to translate. Please provide the actual chunk content so I can translate it.``` $ mofos inventory --format ssh > ~/.ssh/mofos $ echo "Include ~/.ssh/mofos" >> ~/.ssh/config $ ssh root@test Linux linux 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64
The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Jun 2 11:09:51 2025 from UNKNOWN root@linux:~#
Lors d'une session `mofos ssh`, un socket `ControlMaster` est établi au préalable pour accélérer les connexions ultérieures. C'est pourquoi le MOTD n'est pas affiché.
## Personnalisation
Pour simplifier la personnalisation des modèles et des machines virtuelles, Mofos introduit le concept de hooks et de tags. Pour chaque tag, un hook correspondant (un script Bash) peut être exécuté pour effectuer des actions automatisées sur la machine virtuelle ou le modèle cible et le configurer en conséquence.
Les hooks minimaux sont situés dans `/usr/share/mofos/hooks`. Ce sont de simples scripts Bash qui reçoivent les entrées suivantes :```
TAG=$1
NAME=$2
OS=$3
DISTRIB=$4
HOSTNAME=$5
Ce mécanisme peut être exploité avec Ansible pour exécuter des playbooks lors de l'installation du modèle :```bash #!/bin/bash
TAG=$1 NAME=$2 OS=$3 DISTRIB=$4 HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] || [ -z "${DISTRIB}" ] ; then exit 1 fi
ANSIBLE_DIRECTORY="/home/user/Documents/ansible" RANDOM_SUFFIX=$(printf "%x" $RANDOM) INVENTORY_FILE="${ANSIBLE_DIRECTORY}/inventory-${NAME}-${RANDOM_SUFFIX}.ini"
trap 'rm -f "${INVENTORY_FILE}"; exit' EXIT
cat > $INVENTORY_FILE <<EOF [all:vars] ansible_ssh_common_args="-o ProxyCommand='mofos proxy-cmd %h' -o CanonicalizeHostname=no"
[${TAG}] ${NAME}
[${DISTRIB}] ${NAME} EOF
export ANSIBLE_CONFIG="/home/user/Documents/ansible/ansible.cfg" export ANSIBLE_VERBOSITY=1
/usr/bin/ansible-playbook
-i "${INVENTORY_FILE}"
-l "${NAME}"
/home/user/Documents/ansible/playbooks/pentest/install.yml
Ce script crée dynamiquement un inventaire et exécute un playbook sur celui-ci.
### Machine virtuelle - hook de création
Lors de la création d'une machine virtuelle, un autre hook peut être utilisé, par exemple, pour randomiser le nom d'hôte.
Par défaut, Mofos génère un alias basé sur la convention de nommage Windows classique (par exemple, `DESKTOP-2BF9753`). Ce nom, ainsi que d'autres informations, est transmis au script hook :```
#!/bin/bash
TAG=$1
NAME=$2
OS=$3
DISTRIB=$4
HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] || [ -z "${OS}" ] ; then
exit 1
fi
if [ -z "${HOSTNAME}" ] ; then
HOSTNAME="${NAME}"
fi
mofos run -u root "${NAME}" "echo ${HOSTNAME} > /etc/hostname && hostname ${HOSTNAME}"
Ensuite, la configuration doit être modifiée pour activer ce hook :``` [hooks.test] new = "/home/user/.config/mofos/hooks/new.sh"
Ensuite, lors de la création de la machine virtuelle, ce script sera exécuté :```
$ mofos new test2 --tags test
[*] New virtual machine name is test2
[+] Virtual machine test2 successfully created
[*] Triggering post install actions
[*] Create SSH known_hosts entries for test2
[*] Waiting for test2 to be up
[*] Running new hook: test
[+] test2 is ready
No source text was provided to translate. The input is empty.``` $ mofos ssh test2 -u root Last login: Mon Jun 2 11:09:51 2025 from UNKNOWN root@DESKTOP-2BF9753:~#
À l'instar de la phase d'installation, les playbooks Ansible peuvent également être exécutés à ce stade. Dans ce cas, la commande `mofos inventory` peut être utilisée pour générer un inventaire Ansible, ce qui simplifie le processus de sélection et d'accès aux machines virtuelles :```
$ mofos inventory
{
"_meta": {
"hostvars": {
"debian-template": {
"ansible_host": "debian-template",
"ansible_ssh_common_args": "-o ProxyCommand='/usr/bin/mofos proxy-cmd %h' -o CanonicalizeHostname=no"
},
"test": {
"ansible_host": "test",
"ansible_ssh_common_args": "-o ProxyCommand='/usr/bin/mofos proxy-cmd %h' -o CanonicalizeHostname=no"
},
"test2": {
"ansible_host": "test2",
"ansible_ssh_common_args": "-o ProxyCommand='/usr/bin/mofos proxy-cmd %h' -o CanonicalizeHostname=no"
}
}
},
"debian": [
"debian-template",
"test",
"test2"
],
"test": [
"test2"
]
Notez que les groupes sont créés en fonction de la variante de distribution ainsi que des tags.
Ces groupes peuvent être utilisés pour charger différentes variables.
Par exemple, le script ci-dessous exécute un playbook arbitraire:```bash #!/bin/bash
TAG=$1 NAME=$2 OS=$3 DISTRIB=$4 HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] || [ -z "${OS}" ] ; then exit 1 fi
if [ -z "$HOSTNAME" ] ; then HOSTNAME=$NAME fi
if [ $OS == "windows" ] ; then TAGS="hostname,desktop" else TAGS="hostname,hosts,desktop" fi
export ANSIBLE_CONFIG="/home/user/Documents/ansible/ansible.cfg" export ANSIBLE_VERBOSITY=0
/usr/bin/ansible-playbook
-i /home/user/Documents/ansible/inventory.py
-l "${NAME}"
-t "${TAGS}"
-e "hostname=${HOSTNAME}"
/home/user/Documents/ansible/playbooks/pentest/update.yml
### Machine virtuelle - hook de démarrage
De même, le hook de démarrage est exécuté lorsqu'une machine virtuelle démarre. Il est généralement utilisé pour lancer les services requis par la machine virtuelle.
Par exemple, pour activer une intégration Windows transparente dans la machine virtuelle, vous pouvez installer `Xpra`.
Installez d'abord `ansible`:```
# apt install ansible
Ensuite, exécutez le playbook utilisateur situé dans le répertoire ansible. Avant cela, modifiez le fichier playbooks/user.yml pour mettre à jour le hash du mot de passe et la clé SSH publique à installer dans le répertoire personnel de l’utilisateur.```
~/mofos/ansible$ ls
ansible.cfg ansible.log inventory.sh playbooks
- gitlab-cli <gitlab-instance> <gitlab-user-id> - pour obtenir les informations du profil utilisateur et les URLs des projets
- gitlab-cli <gitlab-instance> <gitlab-username> --verify - pour vérifier que l'utilisateur GitLab existe
- gitlab-cli <gitlab-instance> <gitlab-username> --terminal - pour obtenir les informations du profil utilisateur et les URLs des projets comme ci-dessus, mais en désactivant la colorisation qui peut causer des problèmes dans les terminaux non interactifs
Si l'option `--cookies` est passée et qu'un fichier `cookies.txt` est spécifié, cela remplacera les cookies pour tous les autres modules. Par exemple, si vous voulez que tous les modules utilisent les mêmes cookies
gitlab --cookies cookies.txt <gitlab-instance> -c -u <username> -w wordlist.txt
blackbird --cookies cookies.txt --username <username>
ghunt --cookies cookies.txt ...
Remarque : ghunt-cli, gitlab-cli, snusbase-cli, blackbird-cli sont tous des alias pour mcore-cli ou maigret selon l'outil. Ils définissent simplement le module par défaut. Vous pouvez donc exécuter
mcore <gitlab-instance> <gitlab-username>
plutôt que
gitlab <gitlab-instance> <gitlab-username>
plus...```
$ ansible-playbook playbooks/user.yml -l test2
Using /home/user/mofos/ansible/ansible.cfg as config file
[WARNING]: Found both group and host with same name: test
PLAY [Create and configure a user]
[...]
PLAY RECAP
test2 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Après cela, vous pouvez vous connecter en SSH à ce compte utilisateur, à condition que la configuration spécifie cet utilisateur comme utilisateur par défaut :``` $ mofos ssh test2 user@DESKTOP-2BF9753:~$
Ensuite, exécutez le playbook `Xpra`. Ce playbook installe des paquets depuis les miroirs Debian. Veuillez noter que le réseau Mofos ne configure pas, par défaut, le DNS, le proxy ou la passerelle par défaut. Ces éléments doivent être configurés avant d'exécuter le playbook.
Aucune modification du playbook n'est requise par défaut.```
ansible-playbook playbooks/xpra.yml -l test2
Ce playbook installe et configure Xpra et démarre le service xpra sur la machine virtuelle.
Le service distant peut être démarré manuellement en utilisant :``` user@DESKTOP-2BF9753:~$ systemctl --user start xpra
Sinon, le service démarrera automatiquement au prochain redémarrage.
Ensuite, le service client local peut également être démarré manuellement :```
$ mofos xpra start test2
De retour sur la machine virtuelle, l’affichage doit être réglé sur :10 (par défaut), après quoi une application graphique peut être lancée et apparaîtra dans l’environnement de bureau de l’hôte.```
user@DESKTOP-2BF9753:$ export DISPLAY=:10
user@DESKTOP-2BF9753:$ xterm
Pour garantir que ce mécanisme fonctionne de manière fluide et automatique, la commande `mofos xpra` peut être lancée depuis le hook de démarrage.```bash
#!/bin/bash
TAG=$1
NAME=$2
OS=$3
DISTRIB=$4
HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] ; then
exit 1
fi
mofos xpra start "${NAME}"
Pour être informé du démarrage et de l'arrêt des machines libvirt/qemu, le hook qemu de libvirt peut être modifié pour spécifier le nom de l'utilisateur hôte (par défaut user):```
### Presse-papiers
Mofos peut également gérer le presse-papiers entre les machines virtuelles et l'hôte. L'idée est de configurer un raccourci clavier spécifique pour déclencher une connexion SSH à la machine virtuelle actuellement focalisée, soit pour récupérer le presse-papiers X11, soit pour y pousser du contenu.
Pour pousser du contenu dans le presse-papiers X11 de la machine virtuelle :```
mofos clipboard in pentest-0
Pour récupérer le contenu du presse-papiers X11 de la machine virtuelle:``` mofos clipboard out pentest-0
Pour chaque opération, mofos établira une connexion SSH vers la machine virtuelle et utilisera xclip et, sur l'hôte, `wl-copy` ou `xclip` selon la technologie de fenêtrage (wayland vs X11).
Le nom de la machine dans la trace ci-dessus peut être omis ; dans ce cas, le script identifiera la machine virtuelle ayant actuellement le focus et la ciblera.
Si vous utilisez Gnome wayland, vous devrez peut-être installer l'extension Gnome Shell [email protected] à l'aide de `sudo make install_gnome_extension`.
Vous devrez vous déconnecter puis vous reconnecter pour vous assurer que l'extension est bien installée.
### Configuration du routage entre machines
Deux options existent dans mofos pour router une VM :
- `mofos route` qui prend une passerelle et configure une `ip rule` sur l'hôte pour router la machine virtuelle via cette passerelle.
- `mofos pivot` qui prend une autre machine mofos, récupère son adresse IP et la configure comme passerelle par défaut pour la machine virtuelle actuelle.
Les deux options peuvent accepter un serveur DNS à configurer.
### Configuration du tunneling à travers les boîtes de pentest
La commande `mofos tunnel` configure un VPN SSH (`ssh -w`) pour router le trafic d'une machine mofos à travers un serveur. Cette fonctionnalité repose sur quelques configurations :
Concrètement, la commande `mofos tunnel` effectue les actions suivantes (aucune magie noire ici) :
1. Créer une interface tun locale (`sudo /usr/libexec/mofos/mofosnet.py tun add pentest_box`) et attribuer une adresse IP à cette interface.
2. Exécuter la commande `tunneling.command` sur le serveur distant ; cette commande doit créer une interface tun qui sera ensuite reliée à l'interface locale (`/usr/libexec/mofos/mofosnet.py sshvpn start pentest_box`).
3. Router le trafic d'une machine mofos via la passerelle de la boîte distante (`/usr/libexec/mofos/mofosnet.py route mofos_vm_ip gateway_ip`) ; la passerelle par défaut de la machine virtuelle mofos est également modifiée.
La commande `tunneling.command` doit être définie dans le fichier de configuration `/etc/mofos/mofosnet.toml`. Par exemple :```toml
[tunneling.command]
start = "sudo ssh-vpn start" # the peer remote address will be supplied as argv[1]
stop = "sudo ssh-vpn stop"
En ce qui concerne les commandes route et pivot, un DNS peut également être fourni pour les configurer.
La commande mofos usb permet de gérer les périphériques USB.
Les périphériques sont identifiés par leur ID (vendor_id:product_id), nécessaire pour les commandes attach et detach :```console $ mofos ls usb +-----------+------------------------------------------------+-------------+ | ID | Device | Attached to | +-----------+------------------------------------------------+-------------+ | 0bda:8153 | Realtek, RTL8153 Gigabit Ethernet Adapter | | | 046d:c077 | Logitech, Mouse | | | 0a5c:5842 | Broadcom Corp, 58200 | | | 1bcf:28d2 | CN0Y9V728LG003AGBCJZA01, Integrated_Webcam_FHD | | +-----------+------------------------------------------------+-------------+ $ mofos usb attach pentest-1 0bda:8153 $ mofos usb +-----------+------------------------------------------------+-------------+ | ID | Device | Attached to | +-----------+------------------------------------------------+-------------+ | 0bda:8153 | Realtek, RTL8153 Gigabit Ethernet Adapter | pentest-1 | | 046d:c077 | Logitech, Mouse | | | 0a5c:5842 | Broadcom Corp, 58200 | | | 1bcf:28d2 | CN0Y9V728LG003AGBCJZA01, Integrated_Webcam_FHD | | +-----------+------------------------------------------------+-------------+ $ mofos usb detach pentest-4 0bda:8153
L'option `force` détache et rattache un périphérique. Elle est couramment utilisée pour
rattacher un périphérique qui a été débranché sans avoir été préalablement détaché.
Remarque : attacher un périphérique USB n'est valable que pour la durée de vie actuelle de la machine virtuelle. Lorsque celle-ci s'arrête, le périphérique est automatiquement détaché.
### Gestion des périphériques PCI
Comme pour les périphériques USB, mofos permet d'attacher un périphérique PCI à une machine virtuelle en cours d'exécution ; les commandes sont les mêmes.
Une limitation supplémentaire concerne certains périphériques PCI qui appartiennent à un groupe. Par exemple, attacher la carte Ethernet à une machine virtuelle en cours d'exécution peut nécessiter de déplacer l'ensemble du groupe PCI dans la machine virtuelle. Comme cela ne peut pas être fait séquentiellement, ce n'est pas encore pris en charge. Cependant, pour un périphérique PCI unique tel qu'une carte réseau Wi-Fi, cela fonctionne parfaitement.
### Dossiers partagés
La commande `mofos mount` crée un dossier partagé et peut monter le nouveau système de fichiers dans un répertoire à l'intérieur de la machine virtuelle. La commande `mofos umount` démontera le répertoire et supprimera le dossier partagé de la configuration de la machine virtuelle.
Ce mécanisme repose sur la technologie `virtiofsd` qui nécessite l'activation de la mémoire partagée ; cela est désormais fait par défaut lors de la création d'une machine virtuelle. Sinon, la commande suivante l'activera :```console
virt-xml -c qemu:///system --edit --memorybacking source.type=memfd,access.mode=shared DOMAIN
De plus, les politiques AppArmor fournies restreignent les répertoires qui peuvent être partagés par l'hôte. Cela vise à empêcher votre utilisateur de configurer un partage sur le répertoire /etc ou la racine du système de fichiers et de le modifier en utilisant les privilèges root dans la machine virtuelle. Par conséquent, il est nécessaire de modifier la politique usr.lib.qemu.virtiofsd pour autoriser le partage de répertoires arbitraires.
Deux lignes doivent être adaptées :``` @{SHARE_DIRS}=/data/libvirt/shares// /home/user/Public/**/ [...] pivot_root /data/libvirt/shares//, pivot_root /home/user/Public/**/,
La variable `SHARE_DIRS` est réutilisée dans la politique, cependant, en raison des limitations d'apparmor, il n'est pas possible de la réutiliser pour les directives `pivot_root`. Par conséquent, il est nécessaire d'adapter manuellement les directives `pivot_root` pour chaque répertoire partagé.
Pour monter un répertoire local :```
mofos mount test ./Public/share -d /home/user/share
Afin de ne pas perturber la machine virtuelle où le partage doit être monté, si le répertoire distant n'est pas vide, un avertissement est émis et le script vous permet d'effectuer manuellement l'opération de montage.
Enfin, l'opération de montage n'est pas persistante et doit être réexécutée à chaque redémarrage.
Pour créer des machines virtuelles Windows, une machine modèle doit d'abord être créée manuellement. Le disque de ce modèle est ensuite utilisé comme fichier de support pour créer les machines enfants. Par défaut, les machines virtuelles Windows créées avec Mofos ne sont pas préconfigurées. Cependant, il est possible de configurer Mofos pour effectuer des tâches de post-configuration, telles que la modification du nom d'hôte et l'ajout d'une entrée dédiée dans le fichier known_hosts, à l'aide de hooks.
Pour activer la configuration post-création, les prérequis suivants sont obligatoires :
authorized_keys doit être créé dans C:\Program Data\ssh\administrators_authorized_keys et des ACL spécifiques```powershell
$admin_group = "Administrators"
$system = "SYSTEM"$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys $acl.SetAccessRuleProtection($true, $false) $administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule($admin_group,"FullControl","Allow") $systemRule = New-Object system.security.accesscontrol.filesystemaccessrule($system,"FullControl","Allow") $acl.SetAccessRule($administratorsRule) $acl.SetAccessRule($systemRule) $acl | Set-Acl
- OpenSSH doit être configuré avec un shell `PowerShell` au lieu de `cmd.exe`.```powershell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" `
-Name DefaultShell `
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
-PropertyType String `
-Force
$HOME/.local/share/mofos/ssh.json. Cela garantira qu’une entrée known_hosts correspondante sera créée pour chaque nouvelle machine avec la clé d’hôte du modèle.## Autocomplétion
L'autocomplétion devrait être prise en charge par défaut pour `bash` et `fish`. Pour `zsh`, il peut être nécessaire d'exécuter les commandes suivantes :```
autoload -Uz compinit
compinit
source /usr/share/zsh/vendor-completions/_mofos
Les machines virtuelles basées sur le même disque de modèle peuvent obtenir la même adresse IP même si l'adresse MAC de leur carte réseau change en raison de l'identifiant DHCP. Ce comportement peut être modifié en éditant la configuration réseau du modèle :
Avec systemd-networkd :``` [Match] Name=eth0
[Network] DHCP=yes MulticastDNS=no IPv6AcceptRA=no
[DHCP] ClientIdentifier=mac
Avec les interfaces réseau héritées `/etc/network/interfaces` :```
iface eth0 inet dhcp
client no