
HikCentral Professional - 사전 인증 라이선스 ActiveCode 유출
다운로드 전에 이미 공개된 정보는 다음과 같습니다:
| 출처 | 알려주는 내용 |
|---|---|
| Hikvision 보안 권고 | "API 엔드포인트에 인증 확인 누락", V2.6.3 / V3.0.1로 업그레이드 권고 |
| NVD CVE-2025-39247 | CVSS 메트릭; 벡터: 네트워크, 인증 불필요, 범위 변경, 기밀성 높음 |
| Wiz, ZeroPath, SentinelOne, OffSeq, gbhackers, cybersecuritynews 요약 | 모두 권고를 재진술함; 기술적 세부사항, PoC, 영향받는 엔드포인트 이름 없음 |
| GitHub PoC 수집기 (poc-in-github, 0xMarcio/cve 등) | 인덱싱된 PoC 없음 |
| 포럼 (ipcamtalk, cctvforum, reddit), 토렌트 인덱서 | PoC 없음, 유출된 설치 프로그램 없음; ipcamtalk에 HikCentral 사용법 스레드는 있지만 익스플로이트 관련 내용 없음 |
따라서 분석일 기준으로 공개된 기술 문서에서 이 버그가 노출되지 않았습니다. 재현은 바이너리 디핑부터 시작해야 합니다.
CVE-2025-39247이 게시된 후 V2.6.2 다운로드 페이지는 목록에서 제거되었지만, CDN의 파일은 삭제되지 않았습니다. 파일 이름은 제거 전 페이지를 인덱싱한 타사 미러(FileHorse — 파일 이름 및 MD5 게시)에서 복구할 수 있습니다. 해당 파일 이름을 사용하여 일반 브라우저 User-Agent와 일치하는 Referer 헤더만으로 Hikvision CDN에 일반 GET 요청을 보내면 여전히 제공됩니다.```bash
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0"
-H "Referer: https://www.hikvision.com/en/support/download/software/hikcentral-professional-v2-6-2/"
-O
"https://www.hikvision.com/content/dam/hikvision/en/support/download/vms/hcp-2-6-2/HikCentral-Professional_Full-Pack_V2.6.2.202501211507_Win_x64_Installer.exe"
결과:
- 크기: 1,314,043,792 바이트 (1.22 GB)
- MD5: `76d42e7cb16dc0e177b9a35d0fed7ced` — FileHorse에 게시된 값과 일치하여, 진정한 Hikvision 서명 설치 프로그램임을 확인합니다 (서드파티 재번들이 아닙니다)
- CDN 응답 헤더: `HTTP/2 200`, `content-type: application/x-msdownload`, `eo-cache-status: HIT`, `age: 2520395` (≈ Tencent EdgeOne 에지 캐시에서 약 29일 동안 제거 없이 유지됨)
**Hikvision PSIRT에 보고할 만한 부수적 관찰:** V2.6.2 페이지의 "목록 제거"는 외관상일 뿐입니다. 분리된 파일은 인증 및 서명된 URL 게이트 없이 CDN에서 접근 가능합니다. V2.5.1 및 V2.6.0 전체 팩도 동일하게 응답합니다.
### 2.2 패치된 설치 프로그램 (V2.6.3 기본 팩)
현재 V2.6.3 다운로드 페이지에서 연결되어 있으며, 동일한 검색 방법을 사용합니다:```
https://www.hikvision.com/content/dam/hikvision/en/support/download/vms/hcp-2-6-3/HikCentral-Professional_Base-Pack_V2.6.3.202508280142_Win_x64_Installer.exe
V2.6.2 다운로드 페이지에서 여전히 링크되어 있음 (Hikvision이 사용자에게 이를 적용하기를 원합니다):``` https://www.hikvision.com/content/dam/hikvision/en/support/download/vms/cve-2025-39247-security-vulnerability-patch/HikCentral-Professional_CVE-2025-39247_FixPack_V2.3.1-V2.6.2V3.0.0_20250904.exe
- 크기: 32,599,504 바이트 (31 MB)
---
## 3. 정적 추출
세 개 모두 InstallShield 스타일의 PE 래퍼입니다. `7z`는 두 번의 패스로 이를 벗겨냅니다.```bash
# pass 1 — extract PE resources
7z x -o./extracted/v262/pe downloads/<v2.6.2 installer>
7z x -o./extracted/v263/pe downloads/<v2.6.3 installer>
# pass 2 — extract the nested 7-Zip streams hiding in PE resources
# (note: the resource-type label says "ZIP" but the byte signature is 7-Zip)
for ver in v262 v263; do
for z in extracted/$ver/pe/.rsrc/2052/ZIP/*; do
sz=$(stat -c %s "$z"); [ "$sz" -lt 1048576 ] && continue
7z x -o"extracted/$ver/payload/$(basename $z)" "$z"
done
done
두 설치 프로그램 모두 약 24개의 명명된 페이로드 아카이브로 확장됩니다. 최상위 디렉터리는 아키텍처를 나타냅니다:
| 아카이브 | 내용 |
|---|---|
246/Nginx + 246/www | Nginx 웹 계층 (전면부) 및 SPA 웹 UI |
244/bin | 네이티브 C++ 서비스 바이너리 + 인증서 |
240 | 번들된 PostgreSQL + DB 초기화 스크립트 |
238 | Bee* 런타임 (BeeAgent, BeeGuard, …) |
282 | 애플리케이션 서비스 및 애드온 (C++ 백엔드 코드의 대부분) |
281, 283-284, 396, 398-399, 513, 520, 538-541, 573 | 소규모 애드온, 플러그인, 업그레이드/제거 스텁 |
결정적으로, 어디에도 Java JAR/WAR 파일이 없습니다. 백엔드는 Nginx 위의 C++입니다. 이는 인증 취약점이 디컴파일이 쉬운 WAR/JAR 바이트코드가 아닌 컴파일된 바이너리에 있음을 미리 알려주기 때문에 중요합니다.
for ver in v262 v263: find . -type f -print0 | xargs -0 md5sum | sort -k2 > inv_$ver.txt
v262 = {ln[34:]: ln[:32] for ln in open("inv_v262.txt")} v263 = {ln[34:]: ln[:32] for ln in open("inv_v263.txt")} common = set(v262) & set(v263) changed = [p for p in common if v262[p] != v263[p]]
결과: 공통 경로에서 239개의 변경된 파일. 분포:
| 버킷 | 개수 | 설명 |
|---|---|---|
| `246/www/*.js` (Web UI 청크) | ~200 | 대부분 버전 범프된 애셋 해시; 무시 |
| `246/Nginx/conf/nginx_location.conf` | **1** | **단일 파일 Nginx 구성 델타 — 여기서 시작** |
| `246/Nginx*/install.bat` | 6 | 설치 스크립트, 관련 없음 |
| `244/bin/*.{exe,dll}` | 6 | 네이티브 바이너리 (`DistributionFilter.dll`, `FilterChain.dll`, 미디어 도구) |
| `282/*.{exe,dll}` | 55 | 애플리케이션 서비스 (가장 큰 클러스터 — `platform.dll`, `PersonCredential.dll`, `baseacs.*`, …) |
| `240/bin/pg_*` | 6 | Postgres 재구축, 관련 없음 |
| `284/hplugin/dahua_plugin/*` | 4 | 벤더 SDK 갱신 (+10.97 MB) — 관련 없음 |
| `284/hplugin/onvif_plugin/*` | 4 | 벤더 SDK 갱신 (+0.99 MB) — 관련 없음 |
| 업그레이드/제거 스텁, 충돌 리포터 | ~30 | 동일 크기 PE 타임스탬프 재구축, 무시 |
벤더 SDK 갱신, 빌드 시스템 타임스탬프 드리프트, 순전히 외형적인 애셋 범프를 필터링한 후, 실제 보안 관련 델타는 다음과 같이 줄어듭니다:
- 하나의 Nginx 구성 파일
- `282/`에 있는 소수의 C++ 바이너리 (가장 두드러진 것은 HCMP 백엔드 서비스인 `platform.dll`, +57 KB)
---
## 5. Nginx diff: 무료 버그 위치 찾기
`diff -u nginx_location.conf` V2.6.2와 V2.6.3 사이에서 정확히 하나의 헝크를 생성합니다: V2.6.3에 새로운 `location =` 블록.```nginx
#禁止非127.0.0.1和::1的重置密码 ← "Forbid non-127.0.0.1/::1 password reset"
location = /ISAPI/Bumblebee/Platform/V0/Permission/ChangeDefaultUserPassword {
if ($remote_addr ~ ^(127\.0\.0\.1|::1)$) { set $allowed 1; }
if ($allowed != "1") { return 403; }
if ($scheme = "http") { proxy_pass http://http_backend; }
if ($scheme = "https") { proxy_pass http://http2_backend; }
}
단 21줄의 추가 사항이 CVE-2025-39247 수정의 전면부 계층 전체이며, 모든 것을 설명해 줍니다:
PUT /ISAPI/Bumblebee/Platform/V0/Permission/ChangeDefaultUserPassword/ISAPI/Bumblebee/Platform/V0/* 프록시 지시문을 통해 원격 주소 제한 없이 그리고 Nginx 수준 인증 검사 없이 백엔드로 전달됩니다.중국어 주석이 중요합니다: 문자 그대로 번역하면 "127.0.0.1/::1 이외의 비밀번호 재설정을 금지"를 의미합니다.
웹 UI 자바스크립트(축소됨, 246/www/Portal/*.js에 위치)는 엔드포인트를 다음과 같이 호출합니다:```js
// API definition (de-minified):
changeDefaultUserPassword: function (sid, payload, opts) {
return http.put({
url: "ISAPI/Bumblebee/Platform/V0/Permission/ChangeDefaultUserPassword",
data: { ChangeDefaultUserPasswordRequest: payload },
params: { SID: sid }
}, opts);
}
// Call site: changeDefaultUserPassword(n.SID, { UserName: form.userName, // "admin" Password: jsEncrypt.encrypt(form.newPassword), // RSA-PKCS1v15 ActiveCode: form.activeCode ? jsEncrypt.encrypt(form.activeCode) : "", QuestionList: questionAnswers // [{ID, Answer}, …] or [] }, ...);
// The RSA pubkey comes from another unauthenticated endpoint: getCrypto: function () { http.get({ url: "ISAPI/Bumblebee/Platform/V0/Security/Crypto" }); } // returns: { CryptoKey: <PEM/base64 RSA pubkey>, ... }
따라서 디스어셈블리 전에도, 공개된 JS는 전체 와이어 형태를 제공합니다. 그러나 또한 어색한 부분을 드러냅니다: 요청 본문에는 **유효한 `ActiveCode` 또는 올바른 `QuestionList` 답변**이 필요합니다. 빈 값을 보내면 작동하지 않습니다 — 백엔드는 문서화된 오류 중 하나로 거부합니다(`platform.dll`의 문자열 마이닝으로 확인됨, §7).
따라서 CVE-2025-39247은 **"엔드포인트가 인증 우회이며, 빈 필드를 보내면 비밀번호가 변경된다"**가 아닙니다. 그것은 **"엔드포인트가 로컬 전용 호출자가 이미 올바른 ActiveCode를 가지고 있다고 신뢰하며, 버그는 네트워크 수준의 localhost 게이트가 없어서 유효한 ActiveCode 또는 QuestionList를 제공할 수 있는 모든 *원격* 호출자가 성공한다는 것"**입니다. 따라서 실제 익스플로잇 퍼즐은: ActiveCode 또는 QuestionList는 어디에서 오는가?
---
## 7. 백엔드 핸들러 — `platform.dll` 문자열 마이닝
`platform.dll`은 HCMP 백엔드 서비스로, V2.6.2에서 46.87MB, V2.6.3에서 46.93MB(+57KB)입니다. 모든 라우팅 문자열, 로그 형식 문자열, C++ RTTI/`__FUNCTION__` 문자열이 평문으로 존재합니다.