주의하세요, 당신의 리크루터가 사기꾼일 수도 있습니다
요약
가짜 리크루터를 통해 개발자에게 악성 코드가 담긴 기술 테스트 저장소를 전달하는 'Contagious Interview' 공격 캠페인이 보고되었습니다. 공격자는 VS Code 설정 파일이나 npm 의존성 등을 악용하여 개발자의 워크스테이션에 침투하며, SSH 키, AWS 자격 증명, 암호화폐 지갑 등 민감한 정보를 탈취합니다. 이 공격은 북한의 Lazarus 그룹과 연관된 것으로 알려져 있어 개발자들의 각별한 주의가 필요합니다.
핵심 포인트
- 기술 인터뷰 과정에서 제공되는 프라이빗 저장소를 통한 원격 코드 실행(RCE) 공격 주의
- VS Code의 tasks.json이나 npm 스크립트 등을 이용해 악성 명령어를 자동 실행하는 수법 사용
- 공격 대상은 주로 AI, Web3, 트레이딩 등 고연봉 니치 분야의 개발자
- 탈취 대상은 AWS 자격 증명, SSH 키, 브라우저 세션, 암호화폐 지갑 등 핵심 자산
- Lazarus 그룹과 연관된 'Contagious Interview' 캠페인의 일환으로 확인됨
한 리크루터가 괜찮아 보이는 AI 엔지니어 직무를 가지고 나타납니다. 회사는 충분히 그럴듯해 보입니다. 직무도 실제처럼 들립니다. 채용 과정도 일반적인 인터뷰 과정처럼 진행됩니다. 처음에는 별로 이상한 점이 없습니다. 그러다 기술 테스트(technical test)가 찾아옵니다. "이 프라이빗 저장소(private repository)를 클론(Clone)해서 로컬에서 실행해 보세요." 바로 그 순간 모든 것이 잘못되었다는 냄새가 나기 시작했습니다. 후보자는 메인 컴퓨터에서 이를 실행하기를 거부했는데, 이는 올바른 결정이었습니다. 나중에 가상 머신(virtual machine) 내부에서 안전하게 해당 저장소를 조사했습니다. 그리고 결과는 "나쁜 코드"나 "엉망인 과제", 혹은 "이상한 의존성(dependency) 문제"가 아니었습니다. 그것은 멀웨어(malware)였습니다. 저장소 내부에는 프로젝트가 열릴 때 curl | bash 명령어를 자동 실행하려는 .vscode/tasks.json 파일이 숨겨져 있었습니다. 그 명령어는 위장된 도메인으로부터 드로퍼(dropper)를 다운로드했습니다. 드로퍼는 ~/.vscode/ 경로에 또 다른 스크립트를 설치하고, 지속성(persistence)을 위해 nohup을 사용했으며, 2단계 페이로드(second stage payload)를 가져왔습니다. 그 2단계는 의도가 매우 노골적이었습니다. 암호화폐 지갑, SSH 키, AWS 자격 증명(credentials), 브라우저 세션, 환경 변수(environment variables)를 노렸으며, 명령 및 제어(command-and-control) 채널을 열었습니다. 만약 후보자가 단순히 npm start를 실행했다면, 프로젝트는 전체 process.env를 외부 서버로 전송하고 응답으로 받은 임의의 자바스크립트(JavaScript)를 실행했을 것입니다. 이것은 완전한 원격 코드 실행(remote code execution)입니다. "앗, 나쁜 패키지를 설치했네" 수준이 아닙니다. "이 저장소가 수상해 보이네" 수준도 아닙니다. 개발자 워크스테이션(workstation)의 완전한 침해입니다. 이것에는 이름이 있습니다. 이것은 고립된 사기 사건이 아닙니다. 이것은 Lazarus 생태계와 연결된 북한 국가 지원 운영자들의 소행으로 알려진, 'Contagious Interview'라고 불리는 기록된 캠페인의 일부입니다. 여러 보안 업체들은 이러한 활동의 파편들을 NICKEL ALLEY, Void Dokkaebi 및 관련 DPRK 클러스터와 같은 이름으로 추적하고 있습니다. 이 패턴은 개발자들이 이미 정상적이라고 생각하는 것, 즉 기술 인터뷰(technical interviews)를 악용하기 때문에 잔인할 정도로 효과적입니다. 가짜 리크루터가 개발자에게 연락을 취합니다.
해당 직무는 대개 암호화폐(crypto), Web3, AI, 트레이딩(trading) 또는 이와 유사한 고연봉 니치(niche) 분야입니다. 대화는 충분히 전문적으로 보입니다. 지원자는 코딩 과제(coding assignment)를 받게 됩니다. 이 과제는 GitHub, GitLab 또는 Bitbucket에 호스팅되어 있습니다. 저장소(repository)는 일반적인 앱처럼 보입니다. 그러고 나서 함정이 작동합니다. 때로는 악성코드(malware)가 npm 의존성(dependency) 안에 숨겨져 있습니다. 때로는 패키지 스크립트(package script) 안에 있습니다. 때로는 난독화된 JavaScript(obfuscated JavaScript) 안에 있습니다. 때로는 Vercel과 같은 클라우드 호스트(cloud host)에서 가져오기도 합니다. 그리고 점점 더, 개발자 도구(developer tooling) 자체에 연결되기도 합니다. 마지막 부분이 중요합니다. Microsoft는 공격이 Visual Studio Code 워크플로(workflows)를 사용하는 사례들을 기록했습니다. 피해자가 다운로드한 프로젝트를 VS Code에서 열면 일반적인 작업 영역 신뢰(Workspace Trust) 프롬프트가 나타나는데, 만약 사용자가 폴더를 신뢰하면 VS Code는 저장소의 작업 구성(task configuration)을 실행할 수 있습니다. Sophos는 .vscode/tasks.json을 통한 동일한 악용 패턴을 기록했는데, 피해자의 운영 체제(operating system)에 따라 curl 또는 wget을 사용하여 악성코드를 가져오도록 작업이 구성되어 있었습니다. 이는 위험한 동작이 항상 "앱을 실행하는 것"은 아니라는 의미입니다. 어떤 경우에는 위험한 동작이 "에디터에서 저장소를 열고 이를 신뢰하는 것"입니다. 이는 대부분의 개발자가 머릿속에 가지고 있는 위험 모델과는 매우 다른 모델입니다.
왜 개발자가 타겟인가
공격자들이 개발자를 타겟으로 삼는 이유는 우리가 특별하기 때문이 아닙니다. 그들이 개발자를 타겟으로 삼는 이유는 우리의 컴퓨터가 추악한 보물 상자이기 때문입니다. 일반적인 개발자의 노트북에는 다음과 같은 것들이 포함되어 있을 수 있습니다:
- SSH 개인 키 (SSH private keys)
- GitHub 및 GitLab 세션 (GitHub and GitLab sessions)
- AWS 자격 증명 (AWS credentials)
- GCP 또는 Azure 자격 증명 (GCP or Azure credentials)
- Kubernetes 설정 (Kubernetes configs)
- .env 파일 (.env files)
- 운영 환경과 유사한 데이터베이스 URL (production-like database URLs)
- CI/CD 토큰 (CI/CD tokens)
- 패키지 레지스트리 토큰 (package registry tokens)
- 브라우저 쿠키 (browser cookies)
- 비밀번호 관리자 세션 (password manager sessions)
- 암호화폐 지갑 확장 프로그램 (crypto wallet extensions)
- 내부 시스템용 소스 코드 (source code for private systems)
이것은 단순한 "하나의 엔드포인트(endpoint)"가 아닙니다. 이것은 기업, 클라우드 계정, 배포 시스템(deployment systems), 소스 저장소(source repositories), 그리고 때로는 고객 데이터로 진입하는 발판(jumping point)입니다.
이것이 바로 이 캠페인이 엔지니어, 특히 암호화폐(crypto), 트레이딩(trading), AI, 인프라스트럭처(infrastructure), 그리고 스타트업 생태계(startup ecosystems) 주변에서 일하는 사람들에게 집중하는 이유입니다. 리크루터는 무작위 피싱 이메일이 할 수 없는 방식으로 구직자를 압박할 수 있습니다. 피해자는 일자리를 원합니다. 피해자는 즉각적으로 반응하는 모습을 보이고 싶어 합니다. 피해자는 과제 테스트(take-home project) 수행을 거부하는 귀찮은 사람이 되고 싶어 하지 않습니다. 그러한 사회적 압박(social pressure)이 바로 취약점(exploit)입니다. 악성코드(malware)는 단지 구현 세부 사항(implementation detail)일 뿐입니다.
이제 이 캠페인은 산업화되었습니다. 엔지니어링 리더들이 주목해야 할 부분은 바로 그 규모(scale)입니다. 이것은 한 명의 영리한 운영자가 LinkedIn을 통해 수동으로 수상한 저장소(repositories)를 보내는 수준이 아닙니다. Socket은 패키지 생태계 전반에 걸쳐 진행되는 'Contagious Interview' 공급망(supply-chain) 활동을 추적해 왔으며, 이 캠페인과 연관된 수백 개의 악성 npm 패키지를 보고했습니다. 2025년의 한 파동(wave)에서만 Socket은 50,000회 이상의 다운로드 수를 기록한 338개의 악성 npm 패키지를 집계했습니다. 2025년 후반부 파동에 이르러서는 공개 보고서를 통해 535개가 훨씬 넘는 악성 npm 패키지와 총 80,000회 이상의 다운로드 수가 집계되었습니다. 캠페인 추적기에 따르면, 이후 2026년까지 npm, PyPI, Cargo, Go, 그리고 Composer 아티팩트(artifacts) 전반에서 활동이 지속되는 것으로 나타났습니다.
Trend Micro의 연구를 인용한 Dark Reading은 이 캠페인이 웜(worm)과 같은 공급망 위협으로 진화했다고 보고했습니다. 즉, 침해된 개발자 프로젝트가 악성 VS Code 작업(task) 구성을 포함할 수 있으며, 이는 다른 개발자들이 해당 저장소를 클론(clone)하고 신뢰할 때 확산됩니다. Trend Micro는 또한 2026년 3월에 750개 이상의 감염된 저장소와 500개 이상의 악성 VS Code 작업 구성을 보고했습니다. Sophos의 NICKEL ALLEY 연구는 다른 각도에서 동일한 운영자 패턴을 보여줍니다. 가짜 회사, 가짜 LinkedIn 신뢰도, 합법적인 소프트웨어 조직으로 위장한 GitHub 계정, Vercel에 호스팅된 페이로드(payloads), 그리고 Web3 또는 풀스택(full-stack) 프로젝트로 꾸며진 저장소들이 그 예입니다. 관찰된 많은 사례에서 저장소는 단지 로더(loader) 역할만 수행합니다.
실제 페이로드(payload)는 플랫폼 외부의 Vercel이나 공격자가 제어하는 인프라에 존재하며, 이로 인해 삭제(takedown) 조치나 정적 저장소 검토(static repository review)의 신뢰도가 떨어집니다. Microsoft의 보고서에는 OtterCookie, BeaverTail, Invisible Ferret, FlexibleFerret와 같은 페이로드 제품군(families)의 이름이 명시되어 있습니다. 중요한 점은 멀웨어의 브랜드명이 아닙니다. 중요한 점은 그것들이 수행하는 작업입니다: 비밀 정보 유출(exfiltrate secrets), 기기 프로파일링(profile the machine), 클립보드 내용 모니터링, 스크린샷 촬영, 추가 모듈 가져오기, 그리고 공격자가 제공한 명령 실행입니다. 이는 채용 파이프라인이 멀웨어 전달 인프라(malware delivery infrastructure)로 변질된 것입니다. 그리고 이는 수년 동안 활동해 왔습니다. Microsoft는 관련 Contagious Interview 활동을 최소 2022년 말까지 추적합니다. 다른 보고서들은 2023년 이후부터 심각한 악용 사례를 설명합니다. 이 공격은 2026년에도 여전히 활발합니다.
무엇을 훔쳐가는가
만약 이것이 당신의 실제 기기에 설치된다면, 공격자가 단순히 장난감 프로젝트(toy project)만을 훔치고 있다고 가정하지 마십시오. 그들은 다음과 같은 것들을 노리고 있다고 가정해야 합니다:
- 암호화폐 지갑 및 지갑 브라우저 확장 프로그램 (crypto wallets and wallet browser extensions)
- 시드 구문 및 개인 키 (seed phrases and private keys)
- SSH 개인 키 (SSH private keys)
- AWS 자격 증명 (AWS credentials)
- 클라우드 제공업체 설정 (cloud provider configs)
- GitHub, GitLab, Bitbucket 세션 (GitHub, GitLab, and Bitbucket sessions)
- npm 및 패키지 레지스트리 토큰 (npm and package registry tokens)
- 브라우저 세션 쿠키 (browser session cookies)
- .env 파일 (.env files)
- 클립보드 내용 (clipboard contents)
- 스크린샷 (screenshots)
- 키 입력 (keystrokes)
- 소스 코드 (source code)
- CI/CD 액세스 (CI/CD access)
또한 그들이 액세스 권한을 계속 유지할 수도 있다고 가정해야 합니다. 일부 페이로드는 원격 액세스 트로이목마(Remote Access Trojans, RAT)입니다. 일부는 명령 및 제어(command-and-control) 채널을 엽니다. 일부는 지속성(persistence)을 설치합니다. 일부는 첫 번째 단계가 가장 쉬운 검사를 통과한 후에 새로운 코드를 가져옵니다. 이것이 바로 "열어보기는 했지만 아무것도 실행하지 않았다"라는 말이 더 이상 충분한 안전장치가 될 수 없는 이유입니다. 에디터 작업(editor task)이 실행되었거나, 의존성(dependency)이 설치되었거나, 패키지 스크립트가 실행되었거나, 혹은 난독화된 로더(obfuscated loader)가 두 번째 단계(second stage)를 가져왔다면, 피해는 이미 발생했을 수 있습니다.
위험 신호 (the red flags)
만약 제가 지금 면접을 보고 있다면, 곁에 두고 확인할 체크리스트는 다음과 같습니다. 🚩 그들이 당신에게 비공개 또는 생소한 저장소(repository)를 클론(clone)하여 로컬에서 실행하도록 요청하는 경우.
🚩 해당 회사가 LinkedIn에만 존재하며, 설득력 있는 웹사이트(web presence), 고객 기반(customer footprint), 팀 페이지, 투자 이력 또는 일반적인 공개 기록이 없는 경우. 🚩 리크루터가 당신을 찾아냈지만, 공통된 인맥이 없거나, 프로필이 부실하거나, 최근에 생성된 계정인 경우. 🚩 기술 테스트가 샌드박스(sandbox) 형태의 연습 문제가 아니라, 통째로 다운로드해야 하는 전체 프로젝트인 경우. 🚩 그들이 서두르는 경우: "그냥 실행해 보세요, 금방 끝납니다", "오늘 중으로 이게 필요합니다", "설치하는 동안 화면 공유를 해주세요". 🚩 저장소(repo)에 .vscode/tasks.json, 의심스러운 워크스페이스 설정(workspace settings), postinstall 또는 preinstall 스크립트, 난독화된 의존성(obfuscated dependencies), 압축된 블롭(minified blobs), 인코딩된 URL, 또는 시작 시 네트워크 호출이 포함된 경우. 🚩 샌드박스(sandbox), VM, 브라우저 IDE 또는 회사에서 제공하는 환경 대신 당신의 개인 컴퓨터를 사용하라고 강요하는 경우. 🚩 직무가 크립토(crypto), Web3, 트레이딩(trading), AI 또는 개발자 도구(developer tooling) 분야이며, 특히 진행 과정에 비해 보상이 이상할 정도로 관대한 경우.
대조 확인 사항:
✅ 합법적인 기술 면접은 보통 CoderPad, HackerRank, LeetCode, Replit 공유 세션, GitHub Codespaces 또는 제한된 환경을 사용합니다.
✅ 합법적인 회사는 리크루터, 회사 도메인, 면접 프로세스 및 채용 담당자(hiring manager)를 확인할 수 있습니다.
✅ 합법적인 리크루터는 당신이 개인 컴퓨터에서 독점적인 미스터리 코드를 실행할 필요가 없습니다.
✅ 합법적인 엔지니어링 팀은 개발자가 과제(take-home assignment)를 검토하기 위한 더 안전한 방법을 요청한다고 해서 기분 나빠하지 않습니다. 만약 그들이 기분 나빠한다면, 그것은 유용한 신호(signal)입니다.
대신 무엇을 해야 할까요
첫 번째 방어책: 저장소를 열기 전에 스캔하세요. scanrepo.dev를 사용하세요. 이 도구는 저장소의 숨겨진 스크립트, 의심스러운 의존성 동작, 악성 패턴 및 알려진 공격 시그니처(attack signatures)를 확인합니다. 이것은 리크루터가 제공하는 코드에 대해 일상적으로 이루어져야 할 가벼운 방어 단계입니다.
그다음에는 속도를 늦추세요. 신뢰할 수 없는 저장소를 당신의 메인 VS Code 프로필에서 직접 열지 마세요. 면접 중에 프롬프트가 나타난다고 해서 폴더에 워크스페이스 신뢰(Workspace Trust)를 부여하지 마세요. 그 프롬프트는 장식이 아닙니다.
그것은 프로젝트가 수행할 수 있는 권한을 변경합니다. 만약 코드를 로컬(local)에서 반드시 검사해야 한다면, 사용자의 홈 디렉터리, SSH 키, 클라우드 자격 증명(cloud credentials), 브라우저 프로필, 비밀번호 관리자(password manager) 또는 클립보드 기록(clipboard history)에 접근할 수 없는 일회용 VM(Virtual Machine)이나 컨테이너(container)를 사용하세요. 무언가를 실행하기 전에 다음 사항을 확인하십시오:
- .vscode/tasks.json 검사
- .vscode/settings.json 검사
- package.json 검사
- postinstall, preinstall, prepare, install 스크립트 검색
- curl, wget, bash, sh, powershell, eval, Function, child_process, exec, spawn, axios, fetch 및 의심스러운 인코딩된 문자열(encoded strings) 검색
- 숨겨진 파일 및 비정상적인 디렉터리 확인
- 커밋 히스토리(commit history) 확인
- 기여자 프로필(contributor profiles) 확인
- 의존성(dependencies)이 새로운 것인지, 타이포스쿼팅(typosquatted)된 것인지, 혹은 이상할 정도로 인기가 없는지 확인
- 앱이 시작 시 외부 서버를 호출하는지 확인
VS Code의 경우, 다음 경로에서 워크스페이스 신뢰(Workspace Trust) 설정을 검토하십시오: 설정(Settings) -> 보안(Security) -> 워크스페이스 신뢰(Workspace Trust)
알 수 없는 코드를 정기적으로 검사한다면, 적대적인 리포지토리(repositories)를 위한 별도의 에디터 프로필을 만드세요. 더 좋은 방법은 VM에서 검사한 후 해당 VM을 폐기하는 것입니다. npm 프로젝트의 경우, 실제 머신에서 절대 npm install로 시작하지 마세요. 패키지 라이프사이클 스크립트(Package lifecycle scripts)는 코드 실행입니다. 악성 postinstall 스크립트가 package.json 안에 있다고 해서 덜 위험한 것은 아닙니다. AI 및 크립토(crypto) 직무의 경우 더욱 의심해야 합니다. 그곳이 공격자의 수익(return)이 가장 높은 곳이기 때문입니다.
기업이 변화해야 할 점
이것은 개인 개발자만의 문제가 아닙니다. 기업은 "이 리포지토리를 클론(clone)해서 로컬에서 실행해 보세요"를 면접 패턴으로 정상화하는 것을 중단해야 합니다. 채용 과정에서 후보자가 코드를 실행해야 한다면, 샌드박스(sandbox)를 제공하십시오. 브라우저 IDE, Codespaces 스타일의 환경, 준비된 VM 또는 제한된 러너(constrained runner)를 사용하세요. 지루하게 만드세요. 감사 가능하게(auditable) 만드세요. 안전하게 만드세요. 그리고 엔지니어를 채용하고 있다면, 후보자가 자신의 개인 머신에서 알 수 없는 코드를 실행할 필요가 없음을 명시적으로 말해 주십시오. 그 한 문장이 후보자가 느끼는 사회적 압박을 크게 줄여줄 것입니다.
보안 팀은 채용 과정 또한 공격 표면 (attack surface)으로 취급해야 합니다. 다른 곳에서 면접을 보는 개발자들은 여전히 회사의 기기를 사용하고 있을 수 있습니다. 설령 그것이 정책 위반이라 할지라도, 실제로 그런 일이 발생합니다. 만약 당신의 보호 전략이 엔지니어가 개인적인 채용 활동과 업무용 기기를 절대 섞지 않을 것이라고 가정한다면, 그 전략은 환상에 기반한 것입니다. 에디터가 실행한 셸 (shell)을 모니터링하십시오. VS Code나 Cursor가 bash, curl, wget, PowerShell, Python 또는 Node 프로세스를 생성하여 즉시 평판이 낮은 도메인과 통신하는지 주시하십시오. 일반적인 레지스트리와 관련 없는 네트워크 활동을 시작하는 패키지 설치를 찾아내십시오. .env, wallet, key, password, seed 및 자격 증명 (credential) 패턴 주변에서 광범위한 파일 시스템 열거 (filesystem enumeration)를 추적하십시오. 이 캠페인이 성공하는 이유는 "보안 교육"과 "개발자가 실제로 일하는 방식" 사이의 간극에 존재하기 때문입니다. 그 간극을 메우십시오. 당신의 직관을 믿으십시오. 이야기 속의 후보자는 가장 중요한 일을 제대로 해냈습니다. 바로 멈춘 것입니다. 그것이 진짜 교훈입니다. 모든 이상한 리크루터가 La
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기