포스트

Cisco ISE CVE-2026-76460 패치 전후 운영 검증: 노출면·자산 매핑·HA·탐지

인증 우회류 취약점은 패치 자체보다 노출면 통제·정확한 자산 매핑·HA 절차·로그 기반 탐지가 실패를 줄입니다.

Cisco ISE CVE-2026-76460 패치 전후 운영 검증: 노출면·자산 매핑·HA·탐지

CVE-2026-76460을 패치만으로 끝내면 안 되는 이유

CVE-2026-76460은 Cisco ISE / ISE-PIC의 API endpoint 인증 통제 미흡으로 인해, 원격 비인증 공격자가 crafted request를 보내 web-based management interface 인증을 우회할 수 있는 취약점입니다. Cisco는 CVSS 10.0으로 분류했고, workaround는 없다고 못 박았습니다.1

이 유형은 “관리 UI가 뚫린다”에서 끝나지 않습니다. ISE의 관리 plane은 정책 엔진, 외부 identity source(AD/LDAP/RSA 등), 인증서/키 material, pxGrid 신뢰, NAD 정의, TACACS+ command set 같은 운영 핵심을 다룹니다. 우회가 성립하면 단기간에 아래가 같이 터질 수 있습니다.

  • NAD 쪽 인증·인가 정책 변조(802.1X, MAB, VPN, TACACS+)
  • 새 Admin 계정 생성 또는 기존 계정 권한 상승
  • 외부 identity source 설정 변경(AD join/탈퇴 포함)
  • 인증서/Trust Store 변조(포털, EAP chain, pxGrid client cert 신뢰)
  • 로그/감사 설정 비활성화 후 흔적 지우기

Cisco PSIRT는 “active exploitation을 인지했다”고도 적었습니다.1 캐나다 Cyber Centre 경보(AL26-021)도 같은 맥락에서 “unauthenticated attacker가 administrative access를 얻을 수 있다”는 표현으로 위험을 상향해 전달합니다.2

또한 CISA는 2026-09-16에 KEV에 CVE-2026-76460을 추가했다는 별도 공지를 냈습니다.3 KEV의 “due date”는 외부에서 재인용되는 값이라 원문 feed를 보는 게 가장 좋은데, 이 글을 쓰는 환경에서는 CISA의 공식 JSON/CSV feed가 403으로 차단되어 확인이 어려웠습니다. 다만 VulDB는 KEV에 2026-09-16 추가, due date 2026-09-19로 정리하고 있습니다.4

오늘이 2026-09-19 KST라면, 일정 압박이 ‘긴급 패치 → 즉시 장애’로 이어질 가능성이 큽니다. 그래서 이 글은 “패치를 어떻게 클릭하나”가 아니라, 패치 전후에 반드시 확인해야 할 운영 검증을 공격 표면/자산 매핑/HA/탐지까지 한 번에 묶어 정리합니다.

공격 표면을 ‘관리 UI’ 한 단어로 뭉개면 매핑이 실패합니다

Cisco advisory는 “API endpoint의 인증 통제가 불충분”하다고 했고, 결과적으로 “web-based management interface를 우회”한다고 설명합니다.1 여기서 중요한 건, ISE에서 API가 어디에 붙어 있는지, 그리고 운영 환경에서 그 API가 어떤 방식으로 노출되고 있는지를 노드/포트/경로 레벨로 분해해야 한다는 점입니다.

Admin Portal(관리 UI)의 고정 포트: 80/443

Cisco ISE Administrator Guide(Release 3.1)는 administration portal이 HTTP 80, HTTPS 443을 사용하며 변경할 수 없다고 명시합니다. 또한 end-user portal에 이 포트를 쓰지 못하게 하는 이유를 “administration portal risk 감소”로 설명합니다.5

이 문장 하나가 운영 체크리스트로 변환되면 다음이 됩니다.

  • 외부/사용자 트래픽이 닿는 VIP/LB/WAF/Reverse Proxy가 443으로 ISE Admin Portal을 프록시하고 있지 않은지 확인
  • “어차피 443은 열려 있으니…”라는 이유로 Admin 접근 제어를 네트워크 레벨에서 빼먹지 않았는지 확인
  • end-user portal(Guest, BYOD, posture redirect)이 우회적으로 443과 섞이도록 구성되어 있지 않은지 확인

즉, “관리 UI는 내부망이라 안전”이라는 문장 대신, “어떤 네트워크 세그먼트에서 443/TCP가 닿는가”를 자산 표에 넣어야 합니다.

API Gateway가 공격 표면을 넓히는 방식: ‘단일 entry point’의 역효과

ISE 3.1부터 MnT API / ERS API / Open API가 API Gateway로 라우팅된다고 가이드에 적혀 있습니다.5 DevNet 문서에는 API Gateway 노드 설정을 GUI에서 관리하고, /admin/API/apiGateway/get, /admin/API/apiGateway/update 같은 endpoint가 예시로 나옵니다.6

여기서 운영 리스크는 두 가지입니다.

