আমি কীভাবে স্পষ্টভাবে এবং নিরাপদে বাশ-এ বিল্ট-ইন কমান্ডটি ব্যবহার করতে বাধ্য করব


19

একটি অনুরূপ প্রশ্ন রয়েছে যা 'মোড়ানো' দৃশ্যের সাথে সম্পর্কিত, যেখানে আপনি উদাহরণস্বরূপ cdএকটি আদেশের মাধ্যমে প্রতিস্থাপন করতে চান যা বিল্টিনকে কল করেcd

তবে শেলশক এট আলের আলোকে এবং জেনে যে বাশ পরিবেশ থেকে ফাংশন আমদানি করে, আমি কয়েকটি পরীক্ষা করেছি এবং আমি বিল্টিনকে নিরাপদে কল করার কোনও উপায় খুঁজে পাই না cd আমার স্ক্রিপ্ট থেকে ।

এই বিবেচনা

cd() { echo "muahaha"; }
export -f cd

এই পরিবেশে যে কোনও স্ক্রিপ্টগুলি ব্যবহার করে cdকলগুলি ভেঙে যাবে (এমন কোনও কিছুর প্রভাব বিবেচনা করুন)cd dir && rm -rf . )।

কমান্ডের প্রকারটি পরীক্ষা করার জন্য কমান্ড রয়েছে (সুবিধাজনকভাবে বলা হয় type) এবং কোনও ফাংশন ( builtinএবং command) এর পরিবর্তে বিল্টিন সংস্করণ চালানোর জন্য কমান্ড রয়েছে । তবে দেখুন এবং দেখুন, এগুলি পাশাপাশি ফাংশন ব্যবহার করে ওভাররাইড করা যেতে পারে

builtin() { "$@"; }
command() { "$@"; }
type() { echo "$1 is a shell builtin"; }

নিম্নলিখিত উত্পাদন করবে:

$ type cd
cd is a shell builtin
$ cd x
muahaha
$ builtin cd x
muahaha
$ command cd x
muahaha

বিল্টিন কমান্ডটি ব্যবহার করার জন্য বাশকে নিরাপদে জোর করার কোনও উপায় আছে কি না, বা কমপক্ষে সনাক্ত করতে হবে যে কোনও কমান্ড কোনও বিল্টিন নয়, পুরো পরিবেশটি পরিষ্কার না করেই?

আমি বুঝতে পেরেছি যে কেউ যদি আপনার পরিবেশ নিয়ন্ত্রণ করে তবে আপনি সম্ভবত কোনওভাবেই বিভ্রান্ত হয়ে পড়েছেন, তবে কমপক্ষে এলিয়াসগুলির জন্য আপনি এর \আগে একটি tingোকিয়ে উপন্যাসটি কল না করার বিকল্প পেয়েছেন ।


আপনি এর envআগে কমান্ডটি ব্যবহার করে আপনার স্ক্রিপ্টটি চালাতে পারেন :env -i <SCRIPT.sh>
আরকাদিউস দ্রবকিজেক

কেবলমাত্র যদি envকোনও ফাংশন হিসাবে পুনরায় সংজ্ঞায়িত না হয়। এটা ভয়াবহ। আমি প্রথমে ভেবেছিলাম যে বিশেষ অক্ষরগুলি সহায়তা করবে - সম্পূর্ণ পথের সাথে কল /করা .যা উত্সটি ব্যবহার করে, এবং আরও অনেক কিছু। তবে এগুলি ফাংশন নামের জন্যও ব্যবহার করা যেতে পারে! আপনি যে কোনও ফাংশন চান তা পুনরায় সংজ্ঞায়িত করতে পারেন, তবে আসল কমান্ডে কল করা ফিরে পাওয়া শক্ত।
প্রাচ্য

