cClaude.rocks ☕ Le blog

[Nouvelles technologies, sciences et coups de gueule…]

Menu
😤 Ce billet a été édité le : 2023-05-12

Cet article décrit un gros « hacking » pour les NAS QNAP permettant à des utilisateurs du NAS qui ne sont pas administrateurs d’avoir un accès ssh.



Cette astuce est issue de mes recherches et j’ai pas trouvé de solution similaire sur Internet. À vos risques et périls donc…

Cependant, les modifications apportées par cette solution sont nettement plus limitées que par les solutions alternatives que j’ai pu trouver.

Analyse et configuration du serveur ssh (sshd)

Ceci est en faire en ssh en utilisant le compte administrateur du NAS.

La liste des utilisateurs s’obtient à l’aide de :

cat /etc/passwd | cut -d':' -f1 | grep -v '^\['

Si vous envisager une automatisation, il faudra prévoir un peu de ménage.

Pour commencer on va rechercher processus sur serveur ssh:

ps faxo "%U %t %p %a" | grep '[s]shd'
16543 admin  4123 S   /usr/sbin/sshd -f /etc/config/ssh/sshd_config -p 22
18765 admin  9123 S   sshd: admin@pts/0

Cela permet de vérifier que le chemin de la configuration ssh se trouve dans /etc/config/ssh/ (a défaut vous devrez adapter la suite avec prudence !).

  • Détails…

    Localiser la commande, permet de s’assurer qu’on va bien exécuter la même commande que celle trouvée dans la liste des processus.

    which sshd
    
    /usr/sbin/sshd
    

    Ensuite on va essayer de découvrir la version de sshd, comme souvent avec BusyBox la version n’est pas disponible,
    voir avec des commandes compiler pour des environnements limités mais le support de l’aide n’est pas présent.
    Une astuce que j’utilise consiste à passer un paramètre qui n’est probablement pas pris en charge, espérant que le message d’erreur affichera également l’aide.

    sshd -XXX # Avec un paramètre bidon.
    
    unknown option -- X
    OpenSSH_8.0p1, OpenSSL 1.1.1l  24 Aug 2021
    usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]
                [-E log_file] [-f config_file] [-g login_grace_time]
                [-h host_key_file] [-o option] [-p port] [-u len]
    

    On apprend qu’est c’est OpenSSH 8, ce qui est plutôt une bonne nouvelle, puisque nous somme en terrain connu.

La configuration de sshd se trouve donc dans:

ls /etc/config/ssh

Notez que ce dossier est également accessible avec /root/.ssh qui est un lien symbolique.

lrwxrwxrwx 1 admin administrators 15 2023-02-07 11:34 /root/.ssh -> /etc/config/ssh/

Dans ce dossier, on trouve un fichier nommé sshd_user_config

cat /etc/config/ssh/sshd_user_config

Il a le format suivant :

AllowUsers admin admin2 admin3

Imaginons qu’on veuille ajouter l’utilisateur archives à cette liste, il est possible de faire comme suit :

read -r CONTENT < /etc/config/ssh/sshd_user_config
echo "Avant: ${CONTENT}"

echo "${CONTENT} archives" > /etc/config/ssh/sshd_user_config
read -r CONTENT < /etc/config/ssh/sshd_user_config
echo "Après: ${CONTENT}"

Pour prendre en compte ce changement il faut redémarrer le service.