1) 노출면 집중: 여러 API가 “한 entry point”로 모이면, 그 entry point가 깨질 때 피해 반경도 같이 커집니다. 2) 노드 혼선: 분산 배포에서 API Gateway가 어디에 enable되어 있는지 모르면, “취약 노드” 매핑이 틀어집니다.

CVE-2026-76460이 정확히 어떤 내부 endpoint에서 발생했는지 Cisco advisory는 공개하지 않았습니다. 그래서 이 글도 PoC 추정이나 endpoint guessing을 하지 않습니다. 대신, 공격자 관점에서 “API gateway/관리 UI로 들어오는 HTTP(S) 요청”이 결국 표적이 된다는 점을 전제로, 노출면을 최소화하고 로그로 역추적 가능하게 만드는 것을 목표로 둡니다.

포트 레벨 노출면: 443만 보면 끝나는 게 아닙니다

ISE Installation Guide의 Ports Reference는 Administration node에서 ERS REST API가 9060에서도 동작할 수 있으나, 향후 release에서 9060이 지원되지 않을 수 있어 443만 쓰라고 권고합니다.7

또한 같은 Ports Reference는 “SAML admin login을 위해 PSN의 8443이 admin이 접근하는 디바이스에서 reachable해야 한다”는 노트를 둡니다.7 이건 운영에서 흔한 실수로 이어집니다.

  • “SAML admin login이 안 된다” → 방화벽에서 8443을 광범위하게 오픈 → 사실상 또 하나의 관리 관련 표면이 생김

정리하면, CVE-2026-76460 대응에서 노출면 점검은 다음 3개 묶음으로 봐야 합니다.

  • (A) Admin Portal: 80/443 (실질적으로는 443)
  • (B) API Gateway/관리 API: 443 경로(/admin/... 계열) + 배포에 따라 9060/9070/9443 같은 내부 라우팅 포트 존재5
  • (C) SAML admin login/PSN 연계: 8443 reachable 요구 조건이 방화벽 정책을 망가뜨릴 수 있음7

자산에서 “취약 여부”를 버전·패치·노드 단위로 정확히 매핑하는 법

Cisco advisory는 “구성에 관계없이 영향을 받는다”고 했습니다.1 이 문장을 운영팀이 흔히 잘못 번역하면 “어차피 전부 취약이니 빨리 업그레이드”가 됩니다. 하지만 실제로 해야 하는 건 반대입니다.

  • 전부 취약이라고 가정하되, 자산 대장에는 “어느 노드가 어떤 fixed release에 도달했는지”를 남겨야 합니다.
  • 분산 배포에서 patch level 불일치가 남으면, 공격자는 패치가 덜 된 노드를 골라 들어옵니다.

Cisco가 제시한 Fixed Releases 매트릭스를 ‘정규화된 규칙’으로 바꾸기

Cisco advisory의 fixed release 표는 단순하고 명확합니다.1

  • 3.1 → 3.1 Patch 12
  • 3.2 → 3.2 Patch 11
  • 3.3 → 3.3 Patch 12
  • 3.4 → 3.4 Patch 7
  • 3.5 → 3.5 Patch 4

캐나다 Cyber Centre(AL26-021)도 동일한 fixed release를 표로 재확인해 줍니다.2

이 표를 그대로 들고 다니면 현장에서 부딪히는 문제가 있습니다.

  • ISE는 “release(3.4)”와 “cumulative patch(7)”가 분리되어 있고, 표기 방식이 GUI/CLI/다운로드 포털/내부 문서마다 약간씩 다릅니다.
  • 특히 HA 환경에서는 “Primary PAN GUI에서 보이는 patch level”과 “각 노드의 실제 patch installed”가 어긋날 때가 있습니다(동기화 지연, 업그레이드 중단, 노드 격리 등).

그래서 나는 fixed release 매트릭스를 아래처럼 정규화 규칙으로 변환해 자산 검증에 씁니다.

  • major.minor(3.4) 단위로 그룹핑
  • 각 그룹별 min_fixed_patch를 숫자로 저장
  • 노드별 current_patch를 숫자로 파싱
  • current_patch < min_fixed_patch면 취약

이 규칙은 SIEM/CMDB/스프레드시트 어디에든 옮기기 쉽습니다.

노드별 버전/패치 수집: API보다 ‘SSH 수집’을 먼저 잡는 이유

패치 대응 시점에는 “관리 plane이 신뢰 가능한가” 자체가 흔들립니다. 인증 우회 취약점 대응에서는 특히 그렇습니다. 따라서 나는 자동화가 필요해도, 먼저 read-only SSH 수집 경로를 확보하는 쪽을 선호합니다.

  • API는 API Gateway에 매달려 있고(노출면 집중), 인증 체계가 단일 장애점이 될 수 있음5
  • SSH는 네트워크 레벨에서 강하게 제한하기 쉬움(관리 점프호스트, PAM, MFA, source IP 제한)

아래는 현실적인 수집 패턴입니다.

