আমি উপরে এটি ক্রিস ডাউন দ্বারা উত্তরের উত্তরের একটি টিউটোরিয়াল-শৈলী পুনঃনির্মাণ হিসাবে লিখেছি।
ব্যাশে আপনার শেল ভেরিয়েবল এর মতো থাকতে পারে
$ t="hi there"
$ echo $t
hi there
$
ডিফল্টরূপে, এই ভেরিয়েবলগুলি শিশু প্রক্রিয়াগুলির দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হয় না।
$ bash
$ echo $t
$ exit
তবে আপনি যদি তাদের রফতানির জন্য চিহ্নিত করেন, বাশ একটি পতাকা নির্ধারণ করবে যার অর্থ তারা সাব-প্রসেসের পরিবেশে যাবে (যদিও envp
প্যারামিটারটি খুব বেশি দেখা যায় না, main
আপনার সি প্রোগ্রামে তিনটি প্যারামিটার রয়েছে: main(int argc, char *argv[], char *envp[])
যেখানে পয়েন্টারের শেষ অ্যারেটি অ্যারে হয় তাদের সংজ্ঞা সহ শেল ভেরিয়েবলের)।
সুতরাং আসুন t
নিম্নলিখিত হিসাবে রফতানি করা যাক :
$ echo $t
hi there
$ export t
$ bash
$ echo $t
hi there
$ exit
উপরের t
সাব-শেলের মধ্যে পূর্বনির্ধারিত ছিল, এটি এখন আমরা রফতানি করার পরে এটি উপস্থিত হয় ( export -n t
আপনি যদি এটি রফতানি বন্ধ করতে চান তবে ব্যবহার করুন )।
তবে ব্যাশে ফাংশনগুলি একটি ভিন্ন প্রাণী। আপনি তাদের এইভাবে ঘোষণা করুন:
$ fn() { echo "test"; }
এবং এখন আপনি কেবল এটি ফাংশনটি কল করে যেন এটি অন্য শেল কমান্ড হিসাবে কল করতে পারেন:
$ fn
test
$
আবার, আপনি যদি একটি সাবস্কেল স্পান করেন তবে আমাদের ফাংশনটি রফতানি হবে না:
$ bash
$ fn
fn: command not found
$ exit
আমরা এর সাথে একটি ফাংশন রফতানি করতে পারি export -f
:
$ export -f fn
$ bash
$ fn
test
$ exit
এখানে জটিল অংশটি রয়েছে: fn
শেল ভেরিয়েবলের আমাদের রফতানির t
উপরে যেমন ছিল তেমন একটি রফতানি ফাংশনটি পরিবেশের পরিবর্তনশীলে রূপান্তরিত হয় । fn
স্থানীয় চলক যখন ছিল তখন এটি ঘটে না , তবে রফতানির পরে আমরা এটিকে শেল ভেরিয়েবল হিসাবে দেখতে পারি। যাইহোক, যদি আপনি করতে পারেন এছাড়াও একটি নিয়মিত (অর্থাত, অ ফাংশন) শেল একই নামের পরিবর্তনশীল আছে। ভেরিয়েবলের বিষয়বস্তুর উপর ভিত্তি করে ব্যাশ পৃথক করে:
$ echo $fn
$ # See, nothing was there
$ export fn=regular
$ echo $fn
regular
$
এখন আমরা env
রফতানির জন্য চিহ্নিত সমস্ত শেল ভেরিয়েবলগুলি প্রদর্শন করতে fn
এবং নিয়মিত এবং ফাংশন উভয়ই প্রদর্শন করতে ব্যবহার করতে পারি fn
:
$ env
.
.
.
fn=regular
fn=() { echo "test"
}
$
একটি সাব-শেল উভয় সংজ্ঞা সংক্রামিত করবে: একটি নিয়মিত পরিবর্তনশীল হিসাবে এবং একটি ফাংশন হিসাবে:
$ bash
$ echo $fn
regular
$ fn
test
$ exit
fn
আমরা উপরের মতো বা সরাসরি নিয়মিত পরিবর্তনশীল কার্যভার হিসাবে সংজ্ঞায়িত করতে পারি :
$ fn='() { echo "direct" ; }'
নোট করুন এটি করা একটি উচ্চ অস্বাভাবিক জিনিস! সাধারণত আমরা ফাংশন নির্ধারণ হবে fn
হিসাবে আমরা সাথে উপরে করেনি fn() {...}
সিনট্যাক্স। তবে বাশ পরিবেশের মাধ্যমে এটি রফতানি করে, আমরা উপরের নিয়মিত সংজ্ঞায় সরাসরি "শর্ট কাট" করতে পারি। মনে রাখবেন যে, (আপনার অনুভূতি পাল্টা, সম্ভবত) এই নেই না একটি নতুন ফাংশন ফলে fn
বর্তমান শেল পাওয়া যায়। তবে আপনি যদি একটি ** সাব ** শেল ফেলে থাকেন তবে তা হবে will
আসুন ফাংশনের রফতানি বাতিল করুন fn
এবং নতুন নিয়মিত fn
(উপরে দেখানো হয়েছে) অক্ষত রেখে দিন।
$ export -nf fn
এখন ফাংশনটি fn
আর রফতানি হয় না, তবে নিয়মিত পরিবর্তনশীল fn
হয় এবং এটি এতে থাকে () { echo "direct" ; }
।
এখন যখন কোনও সাবশেল একটি নিয়মিত পরিবর্তনশীল দেখবে যা এর সাথে শুরু হয় বাকীটিকে ()
ফাংশন সংজ্ঞা হিসাবে ব্যাখ্যা করে। তবে এটি তখনই যখন একটি নতুন শেল শুরু হয়। যেমনটি আমরা উপরে দেখেছি, কেবল নিয়মিত শেল ভেরিয়েবলের সংজ্ঞা দিয়ে ()
এটি কোনও ফাংশনের মতো আচরণ করে না। আপনাকে একটি সাব-শেল শুরু করতে হবে।
এবং এখন "শেলশক" বাগ:
যেমনটি আমরা সবেমাত্র দেখেছি, যখন একটি নতুন শেল ()
এটি দিয়ে শুরু করে নিয়মিত ভেরিয়েবলের সংজ্ঞা যুক্ত করে তখন এটি একটি ফাংশন হিসাবে ব্যাখ্যা করে। যাইহোক, যদি ক্লোজিং বন্ধনী পরে ফাংশনটি সংজ্ঞায়িত করে আরও কিছু দেওয়া থাকে তবে এটি সেখানে যা আছে তা কার্যকর করে।
এগুলি আবার প্রয়োজনীয়তা:
- নতুন বাশ তৈরি হয়েছে
- একটি পরিবেশের পরিবর্তনশীল ইনজেক্ট করা হয়
- এই পরিবেশের পরিবর্তনশীলটি "()" দিয়ে শুরু হয় এবং তারপরে বন্ধনীগুলির ভিতরে একটি ফাংশন বডি থাকে এবং তারপরে কমান্ড থাকে
এই ক্ষেত্রে, একটি দুর্বল ব্যাশ পরবর্তী নির্দেশগুলি কার্যকর করবে।
উদাহরণ:
$ export ex='() { echo "function ex" ; }; echo "this is bad"; '
$ bash
this is bad
$ ex
function ex
$
নিয়মিত রফতানি ভেরিয়েবলটি ex
সাবশেলের কাছে প্রেরণ করা হয় যা একটি ফাংশন হিসাবে ব্যাখ্যা করা হয়েছিল তবে সাবিল শিট হওয়ার সাথে সাথে ট্রেলিং ex
কমান্ডগুলি কার্যকর করা হয়েছিল ( this is bad
)।
চিকিত্সা এক-লাইন পরীক্ষা ব্যাখ্যা
শেলশক দুর্বলতার জন্য পরীক্ষার জন্য একটি জনপ্রিয় ওয়ান-লাইনার হ'ল @ জিপ্পির প্রশ্নে উদ্ধৃত এক:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
এখানে একটি ব্রেক-ডাউন রয়েছে: প্রথমে :
ইন ব্যাশটি কেবল একটি সংক্ষিপ্ত হাতের জন্য true
। true
এবং :
উভয়ই বাশে সত্য (আপনি এটি অনুমান করেছিলেন) মূল্যায়ন করেছেন:
$ if true; then echo yes; fi
yes
$ if :; then echo yes; fi
yes
$
দ্বিতীয়ত, env
কমান্ড (এছাড়াও ব্যাশ পাতাটা) এনভায়রনমেন্ট ভেরিয়েবল ছাপে (যেমন আমরা উপরোক্ত দেখেছি) কিন্তু এছাড়াও একটি রপ্তানি পরিবর্তনশীল (অথবা ভেরিয়েবল) যে কমান্ড দেওয়া সঙ্গে একটি একক কমান্ড চালানোর জন্য ব্যবহার করা যেতে পারে, এবং bash -c
থেকে একটি কমান্ডের চালায় তার কম্যান্ড-লাইন:
$ bash -c 'echo hi'
hi
$ bash -c 'echo $t'
$ env t=exported bash -c 'echo $t'
exported
$
সুতরাং এই সমস্ত জিনিস একসাথে সেলাই, আমরা কমান্ড হিসাবে ব্যাশ চালাতে পারি, এটি করার মতো কিছু ডামি জিনিস দিতে পারি (যেমন bash -c echo this is a test
) এবং এমন একটি পরিবর্তনশীল রফতানি করি যা দিয়ে শুরু হয় ()
যাতে সাবশেল এটি একটি ফাংশন হিসাবে ব্যাখ্যা করবে। শেলশক উপস্থিত থাকলে, এটি অবিলম্বে সাব-শেলটিতে কোনও চলমান কমান্ড কার্যকর করবে। যেহেতু আমরা পাস করি ফাংশনটি আমাদের কাছে অপ্রাসঙ্গিক (তবে অবশ্যই পার্স করতে হবে!) আমরা স্বল্পতম বৈধ ফাংশনটি কল্পনাযোগ্য ব্যবহার করি:
$ f() { :;}
$ f
$
ফাংশন f
এখানে শুধু executes :
কমান্ড যা সত্য করে প্রস্থান করে ফেরৎ। এখন কিছু "দুষ্ট" কমান্ডের সাথে যুক্ত করুন এবং একটি সাবশেলের নিয়মিত পরিবর্তনশীল রফতানি করুন এবং আপনি জিতবেন। এখানে আবার ওয়ান-লাইনার:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
তাই শেষ পর্যন্ত টেপযুক্ত x
একটি সাধারণ বৈধ ফাংশন সহ একটি নিয়মিত পরিবর্তনশীল হিসাবে রফতানি করা হয় echo vulnerable
। এটি বাশ-এ স্থানান্তরিত হয় , এবং ব্যাশ x
একটি ফাংশন হিসাবে ব্যাখ্যা করে (যা আমরা যত্ন করি না) তবে echo vulnerable
শেলশক উপস্থিত থাকলে সম্ভবত সম্পাদন করে ।
this is a test
বার্তাটি সরিয়ে আমরা ওয়ান-লাইনারটি কিছুটা ছোট করতে পারি :
$ env x='() { :;}; echo vulnerable' bash -c :
এটি বিরক্ত করে না this is a test
কিন্তু :
আবার সাইলেন্ট কমান্ড চালায় । (আপনি যদি তা ছেড়ে দেন -c :
তবে আপনি সাবশেলে বসে ম্যানুয়ালি বেরিয়ে আসতে পারেন)) সম্ভবত সবচেয়ে ব্যবহারকারী-বান্ধব সংস্করণটি হ'ল:
$ env x='() { :;}; echo vulnerable' bash -c "echo If you see the word vulnerable above, you are vulnerable to shellshock"