Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[PyCon Korea 2026] 3년간 43TB의 PyPI를 수집하며 마주한 멀웨...

[PyCon Korea 2026] 3년간 43TB의 PyPI를 수집하며 마주한 멀웨어 — 그리고 공급망 공격을 어떻게 방어할 것인가?

[PyCon Korea 2026] 3년간 43TB의 PyPI를 수집하며 마주한 멀웨어 — 그리고 공급망 공격을 어떻게 방어할 것인가?

2023년부터 2026년 7월까지 약 43TB 분량의 PyPI 패키지를 수집·분석하며 마주친 실제 멀웨어와 펜테스트 도구, 그리고 셀 수 없이 많은 오탐(false positive)을 공유합니다. 이어서 2026년 LiteLLM·PyTorch Lightning을 비롯한 최근의 공급망 공격이 어떻게 일어났는지를 짚어보고, AI 시대의 바이브 코딩과 MCP 패키지 폭증이 만든 새로운 위협도 살펴봅니다. 마지막으로 개인 개발자, 팀, 조직이 각각 적용할 수 있는 현실적인 방어 전략을 제시합니다.
발표 시각 (KST)
2026년 8월 16일 오후 1:30 ~ 오후 1:50 (20분)
4층 4142/4147호

Avatar for DaeHyun Sung

DaeHyun Sung PRO

August 16, 2026

Resources

[PyCon Korea] 3년간 43TB의 PyPI를 수집하며 마주한 멀웨어 — 그리고 공급망 공격을 어떻게 방어할 것인가?

https://2026.pycon.kr/presentations/5e34f50d-9318-465e-b21a-26ce8f81dd53

2023년부터 2026년 7월까지 약 43TB 분량의 PyPI 패키지를 수집·분석하며 마주친 실제 멀웨어와 펜테스트 도구, 그리고 셀 수 없이 많은 오탐(false positive)을 공유합니다. 이어서 2026년 LiteLLM·PyTorch Lightning을 비롯한 최근의 공급망 공격이 어떻게 일어났는지를 짚어보고, AI 시대의 바이브 코딩과 MCP 패키지 폭증이 만든 새로운 위협도 살펴봅니다. 마지막으로 개인 개발자, 팀, 조직이 각각 적용할 수 있는 현실적인 방어 전략을 제시합니다.

More Decks by DaeHyun Sung

