ネットワークの振る舞い検知でセキュリティ強化を実現しよう - 脅威検知されたホストの自動隔離 -

# はじめに
:::note info
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2023 の 14日目として投稿しています。
:::

- 2017年版: https://qiita.com/advent-calendar/2017/cisco
- 2018年版: https://qiita.com/advent-calendar/2018/cisco
- 2019年版: https://qiita.com/advent-calendar/2019/cisco
- 2020年版: https://qiita.com/advent-calendar/2020/cisco
- 2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
- 2021年版: https://qiita.com/advent-calendar/2021/cisco
- 2021年版(2枚目): https://qiita.com/advent-calendar/2021/cisco2
- 2022年版(1,2): https://qiita.com/advent-calendar/2022/cisco
- 2023年版: https://qiita.com/advent-calendar/2023/cisco <=== ここ

# この記事で書くこと
ネットワーク上に流れるデータから振る舞いを分析して脅威を検知するシスコのNDRソリューションである、[Secure Network Analytics](https://www.cisco.com/c/ja_jp/products/collateral/security/stealthwatch/white-paper-c11-740605.html)をお客様にご紹介した際に、異常が検知されたホストに対して、自動的に隔離することが可能か？　という質問を多くいただきます。そのため本記事では、どのような対応が可能かいくつかの方法をご紹介し、特にどのお客様にも広くご提案可能なAPIを活用する例についてサンプルをご紹介したいと思います。

# Secure Network Analytics とは
[Secure Network Analytics](https://www.cisco.com/c/ja_jp/products/collateral/security/stealthwatch/white-paper-c11-740605.html) は、シスコシステムズの[NDR（Network Detection and Response）](https://www.gartner.com/reviews/market/network-detection-and-respons)製品です。Secure Network Analyticsでは、traffic metadata　として、ネットワーク機器から吐き出される Netflow を収集し、機械学習によりネットワーク内のエンドポイントのふるまいを分析することで、疑わしい振る舞いをするホストや、侵入したマルウェアなどによる偵察行為、エクスプロイト攻撃、C＆Cサーバー通信による遠隔操作、ラテラルムーブメント、機密データのダウンロード、外部への機密データの持ち出し、DDoS攻撃などを検知し、対応することができます。

実パケットではなく、Netflowを利用するため、非常に軽いデータでネットワークにどのような通信が発生しているか可視化することができます。帯域を気にすることなくネットワーク内のあらゆるポイントで情報を収集することができるため、north-southだけではなく、east-westの通信（L2の折り返し通信など）も可視化、分析することができ、近年話題になることが多い、ランサムウェア攻撃に特徴的なラテラルムーブメントのような挙動も検知することが可能となります。

また、エンドポイントの振る舞い検知ソリューションである[EDR(Endpint Detection and Response)製品](https://www.gartner.com/reviews/market/endpoint-detection-and-response-solutions)とは異なりエージェントレスでネットワーク機器側の対応のみで脅威対策が可能で、エンドポイントの機種やOS、アプリケーションとの親和性等の制限でEDRのエージェントをインストールできず、EDRでの脅威対策が難しい環境にも適応することができます。

# 脅威検知されたホストを自動隔離する対応方法
脅威検知されたホストを自動隔離する対応方法として以下の対応が考えられます。

### 1. Ciscoの認証サーバである[ISE(Identity Service Engine)](https://www.cisco.com/c/ja_jp/products/collateral/security/identity-services-engine/data_sheet_c78-656174.html?ccid=cc001033&dtid=odicdc000016&oid=dstsc025999)と連携する方法

Secure Network AnalyticsとISEを連携させ、Secure Network Analyticsが脅威検知したエンドポイントに対してISEがエンドポイントが接続されているスイッチのインターフェースのshutdownやVLAN変更を行い隔離する方法です。
利用には前提条件として、お客様環境でISEが認証サーバとして既に導入されている、または新規に導入いただく必要があります。

本記事では深く触れませんが、設定例は下記をご参考ください。

[Secure Network Analytics v7.4.2 ISE および ISE-PIC コンフィギュレーションガイド](https://www.cisco.com/c/dam/global/ja_jp/td/docs/security/stealthwatch/ISE/7_4_2_ISE_Configuration_Guide_DV_1_0.pdf)
[Stealthwatch: 7.1.1 と ISE 2.6 のインテグレーション](https://community.cisco.com/t5/tkb-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88/stealthwatch-7-1-1-%E3%81%A8-ise-2-6-%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/ta-p/4006786) **バージョンが古いのでご参考まで*


### 2. 製品組み込みの Mitigation 機能を使用する方法
[STEALTHWATCH MITIGATION FEATURE](https://www.cisco.com/c/dam/en/us/td/docs/security/stealthwatch/management_console/smc_users_guide/SW_Desktop_Client_User_Guide_DV_1_0.pdf)
![スクリーンショット 2023-12-10 3.02.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217351/f2631c5c-b102-6985-e0ff-4a661ab9c047.png)

Web GUIからではなく、デスクトップクライアントソフトウェアから設定が可能な機能です。以前からある機能ですが、最新の7.4.2のバージョンからはMITIGATIONの対応デバイスとしてシスコ機器用のテンプレートがなくなりました。。現在は下記のテンプレートのみとなり機能開発としては縮小傾向にあることが要注意点です。

- Custom
- Radware DefensePro

Customをご利用の際は、登録用のテンプレートを自身で作成して使用する必要があり、初心者には少々ハードルが高いものとなっております。[ドキュメント](https://www.cisco.com/c/dam/en/us/td/docs/security/stealthwatch/management_console/smc_users_guide/SW_Desktop_Client_User_Guide_DV_1_0.pdf)に記載もありますが、ご利用の際はシスコの顧客担当にご相談の上で使用いただくことが望ましいです:bow_tone1:

:::note warn
Choose the Custom option if you plan to use an expect script to customize
mitigation actions. However, we recommend that you contact Cisco Customer
Support for assistance before attempting to use expect scripts.
:::


### 3. APIを活用する方法
本題の、Secure Network AnalyticsのAPIを使って実現する方法です。
追加の製品を導入する必要もなく、製品の機能制限に縛られることもなく、お客様の要望に柔軟にお応えすることができることがAPIを利用するメリットですね:point_up:

Secure Network AnalyticsのAPIの利用方法は[こちらの記事](https://community.cisco.com/t5/tkb-セキュリティ-ドキュメント/stealthwatch-rest-api-利用方法/ta-p/4441810)がとてもわかりやすいです。
どのようなAPIを持っているかは、[DevNetのページ](https://developer.cisco.com/docs/stealthwatch/enterprise/#!reporting-api-version-1)から確認することができますし、稼働中のSecure Network Analyticsをお持ちであれば、Webブラウザからも確認が可能です。![スクリーンショット 2023-12-10 3.21.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217351/85663947-2a84-a9f0-6354-67c76c2282f4.png)


例えば、下記のAPIを利用すると、脅威活動の疑いのあるアラームを出しているトップアラーミングホストの情報を取得することができます。
![スクリーンショット 2023-12-09 13.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217351/9a82e132-cb4c-9cda-bd97-f651affb021d.png)

Secure Network AnalyticsのWeb管理インターフェースで表示で言えば、下記で表示されているホスト情報が取得できることになります。

![スクリーンショット 2023-12-13 10.40.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217351/527b954a-9a1d-7c25-2cc3-205c5b5302be.png)



Secure Network Analyticsでは、そのホストが出しているフローの情報から、どのような種類の脅威活動をしている可能性があるか、11のセキュリティカテゴリに分類してアラートを出しますが、このセキュリティカテゴリもTypeIDとしてAPIで取得可能です。

``` 
  32 - High Concern Index
  15 - High Target Index
  45 - Data Exfiltration
  46 - Command & Control
  47 - Policy Violation
  51 - Recon
  52 - Data Hoarding
  53 - High DDoS Target Index
  54 - High DDoS Source Index
  56 - Exploitation
  57 - Anomaly
```
![スクリーンショット 2023-12-13 12.11.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217351/1afbe7d1-c7a6-94d3-5693-2832e4b658a5.png)


では実際に、このAPIを使って情報を取ってみます。下記のような結果が返ってきます。
該当ホストが、セキュリティカテゴリのTypeID=51=”Recon"(偵察）とTypeID=32=”High Concern Index(高懸念）”のカテゴリに分類される疑いのある脅威活動を行っていることがわかります。

```
{
    "data": {
        "data": [
            {
                "hostGroupIds": [
                    1,
                    65534
                ],
                "ipAddress": "10.x.x.x",
                "sourceCategoryEvents": [
                    {
                        "alwaysBadCount": 0,
                        "severity": 2.165832056,
                        "typeId": 51　　　　　
                    },
                    {
                        "alwaysBadCount": 0,
                        "severity": 2.165832056,
                        "typeId": 32
                    }
                ],
                "sourceSecurityEvents": [],
                "targetCategoryEvents": [],
                "targetSecurityEvents": []
            }
        ],
        "header": {
            "endTime": "2023-12-12T16:08:57Z",
            "startTime": "2023-12-11T16:08:57Z"
        }
    }
}
```

では例として、このAPIを使って、脅威活動の疑いのあるアラームを出しているトップアラーミングホストを自動的に隔離することを考えてみます。

下記のような簡単な動作フローを想定しました。

1. Secure Network Analyticsので定期的にトップアラーミングホストを取得
2. ランサムウェアの感染端末の初期の挙動に見られる、”偵察（Recon)”の振る舞いが見られるホストについて、L3GWとなる機器にsshし、該当ホスト宛の通信が破棄されるようにnull0ルートを書き込む




本来は、このホストが接続されているスイッチのポートを特定し、そのポートを遮断したいところですが、その場合、ホストが接続されているポートを特定するために別途、認証サーバやネットワーク監視装置のAPI等と連携する必要があるため、本記事では、一次対処として少なくとも該当ホストが他のセグメントに感染活動を広げないように自動隔離する、という観点で考えてみました。

実際に動作確認したPyhtonスクリプトはこちらです。
Secure Network AnalyticsのPyhtonスクリプトは[GitHub](https://github.com/CiscoDevNet/stealthwatch-enterprise-sample-scripts/blob/master/python/get_security_events.py)にサンプルが豊富にありますので、こちらを参考に書きました。L3GWへのsshにはnetmikoモジュールを使ってみました。

##### 実行環境
- Secure Network Analysis v7.4.2
- Catalyst 9300スイッチ　（L3GW用）
- Python 3.9.6 on Mac PC

##### サンプルスクリプト
``` python:sna_mitigation.py
import requests
import json
import netmiko

try:
    requests.packages.urllib3.disable_warnings()
except:
    pass

# Enter all authentication info
# SNAのダッシュボードへのログインクレデンシャルをセットします。
SMC_USER = "admin"
SMC_PASSWORD = "C!sco123"
SMC_HOST = "10.70.170.85"
SMC_TENANT_ID = "301"

# null0ルートを書き込むL3 GWスイッチのssh用クレデンシャルをセットします。
L3GW_HOST = "10.70.170.120"
L3GW_USER = "admin"
L3GW_PASS = "cisco"
L3GW_SECRET = "cisco"
L3GW_TYPE = "cisco_ios"

# Stealthwatch Constants
XSRF_HEADER_NAME = 'X-XSRF-TOKEN'

# Set the URL for SMC login
url = "https://" + SMC_HOST + "/token/v2/authenticate"

# Let's create the login request data
login_request_data = {
    "username": SMC_USER,
    "password": SMC_PASSWORD
}

# Initialize the Requests session
api_session = requests.Session()

# Perform the POST request to login
response = api_session.request("POST", url, verify=False, data=login_request_data)

# If the login was successful
if(response.status_code == 200):

# Set XSRF token for future requests
    for cookie in response.cookies:
        if cookie.name == 'XSRF-TOKEN':
            api_session.headers.update({XSRF_HEADER_NAME: cookie.value})
            break

    # Get the list of tenants (domains) from the SMC
    url = 'https://' + SMC_HOST + '/sw-reporting/v1/tenants/' + SMC_TENANT_ID + '/internalHosts/alarms/topHosts'
    response = api_session.request("GET", url, verify=False)
    r=response.content

    # If successfully able to get list of tenants (domains)
    if (response.status_code == 200):

       # トップアラーミングホストの情報を取得
       tophost = json.loads(response.content)["data"]["data"][0]["ipAddress"]
       j = 0
       # トップアラーミングホストのアラームのセキュリティカテゴリを取得
       while j<2:
             typeID = json.loads(response.content)["data"]["data"][0]["sourceCategoryEvents"][j]["typeId"]
             if typeID == 51:
               print('!!!!!'+ tophost +'のネットワーク内での偵察行為を検知しました!!!!!')
               # L3GWへsshし、null0ルートを書き込む
               session = netmiko.ConnectHandler(device_type=L3GW_TYPE, host=L3GW_HOST,username=L3GW_USER, password=L3GW_PASS,secret=L3GW_SECRET)
               session.enable()
               print('!!!!!! 隔離を実行します !!!!!!')
               route_command = 'ip route '+tophost+' 255.255.255.255 null0'
               print('隔離実行前の"show ip route"\n')
               print(session.send_command('show ip route') + '\n')
               do_mitigation = [route_command]
               session.send_config_set(do_mitigation)
               print('隔離実行後の"show ip route"\n')
               print(session.send_command('show ip route'))
               session.disconnect()
               print('!!!!!! 隔離完了 !!!!!!')
             j=j+1
 
 # If unable to fetch list of tenants (domains)
    else:
        print("An error has ocurred, while fetching tenants (domains), with the following code {}".format(response.status_code))

    uri = 'https://' + SMC_HOST + '/token'
    response = api_session.delete(uri, timeout=30, verify=False)
    api_session.headers.update({XSRF_HEADER_NAME: None})

# If the login was unsuccessful
else:
        print("An error has ocurred, while logging in, with the following code {}".format(response.status_code))



```


##### 実行結果
```
% python3 sna_mitigation.py
!!!!!10.141.85.87のネットワーク内での偵察行為を検知しました!!!!!
!!!!!! 隔離を実行します !!!!!!
隔離実行前の"show ip route"

Extended Host Mode is enabled
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override, p - overrides from PfR

Gateway of last resort is 10.70.170.65 to network 0.0.0.0

S*    0.0.0.0/0 [1/0] via 10.70.170.65, Vlan1
      10.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        10.70.170.64/26 is directly connected, Vlan1
L        10.70.170.120/32 is directly connected, Vlan1

隔離実行後の"show ip route"

Extended Host Mode is enabled
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override, p - overrides from PfR

Gateway of last resort is 10.70.170.65 to network 0.0.0.0

S*    0.0.0.0/0 [1/0] via 10.70.170.65, Vlan1
      10.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
C        10.70.170.64/26 is directly connected, Vlan1
L        10.70.170.120/32 is directly connected, Vlan1
S        10.141.85.87/32 is directly connected, Null0
!!!!!! 隔離完了 !!!!!!
```

# 終わりに
APIを使えば、さまざまなセキュリティインシデント情報を取得できますので、要件に沿ったトリガーでアクションを実行することが可能になります。今回ご紹介した例はあくまでサンプルですが、ご参考になれば幸いです。また、本記事では紹介できなかったですが、セキュリティ製品を複数お持ちの方には、[Cisco XDR](https://www.cisco.com/c/ja_jp/products/security/what-is-xdr.html)を利用して、Secure Network Analyticsなど単一の製品のログだけではなく、複数製品のインシデントログから相関分析を行い自動ワークフローを組むことも可能となります。次回の記事でぜひご紹介したいと思います。
最後まで読んでいただきありがとうございました。

# 免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。