कैसे कर्ल पीएस आउटपुट में एक पासवर्ड को प्रदर्शित होने से बचाता है?


68

मैंने कुछ समय पहले देखा था कि curlकमांड लाइन तर्क के रूप में दिए गए उपयोगकर्ता नाम और पासवर्ड psआउटपुट में दिखाई नहीं देते हैं (हालाँकि वे आपके बैश इतिहास में दिखाई दे सकते हैं)।

वे इसी तरह से प्रकट नहीं होते हैं /proc/PID/cmdline

(संयुक्त उपयोगकर्ता नाम / पासवर्ड तर्क की लंबाई, हालांकि प्राप्त की जा सकती है।)

नीचे प्रदर्शन:

[root@localhost ~]# nc -l 80 &
[1] 3342
[root@localhost ~]# curl -u iamsam:samiam localhost &
[2] 3343
[root@localhost ~]# GET / HTTP/1.1
Authorization: Basic aWFtc2FtOnNhbWlhbQ==
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Host: localhost
Accept: */*



[1]+  Stopped                 nc -l 80
[root@localhost ~]# jobs
[1]+  Stopped                 nc -l 80
[2]-  Running                 curl -u iamsam:samiam localhost &
[root@localhost ~]# ps -ef | grep curl
root      3343  3258  0 22:37 pts/1    00:00:00 curl -u               localhost
root      3347  3258  0 22:38 pts/1    00:00:00 grep curl
[root@localhost ~]# od -xa /proc/3343/cmdline 
0000000    7563    6c72    2d00    0075    2020    2020    2020    2020
          c   u   r   l nul   -   u nul  sp  sp  sp  sp  sp  sp  sp  sp
0000020    2020    2020    0020    6f6c    6163    686c    736f    0074
         sp  sp  sp  sp  sp nul   l   o   c   a   l   h   o   s   t nul
0000040
[root@localhost ~]# 

यह प्रभाव कैसे प्राप्त होता है? क्या यह कहीं स्रोत कोड में है curl? (मुझे लगता है कि यह एक curlविशेषता है, एक विशेषता नहीं है ps? या क्या यह किसी प्रकार की एक कर्नेल विशेषता है?)


इसके अलावा: क्या यह बाइनरी एक्ज़ीक्यूटेबल के स्रोत कोड के बाहर से प्राप्त किया जा सकता है? उदाहरण के लिए शेल कमांड का उपयोग करके, संभवतः रूट अनुमतियों के साथ संयुक्त?

दूसरे शब्दों में, मैं किसी भी तरह से /procया psआउटपुट में दिखने से एक तर्क को नाकाम कर सकता हूं (एक ही बात, मुझे लगता है) कि मैं कुछ मनमाना खोल कमान में पारित कर दिया ? (मुझे लगता है कि इसका उत्तर "नहीं" है, लेकिन यह इस अतिरिक्त आधे-अधूरे प्रश्न के लायक है।)



16
उत्तर नहीं, लेकिन ध्यान दें कि यह दृष्टिकोण सुरक्षित नहीं है । कार्यक्रम की शुरुआत और तर्क तार को साफ करने के बीच एक दौड़ खिड़की है, जिसके दौरान कोई भी उपयोगकर्ता पासवर्ड पढ़ सकता है। कमांड लाइन पर संवेदनशील पासवर्ड स्वीकार न करें।
आर ..

1
ढीले से संबंधित: पर्यावरण चर किससे संबंधित हैं? और पर्यावरण चर का उपयोग environकरने के लिए किसी को भी सीधे उपयोग करता है? - निचला रेखा: पर्यावरण चर की सूची की तरह तर्क सूची, उपयोगकर्ता प्रक्रिया मेमोरी में पढ़ने / लिखने के लिए है, और इसे उपयोगकर्ता प्रक्रिया द्वारा संशोधित किया जा सकता है।
स्कॉट

1
@ JPhi1618, अपने grepपैटर्न के पहले चरित्र को चरित्र वर्ग बनाएं । जैसेps -ef | grep '[c]url'
वाइल्डकार्ड

1
@ नमस्कार, टी बहुत जटिल नहीं है। कुछ रेगेक्स खुद से मेल खाते हैं और कुछ नहीं। curlमेल खाता है, curlलेकिन [c]urlमेल नहीं खाता [c]url। यदि आपको अधिक विस्तार की आवश्यकता है तो एक नया प्रश्न पूछें और मुझे उत्तर देने में खुशी होगी।
वाइल्डकार्ड

जवाबों:


78

जब कर्नेल किसी प्रक्रिया को निष्पादित करता है, तो यह प्रक्रिया से संबंधित मेमोरी को पढ़ने-लिखने के लिए कमांड लाइन के तर्कों को कॉपी करता है (स्टैक पर, कम से कम लिनक्स पर)। प्रक्रिया उस मेमोरी को किसी अन्य मेमोरी की तरह लिख सकती है। जब psतर्क प्रदर्शित करता है, तो यह वापस पढ़ता है जो प्रक्रिया की मेमोरी में उस विशेष पते पर संग्रहीत किया जाता है। अधिकांश कार्यक्रम मूल तर्क रखते हैं, लेकिन उन्हें बदलना संभव है। की POSIX वर्णनps कहा गया है कि

यह अनिर्दिष्ट है कि क्या स्ट्रिंग का प्रतिनिधित्व तर्क सूची का एक संस्करण है जैसा कि इसे शुरू करने पर कमांड को दिया गया था, या तर्कों का एक संस्करण है क्योंकि वे अनुप्रयोग द्वारा संशोधित किए जा सकते हैं। अनुप्रयोग अपनी तर्क सूची को संशोधित करने और पीएस के उत्पादन में संशोधन को प्रतिबिंबित करने में सक्षम होने पर निर्भर नहीं कर सकते।

इसका उल्लेख यह है कि अधिकांश यूनिक्स संस्करण परिवर्तन को प्रतिबिंबित करते हैं, लेकिन अन्य प्रकार के ऑपरेटिंग सिस्टम पर POSIX कार्यान्वयन नहीं हो सकता है।

यह सुविधा सीमित उपयोग की है क्योंकि यह प्रक्रिया मनमाने ढंग से परिवर्तन नहीं कर सकती है। बहुत कम से कम, तर्कों की कुल लंबाई को बढ़ाया नहीं जा सकता है, क्योंकि कार्यक्रम उस स्थान को नहीं बदल सकता है जहां psतर्कों को लाया जाएगा और अपने मूल आकार से परे क्षेत्र का विस्तार नहीं कर सकता है। अशक्त बाइट्स को अंत में डालकर लंबाई को प्रभावी रूप से कम किया जा सकता है, क्योंकि तर्क सी-शैली के अशक्त-समाप्त स्ट्रिंग्स हैं (यह अंत में खाली तर्कों का एक गुच्छा होने से अप्रभेद्य है)।

यदि आप वास्तव में खुदाई करना चाहते हैं, तो आप एक ओपन-सोर्स कार्यान्वयन के स्रोत को देख सकते हैं। लिनक्स पर, psदिलचस्प स्रोत नहीं है, आप सभी को वहां देखेंगे कि यह proc फाइल सिस्टम से कमांड लाइन तर्क पढ़ता है , में । इस फ़ाइल की सामग्री को उत्पन्न करने वाला कोड कर्नेल में, में है । प्रक्रिया की मेमोरी का हिस्सा (साथ पहुँचा ) पते से जाता है ; जब प्रक्रिया शुरू होती है और उसके बाद ये पते रिकॉर्ड नहीं किए जाते हैं।/proc/PID/cmdlineproc_pid_cmdline_readfs/proc/base.caccess_remote_vmmm->arg_startmm->arg_end

कुछ डेमॉन उनकी स्थिति को प्रतिबिंबित करने के लिए इस क्षमता का उपयोग, जैसे वे अपने को बदलने argv[1]की तरह एक स्ट्रिंग के लिए startingया availableया exiting। कई यूनिक्स वेरिएंट में setproctitleऐसा करने के लिए एक फ़ंक्शन है। कुछ प्रोग्राम इस क्षमता का उपयोग गोपनीय डेटा को छिपाने के लिए करते हैं। ध्यान दें कि यह सीमित उपयोग का है क्योंकि प्रक्रिया शुरू होने के दौरान कमांड लाइन के तर्क दिखाई देते हैं।

अधिकांश उच्च-स्तरीय भाषाएं स्ट्रिंग ऑब्जेक्ट्स के तर्कों को कॉपी करती हैं और मूल भंडारण को संशोधित करने का एक तरीका नहीं देती हैं। यहां एक सी प्रोग्राम है जो argvसीधे तत्वों को बदलकर इस क्षमता को प्रदर्शित करता है।

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
    int i;
    system("ps -p $PPID -o args=");
    for (i = 0; i < argc; i++)
    {
        memset(argv[i], '0' + (i % 10), strlen(argv[i]));
    }
    system("ps -p $PPID -o args=");
    return 0;
}

नमूना उत्पादन:

./a.out hello world
0000000 11111 22222

आप argvकर्ल सोर्स कोड में संशोधन देख सकते हैं । कर्ल एक फ़ंक्शन cleanargकोsrc/tool_paramhlp.c परिभाषित करता है जिसमें उपयोग करने वाले सभी रिक्त स्थान पर एक तर्क को बदलने के लिए उपयोग किया जाता है memset। में src/tool_getparam.cइस समारोह में कई बार, redacting द्वारा जैसे प्रयोग किया जाता है उपयोगकर्ता पासवर्ड । चूंकि फ़ंक्शन को पैरामीटर पार्सिंग से कहा जाता है, यह एक कर्ल इनवोकेशन में जल्दी होता है, लेकिन ऐसा होने से पहले कमांड लाइन को डंप करने से अभी भी कोई पासवर्ड दिखाई देगा।

चूंकि तर्कों को प्रक्रिया की अपनी मेमोरी में संग्रहीत किया जाता है, इसलिए उन्हें डिबगर का उपयोग करके बाहर से नहीं बदला जा सकता है।


महान! तो, उस चश्मे के बारे में, मैं इसका मतलब समझता हूं कि यह प्रक्रिया के रीड-राइट मेमोरी ( कॉपी-राइट मेमोरी में कॉपी के अलावा) के बाहर अपने कर्नेल स्टोर को प्रोसेस कमांड की मूल कमांड लाइन बनाने के लिए POSIX-compliant होगा। ? और फिर कर्नेल की मेमोरी के उस टुकड़े से तर्कों की रिपोर्ट की है, जो प्रक्रियाओं की रीड-राइट मेमोरी में किए गए किसी भी बदलाव को अनदेखा कर रहा है? लेकिन (अगर मुझे यह सही लगा?) तो अधिकांश UNIX भिन्नताएं पूर्व में भी नहीं होती हैं, इसलिए आप कर्नेल संशोधनों के बिना एक कार्यान्वयन नहीं कर सकते , क्योंकि मूल डेटा कहीं भी नहीं रखा गया है? psps
वाइल्डकार्ड

1
@Wildcard सही है। वहाँ यूनिक्स कार्यान्वयन हो सकते हैं जो मूल रखते हैं लेकिन मुझे नहीं लगता कि कोई भी आम करता है। सी भाषा argvप्रविष्टियों की सामग्री को बदलने की अनुमति देती है (आप सेट नहीं कर सकते हैं argv[i], लेकिन आप इसके argv[i][0]माध्यम से लिख सकते हैं argv[i][strlen(argv[i])]), इसलिए प्रक्रिया की मेमोरी में एक प्रति होनी चाहिए।
गिल्स

2
कर्ल स्रोत कोड में प्रासंगिक कार्य: github.com/curl/curl/blob/master/src/tool_paramhlp.c#L139
sebasth

4
@Wildcard, Solaris यह करता है। कमांड लाइन जिसे / usr / ucb / ps द्वारा देखा जाता है, वह स्वामित्व वाली (म्यूटेबल) कॉपी है। कमांड लाइन जिसे / usr / bin / ps द्वारा देखा जाता है वह कर्नेल के स्वामित्व वाली (अपरिवर्तनीय) कॉपी है। कर्नेल हालांकि पहले 80 अक्षर रखता है। और कुछ भी काट दिया जाता है।
बाउलऑफ्रेडेड

1
@Wildcard वास्तव में अनुगामी नल खाली तर्क हैं। में psउत्पादन, कुछ भी नहीं है की तरह वहाँ, लेकिन अगर आप की जाँच देखते हैं कि कितने रिक्त स्थान हाँ, यह एक फर्क पड़ता है, और आप से अधिक सीधे देख सकते हैं खाली तर्क का एक बहुत लग रहा है /proc/PID/cmdline
गाइल्स

14

अन्य उत्तर सामान्य तरीके से प्रश्न का उत्तर देते हैं। विशेष रूप से जवाब देने के लिए " यह प्रभाव कैसे प्राप्त किया जाता है? क्या यह कर्ल के स्रोत कोड में कहीं है? "

कर्ल स्रोत कोड के तर्क पार्सिंग खंड में , -uविकल्प निम्नानुसार है:

    case 'u':
      /* user:password  */
      GetStr(&config->userpwd, nextarg);
      cleanarg(nextarg);
      break;