1) CMDB/가상화 플랫폼/방화벽 오브젝트에서 ISE 노드 IP/hostname 목록을 뽑음 2) jump host에서 각 노드에 SSH로 접속해 버전 문자열을 수집 3) 결과를 CSV로 남기고, fixed release 규칙과 join

실행 가능한 예시: ISE 노드 버전 수집 + 취약 여부 판정 (Python)

  • Python 3.11+
  • 의존성: paramiko, pydantic(선택), rich(선택)

설치:

1
2
3
python3 -m venv .venv
source .venv/bin/activate
pip install paramiko

nodes.txt (호스트 목록):

1
2
3
4
ise-pan-1.example.local
ise-pan-2.example.local
ise-psn-1.example.local
ise-psn-2.example.local

collect_ise_version.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import re
import sys
import json
import socket
from dataclasses import dataclass
from pathlib import Path

import paramiko

FIXED = {
    "3.1": 12,
    "3.2": 11,
    "3.3": 12,
    "3.4": 7,
    "3.5": 4,
}

# 환경마다 show version 출력이 달라질 수 있어서
# (1) release 3.x.y 형태와 (2) Patch N 형태를 둘 다 잡도록 만든다.
RE_RELEASE = re.compile(r"\b(3\.[1-5])\b")
RE_PATCH = re.compile(r"\bPatch\s+(\d+)\b", re.IGNORECASE)

@dataclass
class NodeResult:
    host: str
    ok_ssh: bool
    release: str | None
    patch: int | None
    vulnerable: bool | None
    raw: str | None
    error: str | None

def ssh_run(host: str, username: str, key_path: str, timeout=10) -> str:
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        client.connect(
            hostname=host,
            username=username,
            key_filename=key_path,
            timeout=timeout,
            banner_timeout=timeout,
            auth_timeout=timeout,
        )
        # ISE CLI에서 흔히 통하는 쿼리. 환경에 따라 show version 대신 다른 명령이 필요할 수 있다.
        # 운영 적용 전에는 반드시 lab/유지보수 창에서 확인한다.
        cmd = "show version"
        _, stdout, stderr = client.exec_command(cmd, timeout=timeout)
        out = stdout.read().decode("utf-8", errors="replace")
        err = stderr.read().decode("utf-8", errors="replace")
        if err.strip():
            out = out + "\n" + err
        return out
    finally:
        client.close()

def parse_release_patch(text: str):
    r = RE_RELEASE.search(text)
    p = RE_PATCH.search(text)
    release = r.group(1) if r else None
    patch = int(p.group(1)) if p else None
    return release, patch

def main():
    if len(sys.argv) != 4:
        print("Usage: collect_ise_version.py <nodes.txt> <ssh_user> <ssh_key>")
        sys.exit(2)

    nodes_file, ssh_user, ssh_key = sys.argv[1:4]
    nodes = [line.strip() for line in Path(nodes_file).read_text().splitlines() if line.strip()]

    results: list[NodeResult] = []
    for host in nodes:
        try:
            raw = ssh_run(host, ssh_user, ssh_key)
            rel, pat = parse_release_patch(raw)
            if rel in FIXED and pat is not None:
                vulnerable = pat < FIXED[rel]
            else:
                vulnerable = None

            results.append(NodeResult(
                host=host,
                ok_ssh=True,
                release=rel,
                patch=pat,
                vulnerable=vulnerable,
                raw=raw[:1000],
                error=None,
            ))
        except (socket.timeout, paramiko.SSHException, OSError) as e:
            results.append(NodeResult(
                host=host,
                ok_ssh=False,
                release=None,
                patch=None,
                vulnerable=None,
                raw=None,
                error=str(e),
            ))

    print(json.dumps([r.__dict__ for r in results], indent=2, ensure_ascii=False))

if __name__ == "__main__":
    main()

실행:

1
python collect_ise_version.py nodes.txt iseadmin ~/.ssh/id_ed25519 > ise_inventory.json

예상 출력(예시):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[
  {
    "host": "ise-pan-1.example.local",
    "ok_ssh": true,
    "release": "3.4",
    "patch": 6,
    "vulnerable": true,
    "raw": "Cisco Identity Services Engine ... Patch 6 ...",
    "error": null
  },
  {
    "host": "ise-pan-2.example.local",
    "ok_ssh": true,
    "release": "3.4",
    "patch": 7,
    "vulnerable": false,
    "raw": "Cisco Identity Services Engine ... Patch 7 ...",
    "error": null
  }
]

이 방식의 장점은 “패치 레벨이 보이는 노드”를 명확히 분리한다는 점입니다. PAN에서 패치를 올렸다고 생각해도 PSN 하나가 뒤처져 있으면 그 노드가 외부에서 reachable한 순간 전체가 위험해집니다.

수집 결과를 ‘노출면 정보’와 조인해야 의미가 생깁니다

버전/패치만으로는 우선순위를 못 정합니다. 같은 취약 노드라도,

  • 인터넷(또는 외부 협력사망)에서 443이 열려 있는 PAN
  • 내부 관리망에서만 443이 열려 있는 PSN

