Joomla JCE <= 2.9.99.4의 CVE-2026-48907에 대한 방어적 랩 검증 및 SOC 탐지 지침으로, Apache/Joomla/auditd 텔레메트리, 웹셸 아티팩트, Sigma 규칙, MITRE ATT&CK 매핑 및 완화 권장 사항을 포함합니다.
CVE-2026-48907(최대 2.9.99.4 버전까지 영향을 주는 Joomla Content Editor(JCE) 취약점)에 대한 방어적 검증 보고서 및 SOC 중심 탐지 노트입니다.
이 저장소는 Joomla JCE의 CVE-2026-48907에 대한 통제된 실험실 검증을 문서화하고 SOC 팀을 위한 실무적 탐지 엔지니어링에 중점을 둡니다.
목표는 공격(exploitation) 가이드를 제공하는 것이 아닙니다. 목표는 검증 과정에서 어떤 텔레메트리 소스가 유용했는지, 어떤 아티팩트가 생성되었는지, 그리고 방어자가 이 활동을 어떻게 탐지하고 대응할 수 있는지를 보여주는 것입니다.
| 영역 | 결과 |
|---|
| 취약점 | Joomla Content Editor(JCE)의 CVE-2026-48907; PHP 업로드 및 코드 실행으로 이어질 수 있는 인증 없는 프로필 생성/가져오기 워크플로. |
| 테스트 버전 | JCE 2.9.99.4. Joomla 관리자 패널에 2.9.99.7 업데이트가 가능하다고 표시됨. |
| 실험실 결과 | 공개 PoC 검증으로 RCE가 확인되었고 Joomla /tmp에 jce*.xml.php 형태의 PHP 웹쉘이 생성되었습니다. 명령은 www-data 권한으로 실행되었습니다. |
| 가장 유용한 텔레메트리 | Apache access.log, Apache/PHP error.log, auditd execve 텔레메트리 및 joomla_html/tmp의 파일시스템 아티팩트. |
| Joomla 로그 | 보조 컨텍스트로는 유용하지만 단독으로는 불충분합니다. Joomla 애플리케이션 로그는 exploit → 웹쉘 → 명령 실행의 전체 체인을 재구성하지 못했습니다. |
| SOC 우선순위 | 인터넷에 노출된 Joomla 인스턴스 또는 신뢰 수준이 낮은 내부 네트워크에서 접근 가능한 Joomla 인스턴스의 경우 위험도(Critical) 수준. |
| 매개변수 | 값 |
|---|---|
| 애플리케이션 URL | http://172.20.10.3:9999 |
| Joomla 컨테이너 | joomla-jce-lab, 이미지 joomla:5-apache |
| 데이터베이스 컨테이너 | joomla-jce-db, 이미지 mariadb:11 |
| 포트 매핑 | 0.0.0.0:9999 -> 80/tcp |
| Apache | Apache/2.4.67 (Debian) |
| PHP | PHP 8.3.31 |
| MariaDB | 11.8.8-MariaDB |
| Joomla | Joomla 5.4.6 Stable |
| JCE | 2.9.99.4 |
| 테스트 소스 | Windows 11, IP 172.20.10.2 |
| 로깅 | Apache access/error 로그, Joomla 로그, auditd, Docker 로그, 파일시스템 아티팩트 |







