2023年8月から9月にかけてSansanでの就業型インターンシップに参加した櫛引淳之介(ブログ)です。 普段はIPv6インターネットにおけるIoT機器のセキュリティをテーマに大学院で研究を行っています。
今回のインターンシップでは、情報セキュリティ部CSIRTグループの一員として、自宅ルータ脆弱性検知システムの改修に取り組みました。
背景:自宅ルータの不備によるPCの外部公開とその対策
Sansanではリモートワークを取り入れており、業務用PCが従業員の自宅のネットワーク環境でも使用されています。 そのため、自宅のネットワーク環境に不備がある場合、PCがインターネット側から攻撃可能な状態になってしまう場合があります。
この問題に対応するため、CSIRTグループでは、ルータのポート開放を動的に検知し、CSIRTに通知するシステムを構築、運用しています。 業務用PCがインターネットから不審な通信を受け取った際にシステムが動作し、ネットワーク設定に不備があれば検知してCSIRTへの通知を行います。
既存システムの詳細については、下記をご覧ください。
システムのおおまかな流れをざっくりと伝えると以下の通りです。
自宅ルータの脆弱性検知システムの開発 - Sansan Tech Blog
1. 従業員が利用している端末のログから、ネットワークの設定に不備がありそうなログを収集する
2. 疑いがある端末が利用しているルータに対して、ポートが開放されているか確認する
3. ポートが開放されていた場合は CSIRT に連絡する
既存システムには以下のような課題があり、今回のインターンでは、課題の分析と対策の提案、実装に取り組みました。次章以降では、各課題の詳細と対策について紹介します。
- IPv6に対応していない
- Lambdaがタイムアウトし、スキャンを完遂できないことがある
- 不審な通信を受けたアドレス/ポートがスキャンの対象とならないことがある
- PCの状態が変化すると検知に失敗する
課題と対策の詳細
検知システムのIPv6対応
IPv6は、IPv4アドレス枯渇問題の解決のために導入が進められているネットワークプロトコルです。 2023年9月時点で、IPv6の普及率は日本のインターネットユーザの約半分に迫っています*1。
IPv6とIPv4の大きな違いの一つに、グローバルアドレスの割り当て方法があります。 典型的な家庭向けIPv4環境では、ホームゲートウェイに位置するルータに全世界で一意なグローバルアドレスが一つ割り当てられ、その配下で使用されるPCなどの機器にはネットワーク内で一意なプライベートアドレスが割り当てられます。 このような割り当て方の目的は、不足するIPv4アドレスをなるべく効率的に使用することです。
プライベートアドレスしか割り当てられていない機器では、インターネットで直接通信することはできません。 そのかわりに、グローバルアドレスを持つルータが通信を肩代わりすることでインターネットにアクセスします。このときNAT (Network Adress Translation) と呼ばれるアドレス変換の仕組みが使用されます。
NATには、プライベートアドレスしか持たない機器との通信をインターネット側から開始できないという副作用があります。 この副作用には、インターネットからPCへの攻撃が難しくなるというセキュリティ上のメリットがあります。
一方の、IPv6環境では、アドレスの数を節約する必要がありません。そのため、全てのデバイスにグローバルアドレスが割り当てられ、NATを使用しない構成が一般的です。 NATがない分、ルータにおいてファイアウォールを実装することで、IPv4環境と同等のセキュリティレベルを確保することが求められます。ファイアウォールの実装や設定に不備があると、業務用PCがインターネットに公開された状態になってしまいます。実際に、少し古い実装(IPv6パススルー方式)のルータでは、ファイアウォールが実装されないことが知られています。
既存システムでは、PCからEDRのサーバへログを送信する際に使用されたIPv4アドレス(すなわち、ルータのアドレス)をスキャンの対象としています。 ログ送信に使われるプロトコルはIPv4のみであり、現在の手法ではIPv6で不審な通信が来てもスキャンの対象となりません。 さらに、nmapでのスキャンに使用しているAWS LambdaもIPv6に通信に対応していません。
このような背景から、システム全体のIPv6対応に取り組みました。 具体的には、ログ検索時のクエリとTinesでの前処理の修正、AWS LambdaからAWS Fargateへの移行を行いました。
AWS LambdaからAWS Fargateへの移行
IPv6対応とタイムアウト回避のため、スキャンの基盤については、AWS LambdaからAWS Fargateに変更しました。
Lambdaで使用していたコンテナとPythonのコードをFargate向けに書き換え、ECSタスクとして実行できるようにしました。 TerraformでVPCサブネットやECSクラスタなどの基盤部分を作成しておき、TinesでAWS APIのRunTask*2を叩くことで、任意のタイミングでFargateタスクを起動できるようにしました。 スキャン対象のIPアドレスやポート番号などの必要情報については、環境変数から読み込むようになっており、RunTask呼び出し時にTinesから渡すことができます。
Fargateへの移行により、スキャンのプロセスがタイムアウトしてしまう問題も副次的に解決しました。 Lambdaの実行時間には15分の上限があるため、既存システムでは、スキャンが完了せずに処理が止まってしまう可能性があります。 Fargateには実行時間の制限がないため、タイムアウトを心配することなくスキャンを実施できるようになりました。
nmapのオプション変更によるスキャン漏れの軽減
既存システムでは、以下のコマンドにより従業員PCに対して高速バージョンスキャンを行っていました。
$ nmap [Target IP Address] -sV -F
これに2つのオプションを追加し、スキャン漏れを軽減しました。 以下では、オプションの詳細について説明します。
$ nmap [Target IP Address] -sV -F -Pn -p [Target Port]
-Pn
: pingスキャンを行わない
nmapは、ポートスキャンの前にpingスキャンを行い、ホストの存在確認ができなければポートスキャンを行わずに処理を終了するよう設計されています*3。
IPv4においてはルータがpingに応答するため、これまではさほど大きな問題にならなかったと考えられます。 しかし、IPv6ではPCを直接スキャンすることになります。 Windows PCはデフォルト設定でpingに応答しないようになっているため、IPv6対応に伴ってポートが開放されていても見落とすケースが発生する可能性があります。
この問題は、pingスキャンを行わないようにする-Pn
オプションを使用することによって解決しました。
-p
: 外部から通信を受けたポートをピンポイントでスキャンする
外部からの通信を受けたポートがスキャン対象ポートとならない場合の検知漏れにも対応しました。
既存システムでは、使用頻度の高い一部のポートに絞ってスキャンを行う高速スキャン(-F
オプション)が採用されていました。主要なポートはこの方法でも検出可能です。
しかし、実際に検出したい事象としては、開発中のプログラムの動作確認のため一時的に開放したポートに外部からアクセスされる状況などが考えられます。そのため、外部からアクセスされたポートがスキャン対象とならないことも十分にあり得ます。
そこで、外部からアクセスを受けたポートの情報をログから取得し、スキャン実施用Fargateタスクに渡すことでピンポイントでスキャンを行うよう変更を加えました。
PCの状態変化による検知漏れの防止
既存システムでは、ログ検索を1日に1回行っており、直近24時間に発生した業務用PCへの不審なアクセスログを元にスキャンを実行します。 この方法では、時間の経過によってPCの状態に変化が生じてしまい、検知漏れが生じる場合があります。
具体的には、PCの電源が切られている、ポートを開放していたアプリケーションが停止している、IPアドレスが変化している、といった原因により、 スキャンを実施する頃には、ログ発生時に記録されたアドレスとポート番号でサービスが公開されていない、という状況が起こり得ます。
特に、IPv6アドレスは頻繁に変化することが予想されます。 Mac OSなどのPCでは、セキュリティ上の理由により、使用しているIPv6アドレスの下位64bit(インターフェース識別子)を24時間などの短い周期で変更する仕様となっています*4。
そこで、ログ検索の周期を従来の24時間から1時間に短縮することで対応しました。 本システムの処理はログ検索が実行のトリガーとなるため、この変更によって、PCが通信を受けてから1時間以内にスキャンが実施されるようになります。 タイミングによってはスキャンが実施される前にPCの状態が変化してしまう可能性もありますが、今回は許容範囲内と考えました。
学んだこと
実運用上のさまざまな要件を考慮しながら判断していくことの重要さを学びました。
「PCの状態変化による検知漏れの防止」に取り組んだ当初には、スキャンの実施時にPCの状態を取得し、より正確に検知できるようにすることを提案していました。 Sansanで採用しているEDRにはPCにリモート接続する機能があり、従業員PCを直接操作することができます。 これを用いれば、現在割り当てられているIPv6アドレスなどの情報を取得することができます。
実際にメンターの方にこの方法を提案したところ、Tinesに必要以上の権限を与えなければならないというデメリットがあることをご指摘いただきました。 リモート接続機能では従業員PCでできることは概ね全てできてしまうので、万が一トークンの流出などがあった場合には極めて甚大な被害が発生する恐れがあります。 加えて、強引な実装になることが予想され、メンテナンスコストの増大も懸念されます。
また、このスキャンシステムはインターネットからアクセスを受けてしまった後に被害を最小化する目的で運用しています。 セキュリティ保護のためであっても、調査範囲は必要最低限に抑えることが望まれます。
これらのデメリットを検知性能の向上によるメリットと天秤にかけた結果、ログ検索周期の短縮で対応することに決めました。
研究でもIoT機器を対象とした実験を設計することがありますが、多くの場合、実験を実施するのは一度限りで、手順も正確性を優先して組み立てます。 一方、実際のセキュリティ運用では、厳密であることだけを追求すればよいとは限りません。 今回のインターンでは、複雑なセキュリティ上の課題に取り組むことの難しさと面白さを実際に考えながら学ぶことができました。
終わりに
CSIRTグループでのインターンシップに参加し、ルータの脆弱性検知システムの性能改善に取り組みました。 具体的には、IPv6への対応、スキャンのタイムアウト防止、スキャン方法の改良、PCの状態変化への対策を行いました。 取り組みを通じて、実際のセキュリティ運用の難しさと面白さ、課題への向き合い方を学びました。
最後になりますが、インターン期間中にはCSIRTグループをはじめとする多くのSansanメンバーの方とお話させていただき、手厚くサポートしていただきました。貴重な経験ができる濃密なインターンシップでした。関係者の皆様、本当にありがとうございました。
*1:IPv6 – Google https://www.google.com/intl/ja/ipv6/statistics.html
*2:RunTask - Amazon Elastic Container Service https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RunTask.html
*3:ホストの発見 | Nmap リファレンスガイド (Man Page) https://nmap.org/man/ja/man-host-discovery.html
*4:IPv6のセキュリティ - Apple サポート (日本) https://support.apple.com/ja-jp/guide/security/seccb625dcd9/web