은 리스크가 다릅니다.

그래서 자산 테이블에 최소한 아래 컬럼을 추가합니다.

  • mgmt_reachable_from: admin 접근이 가능한 source CIDR 목록
  • public_exposed: yes/no
  • lb_or_proxy_in_front: yes/no (어떤 장비가 앞에 있는지)
  • api_gateway_enabled: yes/no/unknown (가능하면 명시)

API Gateway enable 여부는 GUI/문서 기반으로 확인할 수 있지만, 최소한 “unknown”이라도 넣어 두는 게 사고 대응에 도움이 됩니다.6

패치 전 ‘노출면’ 검증: 방화벽 규칙만 보는 체크가 왜 자주 실패하는가

인증 우회류에서 운영이 터지는 대표 케이스는 다음 순서입니다.

1) 취약점 공지 → 급하게 패치 일정 잡음 2) “외부 노출은 없을 것”이라고 가정 3) 패치 중 PAN/PSN 재기동, HA 전환, 인증서 검증 변경으로 서비스 영향 발생 4) 그런데 알고 보니 외부에서 443이 열려 있었고, 패치 전후 공격 흔적도 못 찾음

그래서 패치 전 검증은 단순히 “방화벽에 443이 있나”가 아니라, 트래픽이 실제로 어디로 들어가는지를 확인해야 합니다.

1) 443/TCP가 닿는 경로를 ‘실측’으로 확인

  • 외부망/협력사망/원격접속망/VPN 사용자망 등, 신뢰도가 낮은 세그먼트에서 ISE FQDN/VIP로 TCP connect가 되는지 확인
  • LB가 있다면, LB가 백엔드로 어떤 pool을 물고 있는지 확인

여기서 중요한 포인트는 “ISE 노드 IP”가 아니라, 실제 사용자/운영자가 접속하는 이름(FQDN, VIP) 기준으로 확인해야 한다는 점입니다.

2) Admin Portal과 Portal(Guest/BYOD) 경계를 다시 확인

Admin guide는 administration portal이 80/443을 쓰며 변경 불가라고 했습니다.5 운영에서 흔한 실수는 “Guest portal도 443이니까, 프록시에서 경로로 나눠 주면 되겠지” 같은 편법입니다.

  • 취약점이 “web-based management interface 우회”로 연결될 수 있다는 표현이 나온 시점에는, 경로 기반 라우팅 자체가 공격 표면을 늘릴 수 있습니다.
  • end-user portal은 별도 포트(예: 8443 또는 커스텀 포트)로 분리하는 게 원칙입니다.8

3) API 관련 포트/경로를 “내부 통신”으로 방치하지 않기

ISE 3.1+에서 API Gateway가 내부 노드로 라우팅하기 위해 9443/9060/9070을 사용한다는 설명이 있습니다.5 이 포트들은 “노드 간 통신”이라고 생각하기 쉽지만, 실제로는 다음 문제를 만들 수 있습니다.

  • 방화벽 팀이 “ISE끼리 통신해야 한다”는 이유로, 데이터센터 내부 전체에서 9060/9070/9443을 열어버리는 경우
  • 결과적으로 내부 침해 시 lateral movement에 유리한 표면이 됨

Ports Reference는 특히 ERS API는 443만 쓰라고 권고합니다.7 이 권고는 성능/호환성 관점도 있지만, 운영 보안 관점에서는 “불필요한 포트 노출을 줄여라”로 읽는 게 더 유용합니다.

4) SAML admin login을 위한 8443 오픈이 정책을 망치는 지점

Ports Reference의 노트(“SAML admin login을 위해 PSN 8443 reachable”)는, 실제로는 “관리자 브라우저 ↔ PSN 8443” 경로가 열려야 한다는 뜻입니다.7

여기서 절대 하면 안 되는 접근이 있습니다.

  • “안 되니까 그냥 Any-to-PSN:8443 열자”

이건 관리 plane을 외부로 확장하는 셈이라, 인증 우회/세션 하이재킹/설정 누수 같은 이슈가 겹치면 사고로 이어지기 쉽습니다. 8443은 필요한 source(관리자망)로만 제한하고, 가능하면 jump host에서 접근시키는 모델이 안전합니다.

HA(분산 배포)에서 롤링/스윙 업그레이드가 깨지는 지점

ISE 패치/업그레이드에서 가장 흔한 장애는 “패치가 실패했다”가 아니라, “패치는 됐는데 정책/연동이 미묘하게 깨졌다”입니다. 이번 건은 고위험이라 유지보수 창이 짧아질 가능성이 커서 더 위험합니다.

패치 절차가 HA 상태를 강제로 요구하는 경우

Cisco ISE 3.4의 patch upgrade 가이드는 prerequisite check 목록에 “PAN failover validation: HA for PAN is disabled”를 포함합니다.9