और cleanarg()फ़ंक्शन को निम्नानुसार परिभाषित किया गया है:

void cleanarg(char *str)
{
#ifdef HAVE_WRITABLE_ARGV
  /* now that GetStr has copied the contents of nextarg, wipe the next
   * argument out so that the username:password isn't displayed in the
   * system process list */
  if(str) {
    size_t len = strlen(str);
    memset(str, ' ', len);
  }
#else
  (void)str;
#endif
}

इसलिए हम स्पष्ट रूप से देख सकते हैं कि उपयोगकर्ता नाम: पासवर्ड तर्क argvरिक्त स्थान के साथ अधिलेखित है, जैसा कि अन्य उत्तरों द्वारा वर्णित है।


मुझे यह पसंद है कि cleanargराज्यों में टिप्पणी स्पष्ट रूप से यह है कि यह वही कर रहा है जो सवाल पूछ रहा है!
फ्लोरिस

3

एक प्रक्रिया न केवल इसके मापदंडों को पढ़ सकती है, बल्कि उन्हें लिख भी सकती है।

मैं एक डेवलपर नहीं हूं, इसलिए मैं इस सामान से परिचित नहीं हूं, लेकिन बाहर से यह संभव हो सकता है कि पर्यावरण के मापदंडों के परिवर्तन के समान दृष्टिकोण के साथ:

