シェルコードを学べるお弁当教室【後編】
市田 達也
![シェルコードを学べるお弁当教室【後編】](/assets/rtc/prod-rtc-blog/wp-content/uploads/2016/11/24112855/346c7a06275b8ae90fb09ea945bb5500.png)
リクルートテクノロジーズでセキュリティアナリストをしている市田です。
前回に引き続き「シェルコードを学べるお弁当教室 ~ icchii bento cooking studio ~」の内容で、今回は、Linux 32ビット OSにおけるシェル奪取弁当についてお話しします。
シェルの取得
「コマンドシェルを攻撃者が利用可能になると、その権限の範囲で任意のコードが実行できる」、これが <<シェル> >を攻撃者に奪取される脅威です。
そしてもしもroot(admin)権限でシェルを取得されると、システム破壊も可能となります。たとえばログファイルも削除され、消息不明の迷宮入りのインシデント対応を余儀なくされることもあり得ます。root(admin)のパスワードは強固にかつ管理も徹底すべしと言われる所以です。本日はそのコマンドシェルを実行するシェルコード弁当を作ります。
Linuxなお客様用の弁当 その2:シェル奪取弁当
まずコマンドシェルを実行するには、「誰が」つまり「どのユーザアカウントが」という設定が必要になります。よって、ユーザ設定とコマンドシェル実行(EXEC)という2重弁当となります。
![%e3%81%8a%e5%bc%81%e5%bd%93%e7%ae%b1%ef%bc%9d%e3%82%b7%e3%82%a7%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%893](/assets/rtc/prod-rtc-blog/wp-content/uploads/2016/11/18120508/bf77f158d87a275c42294af92ea620b4.png)
次にそのお弁当レシピを記載します。今回も攻撃コードはコンプライアンス上、公開しませんが、本レシピにて概要と流れをつかんでいただけると幸いです。
まずは1段目のお弁当です。だいたいご飯が入っている段ですね。
![%e3%81%8a%e5%bc%81%e5%bd%93%e7%ae%b1%ef%bc%9d%e3%82%b7%e3%82%a7%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%894](/assets/rtc/prod-rtc-blog/wp-content/uploads/2016/11/18120511/22f383a65b8981f6b22d4493c8c41049.png)
今回はユーザID(UID)をroot (0)で設定します。
ポイントは手順3の「/bin/dashNAAAABBBB」の部分でdashはDebian Almquist shellのことでDabian OSでのUNIX Shellです。これは実行環境のOSに合わせて変えてください。
N, AAAA,BBBBは後程必要になるメモリ領域で、さきに仮文字で確保しておきます。
次に2段目のおかずの段です。
![%e3%81%8a%e5%bc%81%e5%bd%93%e7%ae%b1%e3%82%b7%e3%82%a7%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%895](/assets/rtc/prod-rtc-blog/wp-content/uploads/2016/11/18122852/10ad6594969396960f939feaba36f986.png)
「N」はNULL値を挟むために利用し、「AAAA」にはコマンドシェルの引数を格納している実効アドレスが割り当てられます。
「BBBB」は環境変数を指定する場所ですが今回は使いませんのでNULL値を入れます。NULL値を入れる領域には「NULLアドレス*」とレシピ内で表現します。
パーツが多くてなかなか複雑ですね。もう少しわかりやすく説明すると、
今回利用するレジスタ(おかず)はA,B,C,Dの4つで、
EBXには「/bin/dashNAAAABBBB」の先頭が格納されているアドレスが入っています
よって、各パーツには以下のようにアクセスできます
「N」=> EBX + 9 byte ;(/bin/dash が9文字のため)
「AAAA」 => EBX +10 byte
「BBBB」 => EBX +14 byte
そしてシステムコール時は別のレジスタに各パーツを格納しなければならないので、
ECXにEBX+10(=>AAAA)をEDXにEBX+14(=>BBBB=NULL)
EXECのシステム関数番号11は16進数で0x0Bであるため、EAXレジスタにこれを指定してシステムコールします。
作成できたシェルコードの一部抜粋したものがこちらです。
![%e3%82%b7%e3%82%a7%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89%e6%8a%9c%e7%b2%8b%ef%bc%91](/assets/rtc/prod-rtc-blog/wp-content/uploads/2016/11/18120515/9eb07ea54a95377473cfad850289d97e.png)
実行すると以下のようにコマンドシェルをroot権限で取得できます。
![%e3%82%b7%e3%82%a7%e3%83%ab%e3%82%b3%e3%83%bc%e3%83%89%e6%8a%9c%e7%b2%8b2](/assets/rtc/prod-rtc-blog/wp-content/uploads/2016/11/18120557/cc2c6ccfeebff2c4861ca5893eed111e.png)
注意点は、今回はユーザ権限を明示的にrootに指定し、シェルコードもroot権限で実行しているということです。
通常、攻撃者がroot権限でシェルコードを実行できることは多くありません。
root権限のパスワード管理は誰もが徹底し、容易に取得できるものではないからです。よって本来は、前段階でソフトウェア脆弱性悪用するなど、なんらかの方法で権限昇格する必要があるのです。
※本コードを転用して何らかプログラムを作成・実行した場合の諸環境での動作、及び実行時の安全性については、一切の保証はいたしかねます。
シェルコード弁当のおさらい
最後に、前回も含めたおさらいをします。
■シェルコードもお弁当同様に区分に分けて
必要な「肉」「野菜」「ご飯」を詰める
■Linuxではシステムコールは
番号によって動きが違う(覚えてますか? 1番、4番と11番と203番の違い)
■シェルコードをリモートから意図せず実行するには、脆弱性を悪用するコードが必要!
権限昇格も脆弱性を悪用して行う!
Appendix : シェルコードは検知されにくいように攻撃が成功しやすいようにバイト長が短いほうがよい!
そしてシェルコードの書き方はWindowsなのかLinuxなのかMac OSXなのか32ビットなのか64bitなのかでも異なります。別のOSでのお弁当はまた別途機会があれば記載とさせてください。
以上です。
ご一読ありがとうございました!