이 문장이 의미하는 바는 단순합니다.

  • “PAN HA 켠 채로 대충 rolling patch”는 문서 기준의 표준 경로가 아닐 수 있습니다.
  • HA 상태에서 patch wizard가 막히거나, 우회해서 진행하면 rollback 시나리오가 더 어려워질 수 있습니다.

즉, 유지보수 창이 촉박할수록 “HA를 잠깐 끄는 과정에서 운영이 불안정해지는 구간”을 의도적으로 통제해야 합니다.

업그레이드/패치 순서가 왜 중요한가

업그레이드 가이드는 노드 업그레이드 순서를 명시적으로 다룹니다(예: Secondary Administration/Primary Monitoring → PSN → Primary Administration/Secondary Monitoring 같은 식의 그룹).10

이 순서가 중요한 이유는 ISE에서 역할(persona)이 단순 UI 플래그가 아니라, 데이터/로그/정책 배포/인증서/replication 토폴로지에 영향을 주기 때문입니다. 특히 Monitoring 노드가 엮이면, “로그가 사라져서 검증을 못 하는” 장애가 실제로 발생합니다.

스윙(Blue-Green) 방식이 ‘긴급 패치’에서 오히려 안전한 이유

Cisco 업그레이드 문서는 Backup and Restore upgrade를 권장하며, 그 이유를 “설정/노드 세팅 복원, 데이터 손실 방지, 문제 시 재이미징을 통한 복구”로 설명합니다.11

긴급 패치 상황에서 Blue-Green이 유리한 포인트는 다음입니다.

  • 기존 환경을 건드리는 시간을 최소화하고, cutover를 짧게 만들 수 있음
  • rollback이 “다시 old VIP로 스위칭”으로 단순해질 수 있음
  • 패치 적용된 새 환경에서 사전 검증(정책 hit, AD join, 인증서 chain, pxGrid)을 충분히 돌릴 수 있음

반대로 단점도 명확합니다.

  • 라이선스/VM 리소스/하드웨어 여유가 있어야 함
  • 인증서/키 material 이관, AD rejoin 절차 등 운영 부담 증가

나는 “공격 활발 + 관리 plane 우회” 조합이면, 가능할 때는 스윙을 우선 검토합니다. 단, 조직이 스윙 경험이 없으면, 긴급 상황에서 처음 도입하는 건 또 다른 리스크가 됩니다.

패치가 기능/동작을 바꾸는 구간을 ‘사전 리스크’로 잡아야 합니다

Cisco ISE 3.4 Patch 7 release notes에는 정책 평가의 동작 변경(negation operator가 null attribute에서 false로 평가되도록 변경)과 pxGrid client certificate에 OCSP/CRL 기반 상태 검증을 적용하는 변경이 적혀 있습니다.12

이 두 가지는 인증 우회 취약점과 별개지만, 긴급 패치로 올라타는 순간 운영 장애로 튀어나오기 쉬운 변화입니다.

  • 정책 평가 변화: 기존에 “Not Equals”를 이용해 null을 기대값으로 처리하던 규칙이 갑자기 매칭되지 않을 수 있음
  • pxGrid 변경: 기존에 통과하던 client cert가 revocation/OCSP 정책에 걸리면서 연동 실패 가능

따라서 “취약점 패치”라고만 보고 올라가면, 실제 장애 원인을 파악하기가 어려워집니다. 유지보수 창이 짧을수록, release notes의 “Changes in behavior”는 필수로 체크해야 합니다.12

롤링 패치/업그레이드에서 반드시 준비해야 하는 롤백 경로

긴급 패치는 실패하면 더 큰 사고로 이어집니다. 그래서 나는 패치 버튼을 누르기 전에 롤백을 먼저 결정합니다.

1) 패치 롤백 경로가 ‘어디에서 설치했는지’에 종속됩니다

Cisco ISE 3.4 patch 가이드는 패치를 Patch Management의 Install로 설치했으면 rollback도 Patch Management의 Rollback을 쓰라고 권고합니다. 반대로 Upgrade & Rollback 페이지에서 Full/Split upgrade를 사용한 경우에는 같은 페이지의 Patch Rollback을 사용해야 한다고 구분합니다.9

운영 체크리스트로 바꾸면 이렇습니다.

  • “우리는 GUI에서 어느 메뉴로 설치할 건가”를 먼저 정한다
  • 설치 방식이 바뀌면 rollback 방식도 같이 바뀐다
  • 설치/롤백의 주체(PAN/Secondary PAN)와 모니터링 위치를 문서대로 고정한다

이 구분을 놓치면, 롤백이 필요한 순간에 메뉴/옵션이 달라져서 시간만 날립니다.

2) Hot Patch는 최후 수단이고, 파일 구조부터 롤백을 강제합니다

Cisco의 Hot Fix/Hot Patch 문서는 hot patch를 “last resort”로 표현하고, 일반적으로 installation/rollback/readme 3종이 제공된다고 정리합니다. 또한 hot patch는 webGUI로 설치할 수 없고 CLI에서 application install로 진행한다고 못 박습니다.13