1
সত্য, তবে আপনি যদি কোনও আপসকৃত মেশিনে কোনও স্ক্রিপ্ট চালাতে যাচ্ছেন তবে আপনি যেভাবেই স্ক্রু হয়ে গেছেন। বিকল্পভাবে, আপনার স্ক্রিপ্টটি এতে লিখুন #/bin/shযদি এটি ডিফল্ট ইন্টারেক্টিভ শেল নয়।
আরকাদিউস দ্রবকিজিক

উত্তর:


16

অলিভিয়ার ডি প্রায় সঠিক, তবে আপনাকে POSIXLY_CORRECT=1দৌড়ানোর আগে সেট করতে হবে unset। পসিক্সের বিশেষ বিল্ট-ইনগুলির ধারণা রয়েছে এবং ব্যাশ এটি সমর্থন করেunsetএইরকম একটি অন্তর্নির্মিত। জন্য অনুসন্ধান করুন SPECIAL_BUILTINমধ্যে builtins/*.cএকটি তালিকার জন্য ব্যাশ উৎস, এটা অন্তর্ভুক্ত set, unset, export, evalএবং source

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

দুর্বৃত্ত unsetএখন পরিবেশ থেকে সরিয়ে দেওয়া হয়েছে, যদি তোমরা আনসেট command, type, builtinতারপর আপনি এগিয়ে যেতে সক্ষম হওয়া উচিত, কিন্তুunset POSIXLY_CORRECT আপনি অ POSIX আচরণ বা উন্নত ব্যাশ বৈশিষ্ট্য উপর নির্ভর করছে পারেন।

এটি যদিও উপকরণগুলিকে সম্বোধন করে না , সুতরাং আপনার অবশ্যই \unsetএটি অবশ্যই ইন্টারেক্টিভ শেল (বা সর্বদা, ক্ষেত্রে expand_aliasesকার্যকর হয়) কাজ করে তা নিশ্চিত হতে হবে ।

বিড়ম্বনার জন্য, এই সবকিছু ঠিক করা উচিত , আমি মনে করি:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

( while, do, doneএবং [[শব্দ সংরক্ষিত হয় এবং সাবধানতা অবলম্বন প্রয়োজন হবে না।) মনে রাখবেন ব্যবহার করছেন unset -fসেট না ফাংশন নিশ্চিত হতে, ভেরিয়েবল এবং ফাংশন একই নামস্থান ভাগ যদিও এটা সম্ভব উভয় অস্তিত্ব জন্য একযোগে যে ক্ষেত্রে (Etan রিসনার ধন্যবাদ) দুবার আনসেট-ইন করাও কৌতুক করবে। আপনি কেবল ফাংশনটি কেবলমাত্র চিহ্নিত করতে পারেন , ব্যাশ আপনাকে কেবলমাত্র পাঠ্য ফাংশনটি সেট করে বাশ করতে পারে না including ব্যাশ -৪.২ সহ, ব্যাশ -৪.৩ আপনাকে বাধা দেয় না তবে এটি বিশেষ বিল্টিনগুলিকে সম্মান জানায়POSIXLY_CORRECT সেট করার ।

পঠনযোগ্য POSIXLY_CORRECTকোনও আসল সমস্যা নয়, এটি কোনও বুলিয়ান বা পতাকা নয় এটির উপস্থিতি পসিক্স মোডকে সক্ষম করে, তাই যদি এটি কেবল পঠন হিসাবে উপস্থিত থাকে তবে আপনি পসিক্স বৈশিষ্ট্যগুলিতে নির্ভর করতে পারেন, এমনকি মানটি খালি বা 0 থাকলেও আপনাকে কেবল প্রয়োজন হবে সমস্যাযুক্ত ফাংশনগুলি আনসেট করুন উপরের চেয়ে আলাদাভাবে, সম্ভবত কিছু কাট-পেস্ট সহ:

\help -s "*" | while IFS=": " read cmd junk; do echo \\unset -f $cmd; done

(এবং কোনও ত্রুটি উপেক্ষা করুন) বা অন্য কিছু স্ক্রিপ্টোব্যাটিক্সে নিযুক্ত হন ।


অন্যান্য নোট:

  • functionএটি একটি সংরক্ষিত শব্দ, এটি অ্যালাইজড হতে পারে তবে কোনও ফাংশন দিয়ে ওভাররাইড করা যায় না। (Aliasing functionআস্তে বিরক্তিজনক কারণ \function নয় এটা বাইপাস একটি উপায় হিসেবে গ্রহণযোগ্য)
  • [[, ]]সংরক্ষিত শব্দ, এগুলিকে এনিয়াস করা যেতে পারে (যা এড়ানো হবে) তবে কোনও ফাংশন দিয়ে ওভাররাইড করা হবে না (যদিও ফাংশনগুলির নাম দেওয়া যেতে পারে)
  • (( কোনও ক্রিয়াকলাপের জন্য কোনও বৈধ নাম নয়, বা একটি উপাধি নয়

মজার, ধন্যবাদ! আমি আমার কাছে অদ্ভুত বলে মনে করি যে বাশ এট ওলাইট্রাইট হওয়া থেকে রক্ষা না করার জন্য ডিফল্ট হবে unset
ফ্যালস্ট্রো

এই -fযুক্তি প্রয়োজন এটি unsetনা? অন্যথায় যদি বিল্টিন হিসাবে একই নামের একটি ভেরিয়েবল এবং ফাংশন উভয়কে সংজ্ঞায়িত করা হয় তবে unsetপ্রথমে আনসেট করার জন্য চলকটি বেছে নেবে। এছাড়াও কোনও অস্পষ্ট কার্যকারিতা সেট করা থাকলে এটি ব্যর্থ হয় readonly? (যদিও এটি সনাক্তযোগ্য এবং একটি মারাত্মক ত্রুটি করা যেতে পারে)) এছাড়াও [এটি মনে হয় বিল্টিনটিকে মিস করে ।
এটান রিজনার

1
আমি মনে করি না যে \unset -f unsetএটি বোঝা যায়, প্রদত্ত লুপে এটি করা হবে will যদি unsetকোনও ফাংশন হয় \unsetতবে আপনি বিল্টিনের পরিবর্তে এটি সমাধান করতে পারেন তবে \unsetপসিক্স মোড কার্যকর হওয়ার পরে আপনি নিরাপদে ব্যবহার করতে পারবেন । স্পষ্টভাবে কলিং \unset -fউপর [, .এবং :, যদিও একটি ভাল ধারণা হতে পারে আপনার Regex বাদ তাদের। আমিও যোগ হবে -fথেকে \unsetলুপ, এবং would \unset POSIXLY_CORRECTলুপ পর, আগে পরিবর্তে। \unalias -a(পরে \unset -f unalias) পরবর্তী কমান্ডগুলিতে একজনকে নিরাপদে পলায়নের পূর্বাভাস দেয়।
অ্যাড্রিয়ান গন্টার

1
@ অ্যাড্রিয়ানগ্যান্টার চেষ্টা করুন:, [[ ${POSIXLY_CORRECT?non-POSIX mode shell is untrusted}x ]]এটি ভেরিয়েবলটি আনসেট না থাকলে নির্দেশিত ত্রুটিটি সহ একটি অ ইন্টারঅ্যাক্টিভ স্ক্রিপ্টের প্রস্থান করতে পারে, বা এটি সেট করা থাকলে (খালি, বা কোনও মান) অবিরত করবে।
মিঃ স্পুর্যাটিক

1
"আপনাকে অবশ্যই ব্যবহার করতে হবে \unset" ... এটি লক্ষ করা উচিত যে যে কোনও চরিত্রের উদ্ধৃতি কেবলমাত্র প্রথমটি নয়, ওরফে সম্প্রসারণ এড়াতে কাজ করবে। un"se"tঠিক পাশাপাশি কাজ করবে, কম পাঠযোগ্য হবে ab "প্রতিটি সাধারণ কমান্ডের প্রথম শব্দ, যদি উদ্ধৃত না হয়, এটির একটি উলাম আছে কিনা তা পরীক্ষা করা হয়।" - বাশ রেফ
রবিন এ

6

আমি বুঝতে পেরেছি যে কেউ যদি আপনার পরিবেশকে নিয়ন্ত্রণ করে তবে আপনি সম্ভবত যেভাবেই খারাপ হয়ে গেছেন

হ্যা সেটাই. আপনি যদি অজানা পরিবেশে কোনও স্ক্রিপ্ট চালান, LD_PRELOADশেল প্রক্রিয়াটি এমনকি আপনার স্ক্রিপ্টটি পড়ার আগে শেল প্রক্রিয়াটিকে স্বেচ্ছাসেবক কোড কার্যকর করতে শুরু করে সমস্ত ধরণের জিনিস ভুল হতে পারে । স্ক্রিপ্টের অভ্যন্তর থেকে প্রতিকূল পরিবেশের বিরুদ্ধে রক্ষা করার চেষ্টা নিরর্থক।

সুডো এক দশক ধরে বাশ ফাংশন সংজ্ঞার মতো মনে হচ্ছে এমন কোনও কিছু সরিয়ে পরিবেশকে স্বাস্থ্যকর করে তুলছে। শেলশক থেকে , অন্যান্য পরিবেশগুলি যা একটি সম্পূর্ণরূপে নির্ভরযোগ্য পরিবেশে শেল স্ক্রিপ্ট চালায় না সেগুলি অনুসরণ করেছে।

অবিশ্বস্ত সত্তা দ্বারা নির্ধারিত পরিবেশে আপনি কোনও স্ক্রিপ্ট নিরাপদে চালাতে পারবেন না। সুতরাং ফাংশন সংজ্ঞা সম্পর্কে উদ্বেগ উত্পাদনশীল নয়। আপনার পরিবেশটি স্যানিটাইজ করুন এবং এমন ভেরিয়েবলগুলি করার ক্ষেত্রে বাশ ফাংশন সংজ্ঞা হিসাবে ব্যাখ্যা করবে।


1
আমি এর সাথে পুরোপুরি একমত নই। সুরক্ষা "স্যানিটাইজড" বা "নিরবচ্ছিন্ন" এর আশেপাশে কেন্দ্রিক বাইনারি প্রস্তাব নয়। এটি শোষণের সুযোগগুলি সরিয়ে দেওয়ার বিষয়ে। এবং দুর্ভাগ্যক্রমে, আধুনিক সিস্টেমগুলির জটিলতার অর্থ অনেকগুলি শোষণের সুযোগ রয়েছে যা সঠিকভাবে লক করে দেওয়া দরকার। নিরীহ-আপাতদৃষ্টিতে উজানের উপরের আক্রমণগুলির আশেপাশের অনেকগুলি শোষণের কেন্দ্র, যেমন PATH ভেরিয়েবল পরিবর্তন করা, অন্তর্নির্মিত কার্যগুলি পুনরায় সংজ্ঞায়িত করা ইত্যাদি a কোনও একক ব্যক্তিকে বা প্রোগ্রামকে করার সুযোগ দেয় এবং আপনার পুরো সিস্টেমটি দুর্বল।
দেজয় ক্লেটন

@ দেজেক্লেটন প্রথম বাক্যটি বাদে আমি আপনার মন্তব্যের সাথে পুরোপুরি একমত, কারণ এটি কোনওভাবেই আমার উত্তরের সাথে কীভাবে বিরোধিতা করে তা আমি দেখতে পাচ্ছি না। শোষণের সুযোগ অপসারণ সাহায্য করে, তবে আক্রমণটির মধ্যে একটি তুচ্ছ ত্বক এটি কাজ করতে দেয় যেখানে কেবলমাত্র অর্ধেকটিকে সরিয়ে না দেয়।
গিলস 'অশুভ হওয়া বন্ধ করুন'

আমার বক্তব্যটি হ'ল আপনি কেবল "আপনার পরিবেশকে স্যানিটাইজ" করতে পারবেন না এবং তারপরে বিভিন্ন আক্রমণকারী ভেক্টর সম্পর্কে উদ্বেগ বন্ধ করতে পারবেন না। কখনও কখনও এটি "স্ক্রিপ্টের অভ্যন্তর থেকে প্রতিকূল পরিবেশের বিরুদ্ধে সুরক্ষা" প্রদান করে। এমনকি যদি আপনি "ফাংশন সংজ্ঞা" সমস্যাটি সমাধান করেন, তবুও আপনাকে এমন কিছু বিষয় নিয়ে চিন্ত করতে হবে যেমন একটি PATH থাকার কারণে যেখানে কেউ "বিড়াল" বা "এলএস" নামে একটি কাস্টম স্ক্রিপ্ট ডিরেক্টরিতে রাখতে পারে এবং তারপরে "বিড়াল" কে আহ্বান করে এমন কোনও স্ক্রিপ্ট "/ বিন / বিড়াল" এবং "/ বিন / এলএস" এর পরিবর্তে "বা" এলএস "কার্যকরভাবে একটি শোষণ কার্যকর করছে।
দেজয় ক্লেটন

@ দেজাইক্লেটন স্পষ্টতই পরিবেশকে স্যানিটাইজ করা আক্রমণ সম্পর্কিত ভেক্টরগুলির সাথে সম্পর্কিত নয় যা পরিবেশের সাথে সম্পর্কিত নয়। (উদাহরণস্বরূপ কোনও স্ক্রিপ্ট যা /bin/catএকটি ক্রুটে কল করে যে কোনও কিছু কল করতে পারে)) পরিবেশকে স্যানিটাইজ করা আপনাকে এক বিদ্বেষ দেয় PATH(ধরে নিবেন আপনি এটি অবশ্যই করছেন)। আমি এখনও আপনার বক্তব্য দেখতে পাচ্ছি না।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

PATH অন্যতম শোষণের জন্য সবচেয়ে বড় সুযোগ এবং এই বিষয়টি বিবেচনা করে যে অনেক প্রশ্নোত্তর PATH অনুশীলনগুলি সুরক্ষা ব্লগগুলিতে প্রস্তাবিত পরামর্শ হিসাবে নথিভুক্ত করা হয়েছে এবং এ জাতীয় অ্যাপ্লিকেশনগুলি যাতে কাজ করে তা নিশ্চিত করার জন্য কখনও কখনও ইনস্টল করা অ্যাপ্লিকেশনগুলি PATH পুনরায় অর্ডার করে, আমি কীভাবে দেখতে পারি না স্ক্রিপ্টের মধ্যে রক্ষণাত্মক কোডিং একটি খারাপ ধারণা হবে। আপনি যে বুদ্ধিমান PATH হিসাবে বিবেচনা করছেন তা বাস্তবে আপনার মুখোমুখি না হওয়া শোষণের পক্ষে ঝুঁকিপূর্ণ হতে পারে।
দেজয় ক্লেটন

1

আপনি unset -fবিল্টিন, কমান্ড এবং টাইপ করুন ফাংশনগুলি সরাতে ব্যবহার করতে পারেন।


2
দুঃখিত, unset() { true; }এটি যত্ন নেয়
ফালস্ট্রো

1
অভিশাপ! এবং সংজ্ঞায়িত ফাংশন তালিকাভুক্ত করা একটি বিল্টিনের উপরও নির্ভর করে। আমি ছেড়ে!
ওডিসি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.