Transcript

  1. 3년간 43TB의 PyPI를 수집하며 마주한 멀웨어 - 공급망 공격을 어떻게

    방어할 것인가? 성대현 DaeHyun Sung dhsung at lablup dot com
  2. 자기 소개 오픈소스(Open Source)를 좋아하는 사람 · 여러 FLOSS 프로젝트에

    기여함 · GNOME, KDE, libhangul, LibreOffice 등등 · GNOME Foundation Member · TDF(The Document Foundation) Membership · 현재, 래블업(Lablup)에서 근무
  3. Presentation Overview 01 PyPI 저장소 소개 02 공급망 해킹은 무엇인가?

    03 PyPI 악성 패키지 조사 04 공급망 공격 패턴의 진화 05 방어 전략 및 결론
  4. 왜 PyPI 전체를 수집하였나? 에어갭(Air-gapped) AI인프라 인터넷이 없는 곳에도 pip는

    필요하다 · 금융(Finance): 해킹과 악성코드 감염차단, 민감정보(금융 정보 및 자산 데이터) 보호를 위해 망분리 규제 - 인터넷 차단이 ʻ의무’ · 의료(Health): 환자 데이터는 민감정보이기때문에 단절망으로 운영해야함 · 공공분야(Public Sector): 국가 기밀 및 개인정보 등 민감 정보 보호를 위해 폐쇄망 운영 인터넷 PyPI repo 미러 서버 반입 전 검사 에어갭 반입 매월 1일 차분 수집 AV 스캐너 검사(ex. V3) 폐쇄망에서 pip install · 어떤 패키지를 요청할지 미리 알 수 없음 → 전체 패키지 수집이 필요하다
  5. PyPI 파이썬 생태계의 패키지 공급원 Python Package Index · 규모:

    수십만 프로젝트, 수백만 릴리즈 파일이 존재. 2026년 7월 23일 43TB, 2026년 8월 초 43.8TB · 운영 PSF(Python Software Foundation) CDN(fastly)배포 · 업로드: 계정만 있으면 누구나 즉시 배포 - 사전 심의 없음 · 삭제는 신고 기반 사후 대응 누구나 올릴 수 있다는 개방성이 생태계를 키우고, 해커의 공격도 쉬워짐
  6. PyPI는 3년만에 3배 가까이 커졌음 2023년 5월부터 2026년 7월까지 15TB

    → 43TB · AI/ML 라이브러리, 바이브 코딩 도구, MCP 서버 패키지등 AI붐이 성장을 3.5배 가속 · 검토되지 않은 패키지의 절대량이 함께 늘어남 · 출처: https://pypi.org/stats/
  7. PyPI 이외의 저장소 pip install은 PyPI만 바라보지 않음 · download.pytorch.org/whl

    GPU(Nvidia CUDA, AMD ROCm, Intel Arc 등등)별 torch 빌드 PyPI밖에서 배포함 · pypi.nvidia.com 등: 벤더 전용 인덱스 - GPU 생태계의 필수 경로 · --extra-index-url: 인덱스를 ʻ추가'하면 같은 이름 패키지 간 우선순위 혼란 · 저장소 이슈 torchtriton PyTorch nightly 의 내부 의존성과 같은 이름이 PyPI에 선점 업로드 -> 설치시 PyPI것이 우선 · SSH 키·환경변수 탈취. "의존성 혼동(dependency confusion)"의 교과서 사례 · 참고: Compromised PyTorch-nightly dependency chain between December 25th and December 30th, 2022. https://pytorch.org/blog/compromised-nightly-dependency/
  8. pip install <package name> 악성코드가 들어간 패키지를 실행한다면 $ pip

    install <package name> · sdist의 경우 - 설치하는 순간 setup.py, 빌드 실행 · 휠wheel 파일(예시 ***.whl)의 경우 - 설치는 문제 없지만 import 하는 순간 실행 (.pth 파일이 들어있다면 import 없이도, 파이썬이 뜰때마다 실행) 타이포스쿼팅 계정 탈취 의존성 혼동 업스트림 오염 Typosquatting Account Takeover Dependency Confusion Upstream Compromise aiotools → aiotoolsbox 비슷한 이름 선점 정상 패키지의 새 버전을 변조 ex) LiteLLM, Lightning 내부 패키지 명을 공개 저장소에 선점함 torchtriton 빌드(CI/CD) 단계에서 소스 자체를 변조함 예) ultralytics
  9. 타이포스쿼팅(Typosquatting)의 예 aiotools vs aiotoolsbox · Detecting Malicious Packages on

    PyPI: Malicious package on PyPI use phishing techniques to hide its malicious intent https://blog.checkpoint.com/2023/03/18/detecting-malicious-packages-on-pypi-malicious-package-on-pypi-use-phishing-techniques-t o-hide-its-malicious-intent/
  10. pip install <package name> 악성코드 실행 시점 - 설치할때와 import할때

    설치할 때 악성 코드 실행 - sdist import할 때 악성 코드 실행 - whl 파일 · sdist(.tar.gz): 소스 + 빌드 레시피 · .whl 파일: 빌드가 끝난 결과물 · 설치: 내 머신에서 setup.py 실행 · 설치 시점에는 아무 코드도 실행되지 않는다 → setup.py는 그냥 파이썬 스크립트다 · 하지만 import 하는 순간 __init__.py 실행 · 맞는 휠이 없으면 pip는 조용히 sdist로 폴백 “Building wheel for …” 패키지 코드가 실행됨 예시 · Lazarus : __init__.py 가 XOR DLL 자동 실행 · Lightning 2.6.2 : import 시 11MB 난독화 JS 실행 · 방어 방법: ① 설치할때: “--only-binary :all:” whl파일로만 설치(빌드 스크립트가 아예 돌지 않음) ② import 할 때: 실행을 막을 수 없음. 설치하기 전에 .whl파일 버전, 해시 고정 & 반입 전 검사 · 예외: .pth파일은 import없이도, 파이썬이 시작할때마다 실행 (예. Shai-Hulud 웜 공격 수법)
  11. 3년간 월별 삭제 추이 정기 diff 다운로드 후 검사한 파일

    V3 2617개 파일 삭제, clamscan 1555개 파일 삭제
  12. 오탐(False Positive) vs 미탐(False Negative) 악성코드 스캐너의 두가지 실패 오탐(False

    Positive) 미탐(False Negative) · 정상을 악성코드로 인식 · 전체 탐지의 67% · 대응: 교차 검증, 탐지 경로 확인, 출처 확인, 화이트리스트 · 악성코드를 정상으로 인식함 · 대응: 기본 값을 ʻ미확정'으로 함, 소급 재검사를 해야함(사후 탐지), 구조적 방어(lock파일, SBOM)
  13. 악성이 아닌 경우 Virustotal로 정적분석한 경우 몇몇 9건을 미러에서 직접

    받아 VirusTotal로 정적분석 한 결과 · VirusTotal: 파일 혹은 Hash를 조회하여 60여개 백신엔진에 한꺼번에 돌려보는 서비스 · 다음의 패키지는 설치 및 import 만으로 아무일을 하지 않음 - 백신이 반응할 바이너리를 담음 패키지명 VirusTotal 검사 설명 mik-py 45/63 EICAR 테스트 파일 패키지 — 설계상 스캐너가 탐지 fray 31/65 WAF 테스트 — payloads/web_shells/* 가 탐지 대상 securityforge 28/54 보안 도구 — fray 와 동일하게 페이로드 번들 winhidder 16/59 run() 호출 시에만 winHidder.exe 실행 (winHiddler.exe은 창숨기기 파일) 실행파일이 수상하지만, 자동 실행을 하지 않음)
  14. 악성이 아닌 경우 Virustotal로 정적분석한 경우 mik-py의 VirusTotal 조회 예시

    · package url: https://pypi.org/project/mik-py/ · A Python package containing the Eicar file to help test anti-malware or anti-virus software · VirusTotal: https://www.virustotal.com/gui/file/5aebb58980fb307545e0e7005d315d7eead26b077cdba6e067e2026348debd5a
  15. 미탐(False Negative)후 발견 북한 해커 조직 Lazarus가 공급망 교란으로 배포한

    PyPI 패키지 다운로드 후 malware 검사 2번째에 발견 · V3 첫번째 검사에선 미탐(False Negative)였으나 2번째 검사 후 발견함 · 패키지명: pycryptoenv, pycryptoconf, quasarlib, swapmempool · 수법: pycrypto 오타를 노린 타이포스쿼팅(Typosquatting) · test.py는 파이썬이 아니라 XOR인코딩된 DLL · __init__.py가 그 DLL을 실행 · JPCert/CC - New Malicious PyPI Packages used by Lazarus https://blogs.jpcert.or.jp/en/2024/02/lazarus_pypi.html
  16. 보안도구 보안도구가 대부분 100개 패키지, 탐지 파일 2360개 · “컴퓨팅

    환경에 있어도 되는가?” · 스캐너가 답할 수 없는 질문이고 조직 정책에서 확인해야함 패키지명 설명 crackmapexec AD 침투 도구 — Mimikatz 시그니처로 30개 파일 탐지 pwncat-vl, pywerview PowerSploit 계열 레드팀 도구 fray, payloadforge, vulnmap 공격 페이로드를 번들 → 피싱·웹셸 시그니처로 탐지 bane, doughnuts 봇넷 툴킷 · PHP 웹셸 관리자 · 네트워크 보안 패키지 BdySandbox, masc Cuckoo 샌드박스 · 웹 멀웨어 스캐너 — 분석 도구가 분석 대상을 담는다
  17. 오탐(False Positive) 검사 결과의 대부분을 차지 281개, 전체의 67% ·

    오탐을 방치하면 -> 경보 피로 -> 어차피 오탐인데? -> 진짜 악성을 놓칠 수 있음 · 오탐 관리는 잡무가 아니라 핵심 보안 업무 패키지 명 시그니쳐 이름 설명 uv Win.Trojan.Virut Rust 컴파일 바이너리 numpy, opencv, polars Trojan/Win.Evo-gen 컴파일 된 .pyd/.so 확장 모듈 symbolic Malware/Win32.Generic Sentry SDK
  18. 최근 5년간 PyPI 공격 사건 알려진공격 년도 사건 2022 torchtriton

    2023 위조된 VMware vSphere Connector 모듈 'VMConnect' 악성코드가 들어감 2024 pycryptoenv · pycryptoconf · quasarlib · swapmempool 등 Lazarus의 타이포스쿼팅 공격 2025 soopsocks · termncolor · sisaws · pycord-self … 2026 litellm 1.82.7/8 · lightning 2.6.2/3 · Shai-Hulud PyPI 37종
  19. 탐지하기 전에 거르는 방법 OSSF malicious-packages OSSF malicious-packages목록을 이용하여 설치

    파일 받기 전에 거름 · OSSF Malicious Package: https://github.com/ossf/malicious-packages · https://github.com/ossf/malicious-packages/tree/main/osv/malicious/pypi · PyPI의 경우 총 11,598패키지가 악성 패키지로 등록 · 실제로 OSSF malicious pypi package목록으로 3개 패키지 다운로드 제외됨 · adcraft, amino.fix, whatsfly_labfox
  20. AI가 공격면을 세 방향으로 넓힘 바이브코딩, MCP 폭증, AI 이름

    위장 공통점: ʻ검증 안된 코드를 빠르게 끌어오는’ 문화가 커짐 · 공격자는 도구를 바꾼 것이 아니라 미끼를 바꿈 - 이제 좋은 미끼는 “AI” 바이브 코딩 MCP, pre-release 폭증 AI 이름 위장 AI가 추천한 패키지를 검토 없이 pip install * MCP 이름의 PyPI 패키지: 19,022개 “AI보안도구" 이름을 단 패키지가 2026년 봄경에 급증 슬롭스쿼팅(Slopsquatting): LLM이 존재하지 않는 이름의 패키지를 추천 (환각), 환각한 이름을 공격자가 선점함 예) huggingface-cli 동작하는 코드면 출처를 안보는 이슈 * pre-release(alpha, beta, rc, dev)를 바로 끌어다 씀 * PyPI업로드 용량의 30%정도가 pre-release 2023년까지 4개 → 2024년 96개 → 2025년 8,040개 → 2026년(1~8월) 10,882개 * breach-ai * securevibes * agentcore-sdk * mcpsec
  21. pre-release가 용량의 1/3 PyPI전수 집계(BigQuery distribution_metadata): 2023.05 - 2026.07 ·

    파일 수로 13%, 그러나 용량으로 31%. pre-release가 대용량ML 설치파일에 몰려 있음
  22. 2023년부터 2026년까지 수집하며 본 변화 3년간의 Malware의 변천을 볼 수

    있음 · 방향성: 패키지당 공격 → 자동화 캠페인(스크립트가 변종 양산) → 파이프라인 침해(패키지가 아니라 배포 권한을 노림) 2023 2024 2025 2026 개별 패키지 위장, 동봉형 도구의 양산 CI/CD자체를 노림 * bane 봇넷 툴킷(탐지 286개 파일) * 코인 마이너 클러스터 등 * pynanocms: exe파일동봉 * ultralytics: 계정 탈취 * AI레드팀 도구 급증 * CI 침해 (tj-actions/changed-files GitHub Action해킹, 해킹된 커밋으로 CI/CD시크릿키 유출시도) *LiteLLM: Trivy침해(보안 도구가 침투 경로) * slopsquatting의 부상
  23. 방어 전략 지금 당장 쓸 수 있는 방법 지금 당장

    malware를 회피할 수 있는 방법 · 핀 고정 + .lock파일 -> requirements.txt, uv.lock, poetry.lock 등등 · 쿨 다운(Cooldown) 대기 - 새 버전은 며칠 지나서(3-30일정도) 설치 · 패키지 스캔(scan) - 공급망 공격이 있다는 전제로 항상 스캔 · 검토 - 도구는 멀웨어를 어느정도 걸려 줘도 최종 판단은 사람이 해야함
  24. 방어 전략 개인, 팀, 조직별 방어전략 개인 - 내 컴퓨터에서

    팀 - Repository & CI에서 조직 - 인프라에서 · 설치전: PyPI 페이지 확인 (이름, 배포자, 첫 릴리즈 날짜 등) · 설치 후: pip-audit 로 검사 알려진 취약점 및 악성 DB와 대조 · 새 패키지 추가 시 코드처럼 리뷰 · 설치 경로 단일화: requirements.txt, pyproject.toml에 한줄 사내 미러 하나만 바라보도록 함(--index-url) 추가시 리뷰필요 · 반입 전 이중 스캔 · 잠금파일로 버전·해시 고정 · CI 게이트: pip-audit실행하여 이슈가 생기면 + OSSF 목록으로 수집 자체를 차단 (uv.lock, pip --require-hashes) 병합(merge) 금지 · 격리 보관 및 허용 목록 운영 · --only-binary :all: (바이너리 패키지로 · 자동 업데이트 유예 기간(쿨다운 cool down) · 스캐너의 시그니처 갱신 후 소급 재검사 설치하도록 강제) 설정 패키지 설치 할 때 실행(sdist) 차단 · SBOM(Software Bill of Materials): 소프트웨어가 만드는데 사용된 모든 오픈소스, 라이브러리, 모듈등 구성요소와 의존성을 기록한 목록. 패키지 침해 확인시 명세보고 바로 확인 가능
  25. 결론 43TB를 수집하며 가르쳐준것 3년동안 43TB의 PyPI를 수집한 결과 ·

    이미 PyPI는 오염되어 있음 · malware scan의 탐지의 67%정도가 오탐(False Positive) → 탐지 수는 판정이 아님. 경보 피로가 진짜를 놓침 · 차단은 다운로드 전에 진행해야함 → OSSF 목록으로 수집단계에서 필터링하여 안받도록 진행해야함 → 스캔은 그 다음 방어선 · 받아서 바로 실행하지 말고, 검사한 뒤, 반입한 후 실행하자