긴급 대응에서 hot patch를 쓰는 조직도 있는데, 여기서 실수는 두 가지로 갈립니다.

  • 롤백 번들을 저장하지 않음(= 되돌릴 수 없게 됨)
  • 설치/롤백 readme를 유지보수 창에 들어가서 처음 읽음

Hot patch를 받는 시점에 “rollback 번들까지 확보하고 해시 검증까지 끝낸 상태”가 아니면, 유지보수 창이 짧은 상황에서는 오히려 사고 확률이 올라갑니다.13

패치 전 검증 체크리스트: HA/로그/노출면 기준으로 쪼개기

나는 패치 전 점검을 “기능 점검”이 아니라, 검증 가능성 확보로 봅니다. 즉, 패치 후 문제가 생겼을 때 “어디서부터 깨졌는지”를 추적할 수 있게 만드는 과정입니다.

A. HA/배포 상태

  • 노드 역할/페르소나(PAN/MnT/PSN/pxGrid)와 primary-secondary 관계를 문서화
  • patch wizard prerequisite에서 배포 동기화/서비스 상태를 체크한다는 점을 고려해, 미리 서비스 상태를 정상으로 만들어 둠9
  • PAN HA를 disable해야 하는지(문서 prerequisite에 포함) 유지보수 전에 리허설 수준으로 확인9

B. 노출면 실측

  • 외부에서 닿는 FQDN/VIP 목록 확정
  • 443(관리), 8443(SAML admin login 연계 가능), 22(SSH)가 어떤 source CIDR에 열려 있는지 표로 확정7
  • LB/WAF/Reverse Proxy가 앞에 있다면 “원본 클라이언트 IP가 ISE 로그에 남는지” 확인(남지 않으면 추적이 어렵다)

C. 로그/감사 데이터 보존

  • ISE의 감사/변경 로그(Change Configuration Audit 등)를 SIEM으로 보내고 있는지 확인
  • 유지보수 창 직전/직후 시점의 로그 보존 정책 확인(짧게 잡혀 있으면 사고 후 조사에서 공백이 생김)

여기서 “로그를 어디서 볼 건가”를 사전에 합의하지 않으면, 패치 후 장애가 났을 때 팀 간에 시간을 다 씁니다.

패치 후 검증: ‘버전이 올랐다’ 말고, 공격 표면이 닫혔는지 확인하기

패치 후 검증은 두 갈래입니다.

1) 기능이 살아 있는지(인증/인가/연동) 2) 공격 표면이 실제로 닫혔는지(적어도 더 이상 “비인증으로 관리 영역 진입”이 안 되는지)

1) 노드별 패치 레벨 재수집(혼합 상태 방지)

앞에서 만든 SSH 수집 스크립트를 패치 직후 다시 돌려서, 노드별 patch level이 fixed release 이상인지 확인합니다. Cisco의 fixed releases 매트릭스는 advisory에 명확히 나와 있으니, 여기서 논쟁할 여지가 없습니다.1

2) API Gateway 설정/노드 상태 점검

API Gateway는 “어느 노드에 enable되어 있는지”가 중요합니다. DevNet 문서에 /admin/API/apiGateway/get로 상태 조회 예시가 있습니다.6

여기서 검증 포인트는 “응답 내용”이 아니라 “접근 통제”입니다.

  • 인증 없는 요청이 200으로 떨어지면 안 됨
  • 최소한 302(로그인 유도) 또는 401/403(인증 요구)로 떨어져야 정상

예시(상태코드만 확인):

1
2
curl -k -s -o /dev/null -w "%{http_code}\n" \
  https://ise.example.com/admin/API/apiGateway/get

이 호출은 문서에 존재하는 정상 endpoint를 조회하는 것이고, exploit reproduction과는 별개입니다. 그럼에도 “비인증 접근이 어떻게 처리되는지”는 운영 관점에서 의미가 있습니다.

3) 릴리스 노트 기반 ‘행동 변화’ 회귀 테스트

3.4 Patch 7로 올라간다면, release notes에 적힌 정책 평가 변경과 pxGrid 인증서 검증 변경은 최소 회귀 테스트 항목으로 잡아야 합니다.12

  • (정책) 기존에 null attribute를 전제로 짜여 있던 authorization rule이 있는지, 실제 인증 트래픽 샘플로 확인
  • (pxGrid) 인증서 기반 연동이 있다면 OCSP/CRL 정책에 걸리지 않는지 확인

이건 취약점 대응과 무관해 보이지만, 긴급 패치 후 “인증이 간헐적으로 실패한다” 같은 장애로 표출되기 쉬운 지점입니다.

패치 전후 탐지/헌팅: ISE-kong access.log를 운영 로그로 끌어올리기

Cisco advisory는 IOC 확인을 위해 ise-kong/access.log를 보라고 안내합니다. 예시로 CLI에서 아래처럼 검색하라고 적혀 있습니다.1

  • show logging application ise-kong/access.log | include <username>

