මා මෙය ලිව්වේ ඉහත ක්රිස් ඩවුන් විසින් ලබා දුන් විශිෂ්ට පිළිතුර නැවත නිබන්ධනය කිරීමෙනි.
බාෂ් වලදී ඔබට මේ වගේ ෂෙල් විචල්යයන් තිබිය හැකිය
$ 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
ඔබට එය අපනයනය කිරීම නැවැත්වීමට අවශ්ය නම් භාවිතා කරන්න).
නමුත් bash හි කාර්යයන් වෙනස් සත්වයෙකි. ඔබ ඒවා මෙසේ ප්රකාශ කරයි:
$ fn() { echo "test"; }
දැන් ඔබට ශ්රිතය වෙනත් ෂෙල් විධානයක් ලෙස ඇමතීමෙන් එය ක්රියාත්මක කළ හැකිය:
$ fn
test
$
නැවත වරක්, ඔබ උපසිරැසියක් ඇති කළහොත්, අපගේ කාර්යය අපනයනය නොවේ:
$ bash
$ fn
fn: command not found
$ exit
අපට ශ්රිතයක් අපනයනය කළ හැක්කේ export -f
:
$ export -f fn
$ bash
$ fn
test
$ exit
මෙන්න උපක්රමශීලී කොටස: අපනයන ශ්රිතයක් fn
පරිසර විචල්යයක් බවට පරිවර්තනය වන්නේ අපගේ ෂෙල් විචල්යය අපනයනය කළ ආකාරයටම ය t
. fn
දේශීය විචල්යයක් වූ විට මෙය සිදු නොවේ , නමුත් අපනයනයෙන් පසුව අපට එය ෂෙල් විචල්යයක් ලෙස දැකිය හැකිය. කෙසේ වෙතත්, ඔබට එකම නමක් සහිත සාමාන්ය (එනම් ක්රියාකාරී නොවන) ෂෙල් විචල්යයක් ද තිබිය හැකිය . විචල්යයේ අන්තර්ගතය මත පදනම්ව bash වෙන්කර හඳුනා ගනී:
$ 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
වත්මන් ෂෙල් වලින් ලබා ගත හැක. නමුත් ඔබ ** උප ** කවචයක් බිහි කළහොත් එය එසේ වනු ඇත.
ශ්රිතයේ අපනයනය අවලංගු 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
මඟින් :
විධානය ක්රියාත්මක වන අතර එය සත්ය වන අතර පිටවෙයි. දැන් එම “නපුරු” විධානයට එකතු කර නිත්ය විචල්යයක් උප කුලකයකට අපනයනය කරන්න. මෙන්න නැවත එක්-ලයිනර් ය:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
ඒ නිසා x
සමග සරල වලංගු කාර්යය නිතිපතා විචල්ය අපනයනය echo vulnerable
අවසානය දක්වා මත tacked. මෙය bash වෙත සම්මත කර ඇති අතර, bash x
විසින් ශ්රිතයක් ලෙස අර්ථ නිරූපණය කරයි (එය අප ගණන් ගන්නේ නැත) එවිට සමහර විට shellshock තිබේ echo vulnerable
නම් එය ක්රියාත්මක කරයි .
this is a test
පණිවිඩය ඉවත් කිරීමෙන් අපට එක් ලයිනර් ටිකක් කෙටි කළ හැකිය :
$ env x='() { :;}; echo vulnerable' bash -c :
මෙය කරදර නොවන this is a test
නමුත් නිහ :
command විධානය නැවත ක්රියාත්මක කරයි. (ඔබ ඉවත්ව ගියහොත් ඔබ -c :
උපසිරැසියෙහි හිඳ අතින් පිටවිය යුතුය.) සමහර විට වඩාත්ම පරිශීලක-හිතකාමී අනුවාදය මෙය විය හැකිය:
$ env x='() { :;}; echo vulnerable' bash -c "echo If you see the word vulnerable above, you are vulnerable to shellshock"