
install ps1 iex: 왜 다운로드한 명령어를 실행하면 안 되는가 - FBI의 TeamPCP 교훈
요약
PowerShell의 'irm | iex' 패턴이 가진 보안 위험성을 FBI의 TeamPCP 공격 사례를 통해 분석합니다. 합법적인 도구들이 사용하는 방식이지만, 공급망 공격의 주요 경로가 될 수 있음을 경고합니다.
핵심 포인트
- irm | iex는 스크립트를 메모리에 즉시 실행하여 파일리스 공격에 취약함
- TeamPCP 그룹은 LiteLLM 등 라이브러리를 오염시켜 API 키를 탈취함
- 공식 문서의 설치 명령어를 맹목적으로 신뢰하는 습관이 위험함
- 실행 정책(Execution Policy)은 보안 도구가 아닌 단순 경고 수단임
«install ps1 iex» 요청은 보통 동일한 명령어로 이어집니다: powershell -ExecutionPolicy Bypass -c "irm https://…/install.ps1 | iex". 문서, 포럼 또는 AI 어시스턴트가 이 명령어를 제공했을 때, "이것을 정말 실행해도 되는가"라는 질문은 가능한 가장 올바른 질문입니다. 짧은 답변을 드리자면: 이 조합 자체는 합법적이며 공식 프로젝트에서도 사용됩니다. 하지만 서버가 반환한 모든 것을 맹목적으로 실행하는 것은 위험합니다.
이것이 얼마나 위험한지는 2026년 공식 문서를 통해 드러났습니다. 7월 2일, FBI는 FLASH-20260702-01 "Cyber Criminal Group TeamPCP" 회보(TLP:CLEAR, 6페이지)를 발표했습니다. TeamPCP 그룹은 개발자와 보안 전문가들이 사용하는 여러 도구를 오염시켰으며, 수천 개의 CI/CD 환경에서 클라우드 토큰, SSH 키 및 Kubernetes 비밀(Secrets)을 탈취했습니다. 피해 사례 중에는 PyPI에서 월간 약 9,500만 회의 다운로드를 기록하는 신경망 API 게이트웨이 라이브러리인 LiteLLM이 포함되어 있습니다. 3월 24일, 이 라이브러리는 일반 업데이트와 함께 거의 두 시간 동안 백도어(Backdoor)를 배포했으며, 주요 목표는 LLM 제공업체의 API 키였습니다.
irm …install.ps1 | iex 명령어는 무엇을 하는가?
요약하자면: 이 한 줄짜리 명령어는 스크립트를 메모리로 다운로드한 즉시 코드로 실행하며, 디스크에 파일을 저장하지 않습니다. 스크립트는 사용자와 동일한 권한을 가집니다. 즉, 터미널이 관리자 권한으로 열려 있다면 스크립트도 관리자 권한으로 실행됩니다. 이때 -ExecutionPolicy Bypass 플래그는 서명되지 않은 스크립트에 대한 경고를 무시합니다.
상세 분석:
| 명령어 조각 | 역할 | 위험 요소 |
|---|---|---|
powershell | PowerShell 인터프리터를 실행합니다 | 코드가 사용자의 권한을 가진 새 프로세스에서 작동합니다 |
| ... |
이 메커니즘에서 두 가지 결론이 도출됩니다. 첫째: 파일리스(Fileless) 실행 - 디스크에 파일이 기록되지 않지만, 프로세스와 그 동작은 EDR, 안티바이러스 및 네트워크 모니터링에 의해 탐지될 수 있습니다. 둘째: "다운로드"와 "실행" 사이에 스크립트를 눈으로 직접 확인하고 신뢰 여부를 결정할 수 있는 일시 정지 시간이 없습니다.
이때 iex는 바이러스나 해커의 발명품이 아닙니다. 이는 표준 명령렛(cmdlet)인 Invoke-Expression이며, Microsoft 스스로도 해당 문서에 "주의: 명령어가 안전한지 확인하십시오"라는 경고 블록을 유지하고 있으며, 호출 연산자 &를 더 안전한 대안으로 직접 명시하고 있습니다.
왜 "다운로드 후 실행"이 표준이자 주요 공격 경로가 되었는가?
요약하자면: 이 패턴은 합법적인 프로젝트들에 의해 정상화되었습니다. Hugging Face CLI (irm https://hf.co/cli/install.ps1 | iex), Bun, Chris Titus의 winutil 등이 이 방식을 사용합니다. 공식 문서가 "관리자 권한으로 이것을 실행하십시오"라고 가르칠 때, 정상적인 절차와 함정 사이의 경계가 모호해지며, 공격자들은 바로 이 습관을 이용합니다.
"네트워크에서 다운로드하여 실행한다"는 모델은 일상적인 형태의 공급망 공격 (Supply Chain Attack)입니다. 공격자가 당신을 직접 해킹할 필요 없이, 설치 또는 업데이트 경로에 자리 잡기만 하면 충분하기 때문입니다. 이 패턴에는 Unix 계열의 형제 격인 curl | bash가 있습니다. 구문은 다르지만, 맹목적으로 실행한다는 점은 동일합니다.
보호에 대한 미신에 대해 별도로 언급하자면: 실행 정책 (Execution Policy)은 누구도 보호해주지 않습니다. 이는 경고일 뿐이며, -ExecutionPolicy Bypass 플래그는 프로세스가 진행되는 동안 이를 단순히 꺼버립니다. Microsoft Q&A (2026년 5월)에서 irm ... | iex 패턴은 위험한 것으로 직접 명시되었으며, 권장 사항은 매우 평범합니다: 스크립트를 다운로드하여 검토한 다음 실행하십시오. 악성코드 (Malware)의 지속성 유지 (Persistence) 징후로는 레지스트리의 Run 키와 -ExecutionPolicy Bypass 및 iex(irm ...)가 포함된 작업 스케줄러가 언급되었습니다. 이 조합을 기억해 두십시오. 아래에서 필요할 것입니다.
참고로, AI 도구 설치 외에도 러시아의 현실적인 문제인 비용 문제가 있습니다. Claude나 GPT를 러시아 카드로 직접 결제할 수는 없습니다. 작동하는 방법은 세 가지입니다: 해외 카드, 추가 비용이 붙는 리셀러, 그리고 provod.ai (러시아의 OpenRouter)와 같은 애그리게이터(Aggregator)를 통해 동일한 모델을 공식 요금의 루블화로 이용하는 것입니다. 하지만 그 전에, 명령어 자체에 대해 알아보겠습니다. 이것이 더 중요합니다.
FBI는 TeamPCP에 대해 무엇이라고 말하는가?
요약하자면: 2026년 3월 5일 동안 TeamPCP 그룹은 보안 스캐너인 Trivy부터 PyPI의 LiteLLM 라이브러리에 이르기까지 5개의 생태계를 연쇄적으로 통과했습니다. FBI는 이번 캠페인과 관련하여 4개의 CVE를 연결하고 있으며, 웜(worm)이 탈취된 자격 증명(credentials)을 사용하여 피해자의 GitHub 조직 내에 생성하는 tpcp-docs 및 docs-tpcp 저장소를 감염 마커로 지목했습니다. 2026년 7월 기준으로, 탈취된 자격 증명은 회수(revocation) 또는 순환(rotation) 전까지는 침해된 것으로 간주해야 하며, 사고 발생 후에도 지속적인 모니터링이 필요합니다.
Mallory Intel, Trend Micro 및 Cycode 보고서에 따른 연대기:
| 날짜 (2026) | 대상 | 발생 상황 |
|---|---|---|
| 3월 19일 | Trivy, GitHub | trivy-action 태그 77개 중 76개 및 setup-trivy 태그 7개 전체에 대한 강제 푸시(force-push); 트로이목마화된 v0.69.4 릴리스 |
| ... |
첫 번째 도미노가 보안 전문가를 위한 도구였다는 점은 시사하는 바가 큽니다. 2월 말, 봇은 Trivy CI의 안전하지 않은 pull_request_target-workflow를 악용하여 aqua-bot 토큰을 탈취했습니다. Aqua는 3월 1일에 사고를 공개하고 순환(rotation)을 시작했지만, 자체 사후 분석 보고서(post-mortem)에서 인정했듯이 순환은 "원자적(atomic)이지 않았습니다" — 공격자들은 잔류 액세스 권한을 유지했고, 이를 3월 19일에 활용했습니다. 이 사고는 CVE-2026-33634 번호를 부여받았으며(CVSS 9.4, "내장된 악성 코드"), 이후 CISA KEV 카탈로그에 등록되었습니다.

LiteLLM과 관련된 에피소드는 인공지능(AI) 사용자들을 직접적으로 타격했다는 점에서 별도로 주목할 만합니다. TeamPCP는 CI에서 탈취한 PYPI_PUBLISH 토큰을 사용하여 1.82.7 버전(10:39 UTC)과 1.82.8 버전(10:52 UTC)을 게시했습니다. 아이러니하게도 LiteLLM 자체의 CI가 오염된 Trivy를 실행하고 있었습니다. 11:48 UTC에 연구원 Callum McMahon은 자신의 컴퓨터에서 발생한 "포크 폭탄(fork bomb)" 이후 GitHub issue #24512를 생성했습니다; 메인테이너(maintainer) 권한을 가진 공격자는 해당 스레드를 닫고 봇 댓글로 도배했습니다.
백도어의 메커니즘은 별도의 주제입니다. 1.82.7 버전에서는 proxy_server.py 내의 12줄에 불과했던 난독화된 코드였으나, 1.82.8 버전에서는 site-packages 내에 34,628바이트 크기의 litellm_init.pth 파일로 변했습니다. Python은 인터프리터가 시작될 때마다 .pth 파일의 import 문을 실행하므로, 이 악성코드(malware)는 litellm을 임포트하지 않더라도 Jupyter, Ansible, 테스트 등 모든 Python 프로세스에서 작동했습니다. Snyk은 해당 파일이 유효한 해시와 함께 휠(wheel)의 RECORD에 정직하게 선언되어 있었음을 확인했습니다. 즉, 형식적으로는 패키지가 "온전한" 상태였습니다. Wiz는 클라우드 환경의 약 36%에서 LiteLLM이 존재하는 것으로 평가했습니다.
개발자의 컴퓨터에서 무엇을 탈취하는가?
요약하자면 다음과 같습니다: AWS, GCP, Azure의 클라우드 토큰, SSH 키, Kubernetes 비밀값(secrets), 환경 변수(env-variables), 암호화폐 지갑, 그리고 LLM 제공업체의 API 키입니다. FBI는 npm과 PyPI를 통해 자가 전파되는 웜(worm)인 CanisterWorm, SANDCLOCK, Mini Shai-Hulud 및 그 변종인 Miasma 제품군을 나열했습니다. FBI가 공개한 침해된 도구 목록은 "~를 포함하지만 이에 국한되지 않는다(including, but not limited to)"라고 명시되어 있습니다.
Trend Micro의 데이터와 CrowdStrike의 관찰에 따르면, 오염된 Trivy의 페이로드(payload)는 Runner.Worker 프로세스의 메모리를 스크래핑(scraping)하고, 파일 시스템에서 자격 증명(credentials)을 수집하며, AES-256-CBC 및 RSA-4096으로 암호화한 뒤 타이포스쿼팅(typosquatting) 도메인인 scan.aquasecurtiy[.]org로 유출했습니다. "i"가 빠져 있다는 점에 주의하십시오. FBI 보고서에 등장하는 두 번째 C2 도메인은 checkmarx[.]zone으로, 이 또한 유명 보안 브랜드를 모방한 것입니다. 가장 끔찍한 점은 데이터 탈취 후에도 정상적인 스캔이 문제없이 수행되었다는 것입니다. 로그에는 아무런 흔적도 남지 않았습니다.
결과(consequences)의 규모는 피해 사례를 통해 알 수 있습니다. Mercor의 경우, 탈취된 Tailscale 키를 통해 소스 코드, PII(개인 식별 정보) 데이터베이스, 비디오 인터뷰, 신분증 문서 등 4TB의 데이터를 유출당했습니다. Cloud Security Alliance의 요약(Google GTIG는 이 그룹을 UNC6780으로 추적 중)에 따르면, Trivy 해킹에서 유출된 자격 증명(credentials)은 이후 Cisco의 개발(dev) 환경으로 이어졌으며, 이를 통해 Cisco AI Assistant의 소스 코드가 포함된 300개 이상의 내부 리포지토리(repositories)가 노출되었습니다. 또한 5월 18~20일 사이, 해당 그룹은 Visual Studio Marketplace에 18분 동안 게시되었던 트로이 목마화된 Nx Console 확장 프로그램을 통해 GitHub의 내부 인프라에 침입하여 약 3,800개의 리포지토리를 탈취했습니다.
탈취된 데이터에 대한 FBI의 문구는 두 번 읽어볼 가치가 있습니다. 즉,
Windows에서 수동으로 설치하려면:
- 오직 1차 출처(공식 리포지토리, 공식 문서)의 링크만 사용하세요. 채팅창, 광고, 혹은 "편리한" 미러 사이트에서 가져오지 마세요. 도메인을 철자 하나하나 대조하여 확인하십시오. 이번 사건에서는 타이포스쿼팅 (Typosquatting)이 두 번이나 발생했습니다.
- 스크립트를 파일로 다운로드하세요:
irm https://…/install.ps1 -OutFile install.ps1. - 에디터로 열어서 읽어보세요. 난독화된(Obfuscated) 코드 조각, base64, 이상한 외부 주소, 스크립트 내부에 포함된
iex등을 찾으십시오. - 호출 연산자(Call operator)를 통해 로컬에서 실행하세요:
& . rain.ps1. 스크립트에 서명이 되어 있다면 Bypass 없이 실행하십시오. - 패키지 관리자(Package manager)를 통해 설치하는 경우, 락 파일(Lock-files), 명시적 버전, 검증된 해시(Hash) 또는 서명, 그리고 격리된 환경을 사용하세요. 관리자 자체가 보안을 보장하지는 않습니다.
CI/CD를 위해 FBI가 권장하는 사항은 다음과 같습니다: GitHub Actions를 유동적인 태그(Floating tags) 대신 전체 SHA 커밋에 고정(Pinning)하십시오(Trivy 사례에서 태그가 유동적이었기에 재작성되었습니다). 모든 환경에서 패키지의 최소 연령을 7일로 유지하십시오. LiteLLM 사례에서는 이 규칙이 자동으로 당신을 구했을 것입니다. 게시 권한이 있는 계정에는 피싱 방지 MFA (Phishing-resistant MFA)를 활성화하십시오. Harden-Runner와 같은 러너(Runner)가 예상치 못한 외부 연결을 시도하는지 모니터링하십시오. npm 계정의 만료된 복구 도메인(Recovery domains)에 대해 감사를 수행하십시오.
의심스러운 명령어를 이미 실행했다면 - 이제 어떻게 해야 하는가?
요약하자면: 기기의 네트워크를 차단하고, 지속성(Persistence) 확보 지점을 점검하며, "증상"이 나타나기를 기다리지 말고 즉시 키 로테이션(Key rotation)을 시작하십시오. Trivy 피해 사례의 경우, 자격 증명(Credentials)이 이미 타인의 서버로 넘어간 상태에서도 스캐너는 평소처럼 작동했기에 아무런 이상 징후를 느끼지 못했습니다. 여기서 징후가 없다는 것은 아무것도 의미하지 않습니다.
절차는 다음과 같습니다. 우선 머신을 네트워크에서 격리하십시오. 그다음 레지스트리(Registry)의 Run 키와 작업 스케줄러(Task Scheduler)에서 -ExecutionPolicy Bypass와 iex(irm …)가 결합된 형태가 있는지 확인하십시오. Microsoft는 이를 전형적인 지속성(Persistence)의 징후로 정의합니다. 다음은 GitHub입니다. 조직 내에서 tpcp-docs 또는 docs-tpcp 리포지토리가 있는지 찾으십시오. FBI는 이 리포지토리들의 생성을 감염의 표식으로 간주합니다. 그리고 로테이션(Rotation)입니다. 클라우드 자격 증명(Credentials), SSH 키, CI/CD 토큰, 그리고 LLM API 키를 최우선으로 교체하십시오. 이것들이 바로 TeamPCP의 주요 목표였습니다. 3월 19일에서 24일 사이에 노출된 비밀값(Secrets), 토큰, 아티팩트(Artifacts) 및 환경은 특정 CI 작업 및 러너(Runners)를 중심으로 조사해야 하며, 해당 기간 내의 비밀값과 자격 증명은 반드시 로테이션해야 합니다.
이 의식이 해결하지 못하는 것
요약하자면: "다운로드하고, 읽고, 실행하는" 습관은 실수로 잘못된 링크를 클릭하는 것은 막아주지만, 벤더(Vendor) 자체가 침해당하는 상황은 막지 못합니다. LiteLLM의 백도어(Backdoor)는 유효한 RECORD 해시를 가진 채 PyPI에 공식적으로 게시된 패키지에 포함되어 배포되었으며, Trivy는 신뢰할 수 있는 GitHub Action 내에서 오염되었습니다. 즉, 휠(Wheel) 파일의 무결성이 게시물의 선의를 보장하지는 않습니다.
따라서 솔직한 상황은 이렇습니다. 검토 의식은 "채팅창에서 한 줄 명령어를 발견하는" 일상적인 시나리오를 방어합니다. 하지만 공급망(Supply Chain)의 시스템적 리스크는 제거하지 못합니다. 그 영역에서는 버전 고정(Pinning)과 SHA 값 확인, 패키지의 연령 제한, 파이프라인으로부터의 비밀값 격리, 그리고 아웃바운드 트래픽(Outbound Traffic) 모니터링만이 작동할 뿐입니다. 이 이야기에서 저를 가장 불안하게 만드는 지점은 바로 이것입니다. 사용자의 완벽한 편집증조차 유효한 해시를 가진 1.82.8 버전의 휠(Wheel)로부터는 스스로를 구하지 못했을 것이라는 점입니다.
provod.ai가 적합하지 않은 경우
요약하자면: provod.ai는 러시아에서의 모델 접근과 결제 문제를 해결해 줄 뿐, 귀하의 파이프라인 보안 영역에 대해서는 아무것도 해결해주지 않습니다. 만약 귀하의 목표가 CI/CD를 보호하는 것이라면, 위의 의식들을 직접 구현해야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기