또한 분산 배포라면 “각 노드의 로그를 검토하라”고 적었습니다. 그리고 추가 access.log는 support bundle(디버그 로그 포함)에서 ./ise/logs/apigateway/access.log.<date>.gz 경로로 찾을 수 있다고 설명합니다.1

이 조언을 운영 수준으로 끌어올리면 다음으로 바뀝니다.

1) ISE-kong access log를 “사고 때만 보는 파일”이 아니라 SIEM ingest 대상으로 승격 2) 패치 전 7일~30일 구간을 기준으로, 관리 plane 접근 패턴을 baseline으로 저장 3) 패치 후에는 “공격 시도(실패)”가 더 늘 수 있으니, 실패 패턴을 탐지 룰로 만든다

로그 기반 탐지 룰 설계(현실적인 수준)

CVE-2026-76460의 구체 endpoint는 공개되지 않았으니, 특정 URI 시그니처에만 기대면 금방 무력화됩니다. 나는 대신 아래의 행위 기반 규칙을 씁니다.

  • (R1) /admin/ 또는 /admin/API/로 들어오는 요청이 “관리자망이 아닌 source IP”에서 발생
  • (R2) 비인증 상태로 보이는 요청(쿠키/세션 부재)인데, 응답이 200/302가 비정상적으로 반복
  • (R3) 동일 source IP가 짧은 시간에 username 파라미터(또는 path segment)를 바꿔가며 반복 시도
  • (R4) 패치 적용 직후 24~72시간 구간에, 기존에 없던 User-Agent/ASN/지리적 위치가 admin 경로를 두드림

Cisco advisory가 “suspicious usernames”를 힌트로 던진 이유는, 공격자가 crafted request에 임의 username을 넣어 로그 흔적을 남기는 패턴이 있기 때문입니다.1

예시: Splunk (Kong/Nginx 스타일 access log 전제)

index=ise sourcetype=ise:kong:access
uri_path IN ("/admin/", "/admin/API/") OR like(uri_path, "/admin/%")
| eval is_admin_src=if(cidrmatch("10.10.0.0/16", src_ip) OR cidrmatch("192.168.50.0/24", src_ip), 1, 0)
| where is_admin_src=0
| stats count min(_time) as first max(_time) as last values(status) as statuses values(user_agent) as uas by src_ip, uri_path
| where count > 20

이 쿼리는 “우리 관리자망이 아닌 곳에서 admin 경로를 20번 이상 두드린 IP”를 뽑아냅니다. 숫자(20)는 환경에 맞게 조정합니다.

예시: Elastic/KQL

1
event.dataset: "ise-kong" and url.path: /admin* and not client.ip: (10.10.0.0/16 or 192.168.50.0/24)

여기까지는 기본이고, 패치 직후에는 다음을 추가합니다.

  • status code 분포가 200/302 중심으로 나온다면(정상 로그인 유도) “관리자망 밖 접근이 성공적으로 UI를 열고 있다”는 뜻일 수 있음
  • status code가 401/403 중심으로 나온다면(차단) “탐지 이벤트”로는 의미가 있으나, 즉시 장애로 이어질 가능성은 낮음

네트워크 IDS 관점: Cisco Hardening Release의 Snort rule을 ‘외부 신호’로 활용

Cisco는 2026-09-16에 ISE hardening release advisory를 별도로 내면서 Snort Rule SID 목록을 action link로 제공합니다.14

이 규칙들이 CVE-2026-76460 단일 취약점만을 정확히 찍는지 여부는 문서만으로 단정하기 어렵습니다. 하지만 운영에서는 다음처럼 쓸 수 있습니다.

  • “ISE를 직접 탐지하기 어렵다” → 경계 구간(DC egress, remote access ingress)에서 Snort/IPS로 이상 트래픽을 잡아 triage 신호로 활용
  • hardening advisory의 rule SID를 기준으로 룰 배포 여부를 점검

결국 관리 plane 공격은 “패치만 하면 끝”이 아니라 “패치 후에 공격 시도는 더 늘 수 있다”가 현실입니다.

운영 체크리스트(압축): 패치 전·중·후에 무엇을 확인해야 하는가

이 섹션은 실행 순서만 남깁니다.

패치 전(변경 승인 전에 확정)

  • 고정: 대상 release별 fixed patch 목표치 확정(예: 3.4는 Patch 7)1
  • 노드별 patch level 실측 수집(SSH 수집 결과를 증적화)
  • 노출면 실측(관리 FQDN/VIP 기준으로 443 reachable source 범위 확정)5
  • HA/배포 상태 점검 및 “PAN HA disable 요구” 여부 확인9
  • 롤백 경로 결정(어느 메뉴/어느 방식으로 설치할지에 따라 rollback이 갈림)9
  • ISE-kong access log 보존/수집 계획 수립(패치 전 최소 7일 구간 보존)

패치 중(작업자가 흔히 놓치는 지점)

  • 노드가 재기동/서비스 restart되는 시점에 인증 트래픽 우회 경로(secondary PSN, LB, NAD failover)가 실제로 작동하는지 확인
  • patch wizard precheck 실패 항목을 “무시하고 진행”하지 않기(대개 나중에 롤백/동기화 장애로 돌아옴)9

