Cacher le secret du paramètre de la ligne de commande sur Unix

j'ai un script qui lance à l'intérieur de lui-même une commande avec un paramètre qui est un secret. Par exemple:

#!/bin/bash
command-name secret

en exécutant la commande je peux lire à travers ps -ef | grep command-name qui est le secret.

y a-t-il un moyen de cacher le secret de telle sorte que par ps -ef , le paramètre de la ligne de commande soit obscurci?

26
demandé sur Jonathan Leffler 2010-09-30 17:13:25
la source

9 ответов

si le secret ne change pas entre les exécutions, utilisez un fichier de configuration spécial, ".appsecrets" . Définissez les permissions du fichier à lire uniquement par le propriétaire. À l'intérieur du fichier, définissez une variable d'environnement au secret. Le fichier doit être dans le répertoire home de l'utilisateur qui exécute la commande.

#!/bin/bash  
#filename: .appsecrets
set SECRET=polkalover  

chargez le fichier de configuration pour que la variable d'environnement soit définie.

. ~/.appsecrets

Ce que j'ai vu:

1)

echo $SECRET | command

fonctionne si la commande demande le mot de passe de stdin et si 'echo' est un composant de votre shell. Nous avons été à l'aide de Korn.

2)

password=$ENV{"SECRET"};

fonctionne si vous avez le contrôle du code (par exemple en perl ou C++)

3)

. ./.app.config #sets the environment variables

isql -host [host] -user [user] -password <<SECRET

${SQLPASSWORD}

SECRET

si la commande peut accepter le secret de mst. Une limitation est que la chaîne << doit être le dernier argument donné à la commande. Cela pourrait être gênant s'il y a un arg non-optionnel qui doit apparaître après le mot de passe

l'avantage de cette approche est que vous pouvez l'arranger de sorte que le secret puisse être caché dans la production. Utilisez le même nom de fichier dans la production mais il sera dans le répertoire d'accueil de la compte qui exécute la commande en production. Vous pouvez ensuite verrouiller l'accès au secret comme vous le feriez pour accéder au compte root. Seules certaines personnes peuvent " su "sur le compte prod pour voir ou maintenir le secret tandis que les développeurs peuvent toujours exécuter le programme parce qu'ils utilisent le leur".le fichier appsecret dans leur répertoire personnel.

Vous pouvez utiliser cette approche pour stocker des informations sécurisées pour n'importe quel nombre d'applications, aussi longtemps qu'ils utilisent différents noms de variables d'environnement pour leurs secrets.

(DE MANIÈRE ERRONÉE)

Une ancienne méthode que j'ai vu L'utilisation de DBAs était de mettre SYBASE à "/opt/././././././././././././././././././././././././././././././././././sybase/bin" . Donc leurs lignes de commandement étaient si longues que le ps les a tronquées. Mais sous linux, je pense que vous pourriez être capable de renifler la ligne de commande complète de /proc.

8
répondu Kelly S. French 2015-12-30 04:15:23
la source
  1. tout d'abord, vous ne pouvez pas cacher les arguments en ligne de commande. Ils seront toujours visibles via ps aux et cat /proc/$YOUR_PROCESS_PID/cmdline au moment du lancement du programme (avant le programme a une chance de faire les changements d'exécution des arguments). La bonne nouvelle est que vous pouvez toujours avoir un secret en utilisant des alternatives:

  2. utiliser les variables d'environnement. Si votre programme peut les lire, Faites ceci:

    mySecret='hello-neo' myCommand
    
  3. Use entrée standard:

    mySecret='hello-neo' printenv mySecret | myCommand
    
  4. utiliser le descripteur de fichier temporaire:

    myCommand <( mySecret='hello-neo' printenv mySecret )
    

Dans le dernier cas, votre programme sera lancé comme myCommand /dev/fd/67 , où le contenu de /dev/fd/67 est votre secret ( hello-neo dans cet exemple).


dans toutes les approches ci-dessus, méfiez-vous de quitter le commandement à bash historique du commandement ( ~/.bash_history ). Vous pouvez éviter cela en exécutant la commande à partir d'un script (file), ou en vous demandant de façon interactive le mot de passe à chaque fois:

    read mySecret
    myCommand  # approach 2
    printenv mySecret | myCommand  # approach 3
    myCommand <( printenv mySecret )  # approach 4
7
répondu VasyaNovikov 2018-09-20 09:00:45
la source

la seule façon de cacher votre argument secret de ps n'est pas de fournir le secret comme argument. Une façon de le faire est de placer le secret dans un fichier, et de rediriger descripteur de fichier 3 pour lire le fichier, puis supprimer le fichier:

