सवाल आदेश पंक्ति तर्क के रूप में पारित पासवर्ड कैसे छिपाना है?


मैं एक सॉफ्टवेयर डिमन चला रहा हूं जिसके लिए कुछ विशेषताओं को कुछ विशेषताओं को अनलॉक करने के लिए पासफ्रेज दर्ज करना आवश्यक है जो उदाहरण के लिए दिखता है:

$ darkcoind masternode start <mypassphrase>

अब मुझे अपने हेडलेस डेबियन सर्वर पर कुछ सुरक्षा चिंताएं मिली हैं।

जब भी मैं अपने बैश इतिहास को उदाहरण के लिए खोजता हूं Ctrl+R मैं यह सुपर मजबूत पासवर्ड देख सकता हूं। अब मुझे लगता है कि मेरे सर्वर से समझौता किया गया है और कुछ घुसपैठियों के पास खोल पहुंच है और बस यह कर सकते हैं Ctrl+R इतिहास में अपना पासफ्रेज ढूंढने के लिए।

बैश इतिहास में दिखाए जाने के बिना पासफ्रेज दर्ज करने का कोई तरीका है, ps, /proc या कहीं और?


अद्यतन 1: डेमॉन को कोई पासवर्ड पास करने से कोई त्रुटि नहीं आती है। यह कोई विकल्प नहीं है।


अद्यतन 2: डेवलपर्स को लटकाने जैसे सॉफ़्टवेयर या अन्य सहायक संकेतों को हटाने के लिए मुझे मत कहें। मुझे पता है कि यह एक सर्वोत्तम अभ्यास उदाहरण नहीं है लेकिन यह सॉफ्टवेयर आधारित है Bitcoin और सभी बिटकॉइन आधारित क्लाइंट किसी प्रकार का जेसन आरपीसी सर्वर हैं जो इन आदेशों को सुनता है और इसकी एक ज्ञात सुरक्षा समस्या पर अभी भी चर्चा की जा रही है (, , सी)।


अद्यतन 3: डिमन पहले ही शुरू हो चुका है और कमांड के साथ चल रहा है

$ darkcoind -daemon

करते हुए ps केवल स्टार्टअप कमांड दिखाता है।

$ ps aux | grep darkcoin
user     12337  0.0  0.0  10916  1084 pts/4    S+   09:19   0:00 grep darkcoin
user     21626  0.6  0.3 1849716 130292 ?      SLl  May02   6:48 darkcoind -daemon

तो पासफ्रेज के साथ आदेश पास करना में दिखाई नहीं देता है ps या /proc बिल्कुल भी।

$ darkcoind masternode start <mypassphrase>
$ ps aux | grep darkcoin
user     12929  0.0  0.0  10916  1088 pts/4    S+   09:23   0:00 grep darkcoin
user     21626  0.6  0.3 1849716 130292 ?      SLl  May02   6:49 darkcoind -daemon

यह सवाल छोड़ देता है कि इतिहास कहां दिखाता है? में केवल .bash_history?


42
2018-05-02 15:30


मूल