패치 후(기능 + 공격 표면)

  • 노드별 patch level 재수집(혼합 상태 제거)
  • admin/API 경로에 대한 비인증 접근이 기대한 방식으로 거부되는지 확인(상태코드 레벨)
  • 3.4 Patch 7이라면 release notes의 행동 변화(정책 평가, pxGrid OCSP/CRL)를 회귀 테스트12
  • ISE-kong access log에서 패치 전후 “관리자망 외 접근” 패턴이 있는지 헌팅1

여기까지 완료되면, 긴급 패치가 “버전 올리고 끝”이 아니라 “노출면을 줄이고, 자산을 정확히 매핑하고, HA에서 깨지는 지점을 통제하고, 사후 탐지까지 연결”된 대응으로 닫힙니다.

참고 자료

  • Cisco Identity Services Engine Authentication Bypass Vulnerability (CVE-2026-76460)1
  • Alert AL26-021: Vulnerabilities Impacting Cisco ISE/ISE-PIC (CVE-2026-76460 포함)2
  • Cisco Identity Services Engine Hardening Release: September 202614
  • Cisco ISE 3.4 Upgrade Guide: Install Latest Patch9
  • Install Hot Fix and Hot Patch on ISE13
  • Cisco ISE Administrator Guide 3.1: Ports Used by the Administration Portal / API Gateway 개요5
  • Cisco ISE Ports Reference (Installation Guide)7
  • Cisco ISE API Gateway (DevNet 문서)6
  • Release Notes for Cisco Identity Services Engine, Release 3.4 (Patch 7 변경 사항 포함)12
  • CISA Adds Two Known Exploited Vulnerabilities to Catalog (CVE-2026-76460 포함)3
  • VulDB: CVE-2026-76460 KEV due date(재인용)4
  1. https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-ISE-ABP-VNSW7Tn5.html ↩︎ ↩︎2 ↩︎3 ↩︎4 ↩︎5 ↩︎6 ↩︎7 ↩︎8 ↩︎9 ↩︎10 ↩︎11 ↩︎12

  2. https://www.cyber.gc.ca/en/alerts-advisories/al26-021-vulnerabilities-impacting-cisco-identity-services-engine-ise-cisco-ise-passive-identity-connector-ise-pic-cve-2026-20192-cve-2026-76423-cve-2026-76460 ↩︎ ↩︎2 ↩︎3

  3. https://www.dejavu.org/cgi-bin/get.cgi?url=https%3A%2F%2Fwww.cisa.gov%2Fnews-events%2Falerts%2F2026%2F09%2F16%2Fcisa-adds-two-known-exploited-vulnerabilities-catalog&ver=93 ↩︎ ↩︎2

  4. https://vuldb.com/vuln/406239 ↩︎ ↩︎2

  5. https://www.cisco.com/c/en/us/td/docs/security/ise/3-1/admin_guide/b_ise_admin_3_1.pdf ↩︎ ↩︎2 ↩︎3 ↩︎4 ↩︎5 ↩︎6 ↩︎7 ↩︎8

  6. https://developer.cisco.com/docs/identity-services-engine/v1/ ↩︎ ↩︎2 ↩︎3 ↩︎4

  7. https://www.cisco.com/c/en/us/td/docs/security/ise/3-1/install_guide/b_ise_InstallationGuide31/b_ise_InstallationGuide31_chapter_7.html ↩︎ ↩︎2 ↩︎3 ↩︎4 ↩︎5 ↩︎6 ↩︎7

  8. https://www.cisco.com/c/en/us/td/docs/security/ise/3-1/admin_guide/b_ise_admin_3_1/b_ISE_admin_31_basic_setup.html ↩︎

  9. https://www.cisco.com/c/en/us/td/docs/security/ise/3-4/upgrade_guide/HTML/b_upgrade_install_patch_3_4.html ↩︎ ↩︎2 ↩︎3 ↩︎4 ↩︎5 ↩︎6 ↩︎7 ↩︎8

  10. https://www.cisco.com/c/en/us/td/docs/security/ise/3-3/upgrade_guide/HTML/b_upgrade_method_3_3.pdf ↩︎

  11. https://www.cisco.com/c/en/us/td/docs/security/ise/2-7/upgrade_guide/Upgrade_Journey/HTML/b_upgrade_method_2_7.html ↩︎

  12. https://www.cisco.com/c/en/us/td/docs/security/ise/3-4/release_notes/cisco-identity-services-engine-release-notes-34.html ↩︎ ↩︎2 ↩︎3 ↩︎4 ↩︎5

  13. https://www.cisco.com/c/en/us/support/docs/security/identity-services-engine/222814-install-hot-fix-hot-patch-in-ise.html ↩︎ ↩︎2 ↩︎3

  14. https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-hardening-ise-XU5EwX5T.html ↩︎ ↩︎2

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.