কীভাবে কার্ল পিএস আউটপুটে প্রদর্শিত হতে কোনও পাসওয়ার্ডকে সুরক্ষা দেয়?


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 বলে যে

স্ট্রিংটি আর্গুমেন্ট তালিকার একটি সংস্করণ কিনা এটি শুরু করার সময় কমান্ডের কাছে প্রেরণ করা হয়েছিল কিনা বা অ্যাপ্লিকেশন দ্বারা সংশোধিত হতে পারে যুক্তিগুলির একটি সংস্করণ কিনা তা অনির্দিষ্ট। অ্যাপ্লিকেশনগুলি তাদের যুক্তি তালিকাটি সংশোধন করতে সক্ষম হতে পারে এবং সেই পরিবর্তনটি পিএসের আউটপুটে প্রতিবিম্বিত হয়।

এর উল্লেখ করার কারণটি হ'ল বেশিরভাগ ইউনিক্স রূপগুলি পরিবর্তনের প্রতিফলন ঘটায় তবে অন্য ধরণের অপারেটিং সিস্টেমে পসিক্স বাস্তবায়ন নাও করতে পারে।

এই বৈশিষ্ট্যটি সীমিত ব্যবহারের কারণ প্রক্রিয়াটি স্বেচ্ছাসেবী পরিবর্তন করতে পারে না। খুব কমপক্ষে, আর্গুমেন্টগুলির মোট দৈর্ঘ্য বাড়ানো যায় না, কারণ প্রোগ্রামটি সেই অবস্থানটি পরিবর্তন করতে পারে না যেখানে 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 যেমন: ব্যবহার করা হয় ব্যবহারকারী পাসওয়ার্ড । যেহেতু প্যারামিটার পার্সিং থেকে ফাংশনটি কল করা হয়েছে, এটি কার্লের অনুরোধের প্রথম দিকে ঘটে, তবে এটি হওয়ার আগে কমান্ড লাইনটি ফেলে দেওয়া এখনও কোনও পাসওয়ার্ড প্রদর্শন করবে।

যেহেতু আর্গুমেন্টগুলি প্রক্রিয়াটির নিজস্ব স্মৃতিতে সংরক্ষণ করা হয়, তাই ডিবাগার ব্যবহার না করে সেগুলি বাইরে থেকে পরিবর্তন করা যায় না।


গ্রেট! সুতরাং, সেই চশমাগুলির স্নিপেট সম্পর্কিত, আমি এটি বুঝতে পেরেছি যে এটি আপনার কর্নেলটিকে প্রক্রিয়াটির রিড-রাইটিং মেমরির বাইরে প্রক্রিয়াটির মূল কমান্ড লাইন আর্গুমেন্ট তৈরি করা (পঠন-লেখার মেমরির অনুলিপি ছাড়াও ) পসিক্স-সম্মতিযুক্ত হবে to ? এবং তারপরে psকার্নেলের মেমরির টুকরো থেকে প্রক্রিয়াগুলির 'রিড-রাইট মেমোরির কোনও পরিবর্তনকে উপেক্ষা করে রিপোর্টটি যুক্তি রয়েছে? তবে (যদি আমি এটি সঠিকভাবে পেয়েছি?) বেশিরভাগ ইউনিক্সের প্রকরণগুলি psপূর্বেরটিও করে না, তাই মূল তথ্যটি কোথাও রাখা হয়নি বলে আপনি কার্নেল পরিবর্তন ছাড়াই আধুনিকায়ন করতে পারবেন না ?
ওয়াইল্ডকার্ড

1
@ উইল্ডকার্ড সঠিক ইউনিক্স বাস্তবায়ন থাকতে পারে যা আসল রাখে তবে আমি মনে করি না যে সাধারণগুলির কোনওটিই করেন। সি ল্যাঙ্গুয়েজ বিষয়বস্তু পারবেন argvএন্ট্রি পরিবর্তন করা (যদি আপনি সেট করতে পারে না argv[i], কিন্তু আপনি লিখতে পারেন argv[i][0]মধ্য দিয়ে argv[i][strlen(argv[i])]), তাই প্রক্রিয়া স্মৃতিতে একটি কপি হতে হয়েছে।
গিলস

2
কার্ল উত্স কোডে প্রাসঙ্গিক ফাংশন: github.com/curl/curl/blob/master/src/tool_paramhlp.c#L139
সেবাসথ

4
@ উইল্ডকার্ড, সোলারিস এটি করে। / Usr / ucb / ps দ্বারা প্রদর্শিত কমান্ড লাইনটি প্রক্রিয়াটির মালিকানাধীন (পরিবর্তনযোগ্য) অনুলিপি। / Usr / bin / ps দ্বারা প্রদর্শিত কমান্ড লাইনটি কার্নেলের মালিকানাধীন (অপরিবর্তনীয়) অনুলিপি। কার্নেল যদিও প্রথমে 80 টি অক্ষর রাখে। অন্য কিছু ছাঁটা হয়েছে।
বাউলঅফরেড

1
@ উইল্ডকার্ড প্রকৃতপক্ষে অনুসরণযোগ্য নালগুলি খালি যুক্তি। ইন 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 অবস্থানগত আর্গুমেন্ট প্রাথমিকভাবে কপি এর কিছু শেল প্রক্রিয়া এর কমান্ড লাইন আর্গুমেন্ট। বেশিরভাগ শেল স্ক্রিপ্টটিকে আসল আর্গুমেন্টগুলি পরিবর্তন করতে দেয় না।
গিলস

@ গিলস, হ্যাঁ, এটিই আমার মন্তব্যের মূল বিষয় ছিল। :) এটি যে কোনও সাধারণ প্রক্রিয়া যা কোনও প্রক্রিয়া করতে পারে (এই উত্তরের প্রথম বাক্যটি) বিদ্যমান শেল বৈশিষ্ট্য দ্বারা এটি অর্জন করা যায় কিনা তার উত্তর দেয় না। এর উত্তরটি "না" হিসাবে উপস্থিত হয় যা আমি আমার প্রশ্নের একেবারে নীচে অনুমান করেছি।
ওয়াইল্ডকার্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.