पहला सवाल होना चाहिए: यदि आप पासफ्रेज़ तर्क के बिना डिमन शुरू करते हैं तो क्या होता है। क्या यह सिर्फ इसके लिए संकेत देता है? - MadHatter
मुझे नहीं लगता कि एक जवाब है जो काम करेगा। पासफ्रेज़ के लिए संकेत देने में असमर्थता एक है प्रमुख डेमॉन में कमी यदि यह मुफ्त सॉफ्टवेयर है, तो प्रोग्रामर प्राप्त करें और इसे ठीक करें; अपने परिवर्तन प्रकाशित करना न भूलें। यदि यह मालिकाना सॉफ्टवेयर है, तो विक्रेता को रिंग करें और उन पर चिल्लाओ (जो कुछ भी ठीक नहीं करेगा, लेकिन यह आपको बेहतर महसूस करेगा)। - MadHatter
अपने दस्तावेज़ों की जांच करें, यह सिस्टम पर्यावरण चर से उस पासवर्ड को पढ़ने का समर्थन कर सकता है। - Elliott Frisch
भले ही पासवर्ड को डिमन पर कमांड लाइन पर नहीं दिया गया हो, फिर भी यह किसी अन्य कमांड की कमांड लाइन पर देने के लिए समस्याग्रस्त है। यह केवल बहुत ही कम समय के लिए पीएस आउटपुट में दिखाई देता है, लेकिन पृष्ठभूमि में चल रही एक प्रक्रिया अभी भी इसे उठा सकती है। लेकिन यह निश्चित रूप से अभी भी सार्थक है कि पासवर्ड लेने में मुश्किल हो रही है। - kasperd
के जवाब देखें यह प्रश्न, वे वास्तव में इस मुद्दे से निपटते हैं। - dotancohen


जवाब:


वास्तव में, यह चाहिए आवेदन में ही तय किया जाना चाहिए। और ऐसे अनुप्रयोग चाहिए ओपन सोर्स बनें, ताकि ऐप में समस्या को ठीक करने का विकल्प हो। एक सुरक्षा संबंधी अनुप्रयोग जो इस तरह की गलती करता है, वह अन्य गलतियों को भी कर सकता है, इसलिए मुझे विश्वास नहीं होगा।

सरल इंटरपोजर

लेकिन आप एक अलग तरीके से पूछ रहे थे, तो यहां एक है:

#define _GNU_SOURCE
#include <dlfcn.h>

int __libc_start_main(
    int (*main) (int, char * *, char * *),
    int argc, char * * ubp_av,
    void (*init) (void),
    void (*fini) (void),
    void (*rtld_fini) (void),
    void (* stack_end)
  )
{
  int (*next)(
    int (*main) (int, char * *, char * *),
    int argc, char * * ubp_av,
    void (*init) (void),
    void (*fini) (void),
    void (*rtld_fini) (void),
    void (* stack_end)
  ) = dlsym(RTLD_NEXT, "__libc_start_main");
  ubp_av[argc - 1] = "secret password";
  return next(main, argc, ubp_av, init, fini, rtld_fini, stack_end);
}

इसके साथ संकलित करें

gcc -O2 -fPIC -shared -o injectpassword.so injectpassword.c -ldl

फिर अपनी प्रक्रिया को साथ चलाएं

LD_PRELOAD=$PWD/injectpassword.so darkcoind masternode start fakepasshrase