echo secret > x.$$
command 3<x.$$
rm -f x.$$

il n'est pas tout à fait clair que c'est une façon sûre de sauver le secret; la commande echo est un shell intégré, donc elle ne devrait pas apparaître dans la sortie 'ps' (et toute apparence serait fugace). Une fois sur il y a très longtemps, echo n'était pas un built-in - en effet, sur MacOS X, il y a toujours un /bin/echo même si c'est un built-in pour tous les coquillages.

bien sûr, cela suppose que vous avez la source à command et pouvez la modifier pour lire le secret à partir d'un descripteur de fichier pré-ouvert au lieu de l'argument de ligne de commande. Si vous ne pouvez pas modifier la commande, vous êtes complètement bloqué - la liste 'ps' affichera les informations.

un autre astuce que vous pourriez tirer si vous êtes le propriétaire de la commande: vous pourriez capturer l'argument (secret), l'écrire dans un tuyau ou un fichier (qui est immédiatement déverrouillé) pour vous-même, et puis re-exec la commande sans l'argument secret; la deuxième invocation sait que puisque le secret est absent, il devrait regarder partout où la première invocation A CACHÉ le secret. La deuxième invocation (moins secret) est ce qui apparaît dans la sortie 'ps' après l'intervalle minuscule qu'il faut pour traiter de cacher le secret. Pas comme c'est aussi bien que d'avoir mis en place la chaîne secrète dès le début. Mais ceux-ci sont révélateurs de la durée à laquelle vous devez aller.

Zapper un argument de l'intérieur du programme - en écrasant avec des zéros, par exemple - ne cache pas l'argument de 'ps'.

5
répondu Jonathan Leffler 2010-09-30 17:41:23
la source

la bibliothèque expect a été créée en partie pour ce genre de choses, de sorte que vous pouvez toujours fournir un mot de passe / d'autres informations sensibles à un processus sans avoir à passer comme argument. En supposant que quand "secret" n'est pas donné le programme le demande bien sûr.

4
répondu Wrikken 2010-09-30 17:44:36
la source

je l'ai vu sur un autre post. C'est le moyen le plus simple sous Linux.

ceci modifie la partie mémoire de la ligne de commande que tous les autres programmes voient.

strncpy(argv[1], "randomtrash", strlen(argv[1]));

vous pouvez également changer le nom du processus, mais seulement quand lu de la ligne de commande. Des programmes comme top montreront le vrai nom du processus:

strncpy(argv[0], "New process name", strlen(argv[0]));

n'oubliez pas de copier le maximum d'octets strlen(argv[0]) car il n'y a probablement plus d'espace allouer.

je pense que les arguments ne peuvent être trouvés dans la partie de la mémoire que nous modifions donc je pense que cela fonctionne comme un charme. Si quelqu'un sait quelque chose de précis à ce sujet, s'il vous plaît commenter.

VasyaNovikov note: le mot de passe peut encore être intercepté après que le programme ait invoqué mais avant qu'il ait commencé à faire les changements que vous avez décrits.

4
répondu Jorge Fuentes González 2018-07-12 13:55:46
la source

il n'y a pas de solution facile. Jetez un coup d'oeil à cette question que j'ai posée il y a un certain temps:

Masquer les arguments du ps

est-ce que command est votre propre programme? Vous pouvez essayer de crypter le secret et avoir le command le décrypter avant utilisation.

1
répondu dogbane 2017-05-23 15:01:40
la source

si le script est destiné à être exécuté manuellement, la meilleure façon est de le lire à partir de STDIN

#!/bin/bash
read -s -p "Enter your secret: " secret

command "$secret"
0
répondu Daenyth 2010-09-30 21:15:39
la source

peut-être Pouvez-vous faire comme ceci:

#include <boost/algorithm/string/predicate.hpp>
void hide(int argc, char** argv, std::string const & arg){
    for(char** current = argv; current != argv+ argc ;++current){
        if(boost::algorithm::starts_with(*current, "--"+arg)){
            bzero(*current, strlen(*current));
        }
    }
}
int main(int argc, char** argv){
   hide(argc,  argv, "password");
}
0
répondu user2068018 2017-12-20 09:25:26
la source

vous pouvez utiliser LD_PRELOAD pour qu'une bibliothèque manipule les arguments en ligne de commande d'un binaire dans le processus de ce binaire lui-même, où ps ne le ramasse pas. Voir cette réponse de la mienne sur la faute du serveur pour plus de détails.

0
répondu MvG 2018-05-20 01:44:30
la source

Autres questions sur