https://stackoverflow.com/questions/205064/is-there-a-way-to-change-another-processs-environment-variables


ठीक है, लेकिन उदाहरण के लिए चल रहा है bash -c 'awk 1 /proc/$$/cmdline; set -- something; awk 1 /proc/$$/cmdline'कि कम से कम शेल में, मापदंडों को सेट करना यह संशोधित करने से अलग है कि कर्नेल प्रक्रिया मापदंडों के रूप में क्या देखता है।
वाइल्डकार्ड

4
एक खोल स्क्रिप्ट में @Wildcard स्थितीय तर्क हैं शुरू में प्रतियां के कुछ खोल प्रक्रिया के आदेश पंक्ति तर्क की। अधिकांश गोले स्क्रिप्ट को मूल तर्क को बदलने नहीं देते हैं।
गिल्स

@ गिल्स, हां, यह मेरी टिप्पणी का बिंदु था। :) यह कि सामान्य कथन जो एक प्रक्रिया कर सकता है (इस उत्तर का पहला वाक्य) उत्तर नहीं देता है कि क्या यह मौजूदा शेल विशेषताओं द्वारा प्राप्त किया जा सकता है। इसका उत्तर "नहीं" प्रतीत होता है, जो कि मैंने अपने प्रश्न के बहुत नीचे से अनुमान लगाया है।
वाइल्डकार्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.