इंटरपोजर लाइब्रेरी इस कोड को पहले चलाएगी main आपके आवेदन से कार्य निष्पादित हो जाता है। यह कॉल में वास्तविक पासवर्ड द्वारा अंतिम कमांड लाइन तर्क को मुख्य में बदल देगा। मुद्रित के रूप में कमांड लाइन /proc/*/cmdline (और इसलिए उपकरण जैसे देखा जाता है ps) हालांकि, नकली तर्क अभी भी होगा। जाहिर है आपको स्रोत कोड और लाइब्रेरी को संकलित करना होगा जो आप इसे संकलित करने के लिए केवल अपने आप को पठनीय कर सकते हैं, इसलिए सबसे अच्छा काम करें chmod 0700 निर्देशिका। और चूंकि पासवर्ड कमांड आमंत्रण का हिस्सा नहीं है, इसलिए आपका बैश इतिहास भी सुरक्षित है।

अधिक उन्नत इंटरपोजर

यदि आप कुछ और अधिक विस्तृत करना चाहते हैं, तो आपको इसे ध्यान में रखना चाहिए __libc_start_main रनटाइम लाइब्रेरी को ठीक तरह से शुरू करने से पहले निष्पादित किया जाता है। इसलिए मैं किसी फंक्शन कॉल से बचने का सुझाव दूंगा जबतक कि वे बिल्कुल जरूरी नहीं हैं। यदि आप अपने दिल की सामग्री में कार्यों को कॉल करने में सक्षम होना चाहते हैं, तो सुनिश्चित करें कि आप पहले ऐसा करते हैं main सभी प्रारंभिक होने के बाद ही खुद को बुलाया जाता है। निम्नलिखित उदाहरण के लिए मुझे ग्रुबर्मेंश का शुक्रिया अदा करना है जिन्होंने बताया कमांड लाइन तर्क के रूप में पारित पासवर्ड को कैसे छिपाना है जो लाया getpass मेरे ध्यान में

#define _GNU_SOURCE
#include <dlfcn.h>
#include <unistd.h>

static int (*real_main) (int, char * *, char * *);

static int my_main(int argc, char * * argv, char * * env) {
  char *pass = getpass(argv[argc - 1]);
  if (pass == NULL) return 1;
  argv[argc - 1] = pass;
  return real_main(argc, argv, env);
}

int __libc_start_main(
    int (*main) (int, char * *, char * *),
    int argc, char * * ubp_av,
    void (*init) (void),
    void (*fini) (void),
    void (*rtld_fini) (void),
    void (* stack_end)
  )
{
  int (*next)(
    int (*main) (int, char * *, char * *),
    int argc, char * * ubp_av,
    void (*init) (void),
    void (*fini) (void),
    void (*rtld_fini) (void),
    void (* stack_end)
  ) = dlsym(RTLD_NEXT, "__libc_start_main");
  real_main = main;
  return next(my_main, argc, ubp_av, init, fini, rtld_fini, stack_end);
}

यह पासवर्ड के लिए संकेत देता है, इसलिए आपको अब इंटरपोजर लाइब्रेरी को एक गुप्त रखना नहीं है। प्लेसहोल्डर तर्क को पासवर्ड प्रॉम्प्ट के रूप में पुन: उपयोग किया जाता है, इसलिए इसे इस तरह से आमंत्रित करें

LD_PRELOAD=$PWD/injectpassword.so darkcoind masternode start "Password: "

एक और विकल्प फाइल डिस्क्रिप्टर से पासवर्ड पढ़ेगा (जैसे उदा। gpg --passphrase-fd करता है), या से x11-ssh-askpass, जो कुछ भी।


65
2018-05-03 19:49



हालांकि मैं समझ नहीं पा रहा हूं और कोड का परीक्षण नहीं कर सकता, मुझे इसके बारे में जानकारी मिलती है, और इस एक वास्तविक उत्तर की तरह दिखता है और शीर्ष जवाब होना चाहिए। - Mark Henderson♦
यह वास्तव में कमाल है। - Afri
बहुत बढ़िया। जहां तक ​​मैं यह कह सकता हूं कि यह काम करना चाहिए। बेशक आपको स्रोत तक पहुंच की आवश्यकता है और पुनः संयोजित करने में सक्षम होना चाहिए। पासवर्ड स्रोत और संकलित फ़ाइल में पठनीय है यदि आप "स्ट्रिंग्स" या कुछ ऐसा ही करते हैं तो यह सुनिश्चित करें कि कोई भी उन्हें पढ़ सके। - Tonny
एसटीडीआईएन पर पासवर्ड लेना संभव होना चाहिए और अभी भी यह काम है, जो हटा देता है strings भेद्यता। देख SO: टर्मिनल पर पासवर्ड इनपुट छुपाएं। - Grubermensch
@Gububermensch आप सही हैं। - Tonny


यह सिर्फ इतिहास नहीं है। यह दिखाने के लिए जा रहा है ps आउटपुट भी।

जो भी लिखा है उस सॉफ्टवेयर के टुकड़े को लटका, खींचा और चौगुना होना चाहिए। कमांड लाइन पर पासवर्ड प्रदान करने के लिए यह एक पूर्ण नहीं है, चाहे वह भी सॉफ्टवेयर हो।
एक डेमॉन प्रक्रिया के लिए यह और भी अक्षम्य है ...

के अतिरिक्त आरएम-एफ सॉफ्टवेयर पर ही मुझे इसके लिए कोई समाधान नहीं पता है। ईमानदारी से: काम पूरा करने के लिए अन्य सॉफ्टवेयर खोजें। इस तरह के जंक का प्रयोग न करें।


28
2018-05-02 15:41



बिल्कुल सहायक नहीं होने के लिए धन्यवाद। यह एक लंबी चर्चा है सुरक्षा का मसला, अभी भी अनसुलझा है और मुझे इससे बेहतर कामकाज की आवश्यकता है rm -f अभी व। - Afri
असल में, वह बहुत उपयोगी है। यदि आप पासफ्रेज को तर्क के रूप में पास कर रहे हैं, तो यह दिखाई देगा ps। तो जब तक देव इसे ठीक नहीं कर सकता, वह कुछ और उपयोग करने का सुझाव दे रहा है। - Safado
फिर आप एक और ऑपरेटिंग सिस्टम लिखना बेहतर शुरू करते हैं। वर्तमान में कोई अन्य समाधान उपलब्ध नहीं है जिसे मैं जानता हूं। भगवान से मेरी इच्छा है कि एक था। आप इस समस्या के साथ एकमात्र नहीं हैं। - Tonny
vertoe, snippy मत मिलता है। आप कागज के छोटे पर्ची पर इसे पारित करने के लिए एक रास्ता मांग सकते हैं, लेकिन इसका मतलब यह नहीं है कि ऐसा कोई भी तरीका स्वचालित रूप से मौजूद है। read_x ठीक है, लेकिन फिर भी पासफ्रेज़ को उदाहरण के माध्यम से उजागर करता है ps, तो यह इससे बेहतर नहीं है rm उपाय। - MadHatter
इससे पहले कि आप इस पर एक और +1 फेंक दें और वास्तव में शिकायत करें कि यह असंभव है, मेरा सुझाव है कि आप समीक्षा करें नीचे एमवीजी का जवाब - Mark Henderson♦


यह साफ़ हो जाएगा ps उत्पादन।

बहुत जागरूक रहो: यह आवेदन तोड़ सकता है। आपको विधिवत चेतावनी दी जाती है कि यहां ड्रैगन हों।

  • प्रक्रियाओं की स्मृति में विदेशी प्रक्रियाओं को झुकाव नहीं करना चाहिए।
  • यदि प्रक्रिया इस क्षेत्र पर पासवर्ड के लिए निर्भर करती है, तो आप अपना आवेदन तोड़ सकते हैं।
  • ऐसा करने से आप उस प्रक्रिया में किसी भी कामकाजी डेटा को दूषित कर सकते हैं।
  • यह एक पागल हैक है।

अब आप इन सख्त चेतावनियों के बारे में अधिसूचित हैं। यह प्रदर्शित आउटपुट को साफ़ करेगा ps। यह आपके इतिहास को साफ़ नहीं करेगा, न ही यह बैश नौकरी इतिहास को साफ़ करेगा (जैसे प्रक्रिया को चलाने के लिए myprocess myargs &)। परंतु ps अब तर्क नहीं दिखाएंगे।

#!/usr/bin/python
import os, sys
import re

PAGESIZE=4096

if __name__ == "__main__":
  if len(sys.argv) < 2:
    sys.stderr.write("Must provide a pid\n")
    sys.exit(1)

  pid = sys.argv[1]

  try:
    cmdline = open("/proc/{0}/cmdline".format(pid)).read(8192)

    ## On linux, at least, argv is located in the stack. This is likely o/s
    ## independent.
    ## Open the maps file and obtain the stack address.
    maps = open("/proc/{0}/maps".format(pid)).read(65536)
    m = re.search('([0-9a-f]+)-([0-9a-f]+)\s+rw.+\[stack\]\n', maps)
    if not m:
      sys.stderr.write("Could not find stack in process\n");
      sys.exit(1)

    start = int("0x"+m.group(1), 0)
    end = int("0x"+m.group(2), 0)

    ## Open the mem file
    mem = open('/proc/{0}/mem'.format(pid), 'r+')
    ## As the stack grows downwards, start at the end. It is expected
    ## that the value we are looking for will be at the top of the stack
    ## somewhere
    ## Seek to the end of the stack minus a couple of pages.
    mem.seek(end-(2*PAGESIZE))

    ## Read this buffer to the end of the stack
    stackportion = mem.read(8192)
    ## look for a string matching cmdline. This is pretty dangerous.
    ## HERE BE DRAGONS
    m = re.search(cmdline, stackportion)
    if not m:
      ## cause this is an example dont try to search exhaustively, just give up
      sys.stderr.write("Could not find command line in the stack. Giving up.")
      sys.exit(1)

    ## Else, we got a hit. Rewind our file descriptor, plus where we found the first argument.
    mem.seek(end-(2*PAGESIZE)+m.start())
    ## Additionally, we'll keep arg0, as thats the program name.
    arg0len = len(cmdline.split("\x00")[0]) + 1
    mem.seek(arg0len, 1)

    ## lastly overwrite the remaining region with nulls.
    writeover = "\x00" * (len(cmdline)-arg0len)
    mem.write(writeover)

    ## cleanup
    mem.close()

  except OSError, IOError:
    sys.stderr.write("Cannot find pid\n")
    sys.exit(1)

इसे सहेजकर प्रोग्राम को आमंत्रित करें, chmod +x यह। फिर कर रहे हैं ./whatever <pidoftarget> यदि यह काम करता है, तो यह कोई आउटपुट नहीं देगा। अगर यह विफल रहता है, तो यह कुछ के बारे में शिकायत करेगा और छोड़ देगा।


17
2018-05-02 22:04



। । । यह रचनात्मक और डरावना दोनों है। - voretaq7
EEK! अब मुझे डर लग रहा है। - Janne Pikkarainen
यिक्स, जो काम कर सकता है ... मुझे यकीन नहीं है कि ऐपआर्मर ऐसा कुछ पकड़ लेगा? इसके अलावा वायरसकेनर संभावित रूप से इसे पकड़ सकता है और आपत्तिजनक खाते को अवरुद्ध करके विनाश का कारण बन सकता है जो 'रूट' होगा। वास्तव में ड्रेगन हो .... - Tonny
@ टोनी संरक्षित डोमेन के लिए, SELinux इसे रोक देगा। आपकी मूल यूनिक्स अनुमतियों (डीएसी) में इस व्यवहार से किसी भी सुरक्षा की पेशकश करने के लिए पर्याप्त विषय ग्रैन्युलरिटी की कमी है (उसी यूआईडी के भीतर प्रक्रिया मेमोरी के संशोधन की अनुमति देता है)। वैसे भी, यह एक बग नहीं है - इसकी एक विशेषता है। मेरा मानना ​​है कि यह कैसे है gdb चल रही प्रक्रियाओं की स्मृति को संशोधित कर सकते हैं (इससे अधिक सर्जिकल परिशुद्धता के साथ मैं इसे जोड़ सकता हूं)। - Matthew Ife


क्या आप एक फ़ाइल से तर्क पारित कर सकते हैं, केवल रूट या आवश्यक उपयोगकर्ता द्वारा पहुंचा जा सकता है?

यह कंसोल में पासवर्ड टाइप करने के लिए एक बड़ा नंबर नहीं है, लेकिन अंतिम सहारा ... एक स्थान के साथ अपनी लाइन शुरू करें ताकि यह इतिहास में प्रकट न हो।


10
2018-05-02 16:33



एक खोल विकल्प था जो इसे सक्षम बनाता है, लेकिन मुझे लगता है कि यह डिफ़ॉल्ट रूप से सक्षम नहीं था। - heinrich5991
export HISTCONTROL=ignoreboth इतिहास में प्रवेश के लिए एक प्रमुख स्थान के साथ डुप्लिकेट और लाइनों दोनों को अनदेखा करता है। इसे अपने .bashrc या .bash_profile में जोड़ें। - Andreas


शायद यह काम करता है (?):

darkcoind masternode start `cat password.txt`

6
2018-05-02 19:31



या और भी darkcoind masternode start `head -1`, अगर आप मैन्युअल रूप से पासवर्ड दर्ज करना चाहते हैं। - kasperd
पासफ्रेज अभी भी उपलब्ध है ps और इसी तरह की उपयोगिताएं। - voretaq7
एक सादे पाठ पासवर्ड से चल रहा है .bash_history एक सादे पाठ पासवर्ड में password.txt आपको क्या लाभ देता है, बिल्कुल? - MikeyB
@ माइकीबी: एक छोटी सी जीत है: जब आप किसी को अपने कंधे पर देख रहे हों तो आप अपने इतिहास के माध्यम से इसे गोपनीय रूप से बेनकाब नहीं करेंगे। - MvG
@MikeyB, आप हर बार उस फ़ाइल को बना और निकाल सकते हैं। - RiaD


दुर्भाग्य से, अगर आपका darkcoind कमांड को कमांड लाइन तर्क के रूप में पासवर्ड की उम्मीद है, तो इसे यूटिलिटीज के माध्यम से उजागर किया जाएगा ps। एकमात्र वास्तविक समाधान है डेवलपर्स को शिक्षित करें

जबकि ps एक्सपोजर अपरिहार्य हो सकता है, आप कम से कम पासवर्ड को खोल इतिहास फ़ाइल में लिखे जाने से रोक सकते हैं।

$ xargs darkcoind masternode start

पीरोंरोंwआर

Ctrlडी

इतिहास फ़ाइल केवल रिकॉर्ड होना चाहिए xargs darkcoind masternode startपासवर्ड नहीं


3
2018-05-04 08:13



या यदि आप बैश का उपयोग कर रहे हैं, तो डाल दें ignorespace में $HISTCONTROL, और फिर आप रोक सकते हैं कोई भी अंतरिक्ष के साथ कमांड को उपसर्ग करके शैल इतिहास में जाने से कमांड करें। - derobert


आप एक नई खोल प्रक्रिया से कमांड निष्पादित करके पासवर्ड को अपने खोल के इतिहास से बाहर रख सकते हैं, जिसे आप तुरंत समाप्त कर देते हैं। उदाहरण के लिए:

bash$ sh
sh$ darkcoind masternode start 'correct horse battery staple'
sh$ exit
bash$

सुनिश्चित करो sh कॉन्फ़िगर किया गया है नहीं एक फ़ाइल में अपने इतिहास को बचाने के लिए।

बेशक यह अन्य समस्याओं का समाधान नहीं करता है, जैसे कि पासवर्ड में दिखाई दे रहा है ps। वहाँ हैं, मुझे विश्वास है, के लिए तरीके darkcoind से जानकारी छिपाने के लिए प्रोग्राम खुद ही ps, लेकिन यह केवल भेद्यता की खिड़की को छोटा करता है।


1
2018-05-02 20:38



पासफ्रेज अभी भी उपलब्ध है ps और इसी तरह की उपयोगिताएं। - voretaq7
@ voretaq7: हां, जैसा कि मैंने स्पष्ट रूप से मेरे उत्तर के अंतिम अनुच्छेद में स्वीकार किया है। - Keith Thompson
दरअसल - आप मेरे हिस्से पर अवांछित copypasta का शिकार थे :) - voretaq7