주요 운영상 발견 사항은 Joomla 애플리케이션 로그만으로는 부족하다는 것입니다.
실험실 테스트 중 Joomla 로그는 joomlafailure 이벤트와 같은 애플리케이션 수준 컨텍스트를 기록했지만 전체 공격 체인을 보여주지는 못했습니다. 유용한 체인은 주로 다음에서 확인할 수 있었습니다:
access.logerror.logexecve 레코드joomla_html/tmp의 파일시스템 아티팩트SOC 모니터링 관점에서 Joomla 로그는 이 취약점의 1차 탐지 소스가 아닌 보조 텔레메트리로 취급해야 합니다.
통제된 테스트 중 관찰된 상위 수준 체인:
JCE version discovery
↓
POST to Joomla JCE component
↓
PHP webshell written to Joomla /tmp
↓
HTTP request to /tmp/jce*.xml.php
↓
Command execution through webshell
↓
auditd confirms /usr/bin/dash and commands executed as www-data
가장 명확한 증거는 Apache access.log에 있었습니다:
GET /plugins/editors/jce/jce.xml
GET /
POST /index.php?option=com_jce
GET /tmp/jceolxtshs3.xml.php
GET /plugins/editors/jce/jce.xml
POST /index.php?option=com_jce
GET /tmp/jce624jdcfx.xml.php
GET /tmp/jce624jdcfx.xml.php?c=id%20%26%26%20hostname%20%26%26%20pwd
GET /tmp/jce624jdcfx.xml.php?c=whoami
GET /tmp/jce624jdcfx.xml.php?c=hostname
GET /tmp/jce624jdcfx.xml.php?c=id
GET /tmp/jce624jdcfx.xml.php?c=pwd
Apache/PHP 오류 로그에는 유용한 파서 관련 흔적이 포함되어 있었습니다:
simplexml_load_string()
administrator/components/com_jce/helpers/profiles.php
RXST
RXEND
RXST 및 RXEND 마커는 페이로드 처리 경로에 나타났기 때문에 이 특정 PoC 계열에서 특히 유용한 지표였습니다.
Joomla 로그는 애플리케이션 로깅이 활성화되어 있음을 확인했지만 공격(exploitation)을 재구성하지는 못했습니다:
#Software: Joomla! 5.4.6 Stable [ Kutegemea ] 26-May-2026 16:00 GMT
#Fields: datetime priority clientip category message
2026-06-18T20:37:57+00:00 INFO 172.20.10.2 joomlafailure Username and password do not match or you do not have an account yet.
즉, Joomla 로그만 수집하면 CVE-2026-48907 악용의 가장 중요한 증거를 놓칠 수 있습니다.
테스트는 Joomla tmp에 PHP 웹쉘 파일을 생성했습니다:
/var/www/html/tmp/jce624jdcfx.xml.php
/var/www/html/tmp/jceolxtshs3.xml.php
실험실의 호스트 측 경로:
/home/user/joomla-jce-lab/joomla_html/tmp/jce624jdcfx.xml.php
/home/user/joomla-jce-lab/joomla_html/tmp/jceolxtshs3.xml.php
관찰된 SHA256 해시:
b6fa303daef8aa8cb39566c73d2cb4a458efb2b1fba48052dd039d45c3beb0aa jce624jdcfx.xml.php
f8bcc802ab56b845c968ed6727228f200f8f4bcd332b8ce82c6980d93ac228fd jceolxtshs3.xml.php
파일 이름과 페이로드는 달라질 수 있으므로 해시 기반 탐지는 내구성이 낮은 것으로 간주해야 합니다. 경로, 확장자, 소유권 및 동작 상관관계가 더 유용합니다.
auditd는 웹 서버 사용자가 Joomla tmp 디렉터리에서 명령을 실행했음을 확인했습니다:
CWD=/var/www/html/tmp uid=www-data comm=sh exe=/usr/bin/dash
CWD=/var/www/html/tmp uid=www-data comm=id exe=/usr/bin/id
CWD=/var/www/html/tmp uid=www-data comm=hostname exe=/usr/bin/hostname
CWD=/var/www/html/tmp uid=www-data comm=whoami exe=/usr/bin/whoami
이것은 해당 활동이 단순한 스캐닝이 아니라 실제 원격 코드 실행(RCE)이었음을 확인하는 가장 강력한 증거입니다.
가장 강력한 탐지는 상관관계 기반입니다:
GET /plugins/editors/jce/jce.xml
followed by
POST /index.php?option=com_jce
followed by
GET /tmp/jce*.xml.php
followed by
GET /tmp/jce*.xml.php?c=
and/or
auditd: www-data executes /usr/bin/dash from /var/www/html/tmp
| 심각도 | 조건 | SOC 조치 |
|---|---|---|
| 낮음(Low) | 비정상 소스로부터의 GET /plugins/editors/jce/jce.xml | 정찰로 간주하고 이후 요청과 상관관계를 분석합니다. |
| 중간(Medium) | 관리자 referer 없이 또는 알 수 없는 IP로부터의 POST /index.php?option=com_jce | 경고를 발생시키고 이후 /tmp 요청을 검토합니다. |
| 높음(High) | POST com_jce 이후의 GET /tmp/*.php 또는 /tmp/*.xml.php | 즉시 파일시스템 아티팩트와 PHP 오류 로그를 검증합니다. |
| 치명적(Critical) | GET /tmp/jce*.xml.php?c= 또는 auditd에서 www-data가 셸/시스템 명령을 실행하는 것이 확인되는 경우 | 확인된 RCE/웹쉘로 간주하고 호스트를 격리하거나 제한한 후 증거를 보존합니다. |
/plugins/editors/jce/jce.xml
/index.php?option=com_jce
/tmp/jce[a-z0-9]{8}\.xml\.php
/tmp/.*\.(php|phtml|phar)(\?| )
cs-uri-query contains "c="
joomla_html/tmp/jce*.xml.php
/var/www/html/tmp/jce*.xml.php
RXST
RXEND
shell_exec
system
passthru
exec
$_GET['c']
소유하거나 조사 권한이 있는 시스템에서만 사용하십시오.
grep -RniE "com_jce|profiles\.import|task=profiles|/tmp/.*\.php|RXST|RXEND" apache_logs joomla_html/administrator/logs 2>/dev/null
find ./joomla_html/tmp ./joomla_html/images ./joomla_html/media \
-type f \( -iname "*.php" -o -iname "*.phtml" -o -iname "*.phar" -o -iname "*.xml.php" \) -ls
sudo ausearch -k wwwdata_exec -i | grep -E "uid=www-data|comm=sh|/usr/bin/dash|/var/www/html/tmp|whoami|hostname| id |pwd"
별도의 Sigma 규칙 파일이 rules/sigma에 있습니다:
| 단계 | 조치 | 목표 |
|---|---|---|
| 1 | 인스턴스가 JCE <= 2.9.99.4를 실행 중이거나 JCE 업데이트가 가능한지 확인합니다. | 취약 상태를 확인합니다. |
| 2 | 액세스/오류 로그에서 com_jce, profiles.import, /tmp/*.php, jce*.xml.php를 검색합니다. | 시도되었거나 성공한 공격을 식별합니다. |
| 3 | tmp, images, media에서 PHP/PHTML/PHAR 파일과 비정상적인 이름을 검사합니다. | 웹쉘 또는 백도어를 탐지합니다. |
| 4 | auditd/EDR에서 www-data가 셸 또는 시스템 유틸리티를 실행하는지 검토합니다. | 코드 실행을 확인합니다. |
| 5 | 웹쉘/RCE가 확인되면 호스트를 격리하거나 애플리케이션으로의 트래픽을 제한합니다. | 추가 활동을 중지합니다. |
| 6 | 아티팩트를 보존하고, 웹쉘을 제거하고, JCE 프로필, Joomla 계정, cron 작업 및 수정된 파일을 검토합니다. | 분류 및 제거(eradication). |
| 7 | JCE를 지원되는 최신 버전으로 업데이트하고 다른 Joomla 인스턴스를 검토합니다. | 완화 및 위험 감소. |
| 우선순위 | 권장 사항 | 근거 |
|---|---|---|
| P1 | Joomla/PHP 브랜치에 대해 지원되는 최신 버전으로 JCE를 업데이트합니다. | 실험실에서 JCE 2.9.99.4가 취약했으며 Joomla에 2.9.99.7 업데이트가 표시되었습니다. |
| P1 | 패치 후 웹쉘과 의심스러운 JCE 프로필을 확인합니다. | 업데이트는 진입점을 차단하지만 패치 이전에 남겨진 아티팩트를 제거하지는 않습니다. |
| P1 | tmp, images, media, cache 및 업로드 디렉터리에서 PHP 실행을 차단합니다. | 업로드가 성공하더라도 PHP 실행 차단은 RCE 체인을 끊습니다. |
| P2 | option=com_jce 및 task=profiles.import에 대한 WAF 또는 요청 필터링을 추가합니다. | 공격 시도가 PHP에 도달하기 전에 탐지하고 차단하는 데 도움이 됩니다. |
| P2 | Apache 액세스 로그, PHP 오류 로그 및 auditd/EDR 텔레메트리를 중앙에서 수집합니다. | Joomla 애플리케이션 로그만으로는 불충분했습니다. |
| P2 | 정기적인 Joomla 확장 기능 인벤토리 및 업데이트 상태 점검을 구현합니다. | Joomla 패널에 JCE 업데이트 신호가 표시되었습니다. 이를 VM/SOC 워크플로에 연결해야 합니다. |
| P3 | 파일 기준선(baseline)을 유지하고 통제된 디렉터리 외부의 새 PHP 파일에 대해 경고합니다. | 침해 이후 웹쉘 및 지속성(persistence)을 탐지하는 데 도움이 됩니다. |
정확한 구성은 Apache/PHP 배포 모델에 따라 달라집니다. 목표는 스크립트를 실행해서는 안 되는 디렉터리에서 PHP 실행을 방지하는 것입니다.
<Directory "/var/www/html/tmp">
php_admin_flag engine off
Options -ExecCGI
RemoveHandler .php .phtml .phar
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>
</Directory>
<Directory "/var/www/html/images">
php_admin_flag engine off
Options -ExecCGI
RemoveHandler .php .phtml .phar
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>
</Directory>
| 기법 | 이름 | 근거 |
|---|---|---|
| T1190 | 공개 애플리케이션 악용(Exploit Public-Facing Application) | 인증 없이 Joomla/JCE 엔드포인트를 HTTP로 악용. |
| T1505.003 | 서버 소프트웨어 구성 요소: 웹 셸(Web Shell) | /tmp/jce*.xml.php로 생성된 PHP 웹쉘. |
| T1059.004 | 명령 및 스크립팅 인터프리터: Unix 셸(Unix Shell) | www-data에 의해 실행된 /usr/bin/dash. |
| T1033 | 시스템 소유자/사용자 검색(System Owner/User Discovery) | 웹쉘을 통해 실행된 whoami 및 id. |
| T1082 | 시스템 정보 검색(System Information Discovery) | 웹쉘을 통해 실행된 hostname. |
| T1083 | 파일 및 디렉터리 검색(File and Directory Discovery) | pwd 및 /var/www/html/tmp에서의 활동. |
실험실은 JCE 2.9.99.4에 대한 실질적인 악용 가능성을 확인했습니다. 관찰된 흐름에서는 Joomla 인증이 필요하지 않았으며, 공개 PoC는 버전 탐지와 웹쉘 생성을 자동화했습니다.
실제 환경에서 Joomla가 인터넷에 노출되어 있거나 신뢰 수준이 낮은 내부 네트워크에서 접근 가능한 경우 위험도는 높음(High)에서 치명적(Critical) 수준입니다. 성공적인 공격은 지속성 있는 웹쉘을 남길 수 있으므로, 노출이 의심되는 경우 아티팩트 검사 없이 패치만 하는 것으로는 충분하지 않습니다.
이 저장소는 방어적 연구, SOC 탐지 엔지니어링 및 취약점 관리를 목적으로 합니다. 익스플로잇 코드는 포함되어 있지 않습니다. 모든 테스트는 소유하거나 명시적으로 평가 권한을 부여받은 시스템에서만 수행해야 합니다.