Le plus simple et le plus sur est de le faire depuis l’interface web en désactivant le support ssh et en le réactivant.

  • Une générique version plus élaborée

    Cette version s’assure que l’utilisateur existe et qu’il n’est pas déjà présent dans le fichier.

    function add_user_to_sshd {
      local user="$1"
    
      if ! grep -q "^${user}:" /etc/passwd ; then
        echo "*** ERROR: User '${user}' does not exists." >&2
        return 100
      fi
    
      if grep -q "^AllowUsers ${user}$" /etc/config/ssh/sshd_user_config ; then
        echo "* WARN: User '${user}' already exist and is the only user allowed to use ssh." >&2
        return 0
      fi
      if grep -q "^AllowUsers ${user} " /etc/config/ssh/sshd_user_config ; then
        echo "* WARN: User '${user}' already exist and is the first user allowed to use ssh." >&2
        return 0
      fi
      if grep -q "^AllowUsers .* ${user}$" /etc/config/ssh/sshd_user_config ; then
        echo "* WARN: User '${user}' already exist and is the last user allowed to use ssh." >&2
        return 0
      fi
      if grep -q "^AllowUsers .* ${user} " /etc/config/ssh/sshd_user_config ; then
        echo "* WARN: User '${user}' already exist." >&2
        return 0
      fi
    
      read -r CONTENT < /etc/config/ssh/sshd_user_config || return $?
      echo "Before: ${CONTENT}" >&2
      # shellcheck disable=SC2320 # False positive
      echo "${CONTENT} ${user}" > /etc/config/ssh/sshd_user_config || return $?
      read -r CONTENT < /etc/config/ssh/sshd_user_config || return $?
      echo "After: ${CONTENT}" >&2
      echo 'added'
    }
    

Dans le cadre d’une automatisation, le service ssh peut être redémarré à l’aide de :

/etc/init.d/login.sh restart & disown
  • Explication de la commande ci-dessus utilisant disown

    Utilisation de "disown"

    disown est une commande Unix permettant d’enlever des tâches de la table des tâches actives, ou de les marquer de telle sorte que le signal SIGHUP ne leur soit pas envoyé lorsque le processus parent le reçoit, par exemple lors de la fermeture d’un terminal, qui dans notre cas intervient puis sshd, le service ssh, s’arrête.

    Cette commande s’utilise en conjonction avec l’opérateur & qui permet de placer le processus en tache de fond. Les entrées/sorties (stdin, stdout, et stderr) sont alors commune au processus lancé avec & et le terminal, qui est de nouveau « disponible ».
    Si le terminal reçoit un signal SIGHUP, celui-ci est propagé au processus lancé en tache de fond, ce qui a normalement comme conséquence de détruire ce processus. L’arrêt du terminal propage également le signal SIGHUP aux processus fils (et donc les arrête).

    La commande disown a comme effet de retirer de la liste des processus fils du shell. Cela a comme effet de plus propager le signal SIGHUP au processus dont on lui donne le PID (« Process ID »).

    firefox &
    ps
    
      PID TTY          TIME CMD
     4117 pts/2    00:00:00 bash
     4127 pts/2    00:00:00 firefox-bin
     4133 pts/2    00:00:00 ps
    
    disown 4127
    exit # On quitte le shell mais le processus reste actif.
    

    Cette succession de commandes peut s’écrire de manière simplifiée comme suit :

    firefox & disown &
    exit
    

    d’où dans notre cas l’écriture suivante :

    /etc/init.d/login.sh restart & disown
    


Configurer un compte utilisateur

Le plus simple est de se connecter en ssh ce qui permettra de plus de vérifier l’étape précédente.

ssh archives@192.168.1.121

Vous donnez le mot de passe de ce compte comme demandé, vous êtes maintenant sur le NAS en tant que archives.

mkdir -vp .ssh
chmod -c 750 .ssh/
cd .ssh/

# ensuite vous devez ajouter votre clé publique au fichier : authorized_keys

Dans un autre terminal depuis votre machine, vous pouvez récupérer le contenu de votre clé publique à l’aide de :

cat "${HOME}/.ssh/id_rsa.pub"

La prochaine fois que vous vous connecterez en tant que archives vous n’aurez pas à donner votre mot de passe.



Cohabitation avec l’environnement QNAP

La bonne nouvelle est que cette modification résiste au redémarrage du NAS, cependant si vous modifier dans l’interface web la configuration ssh, ces changements seront perdus.

La contrainte semble assez acceptable.



Liens

ᦿ


ℹ 2006 - 2023 | 🏠 Accueil du domaine | 🏡 Accueil du blog