서론
개발자 채용 피싱은 더 이상 이력서 첨부파일이나 단순 링크 클릭에만 머물지 않는다. 공격자는 채용 담당자나 기술 면접관으로 위장해 코딩 테스트 저장소를 전달하고, 지원자가 직접 의존성을 설치하고 프로젝트를 실행하도록 유도한다. 이 과정은 정상적인 채용 절차처럼 보이기 때문에 개발자가 경계를 낮추기 쉽다.
이번 업무카드의 출발점은 “Fake Coding Tests Deliver OtterCookie-Aligned Malware Hidden in SVG Flag Images”라는 보도다. 원문 전문은 직접 확인되지 않았으므로, SVG 플래그 이미지 은닉 사례는 보조 정황으로 다룬다. 대신 Unit 42와 ReversingLabs가 공개한 북한 연계 개발자 대상 채용 피싱, 악성 Python·JavaScript 프로젝트, PyPI·npm 패키지 악용 사례를 중심으로 대응 포인트를 정리한다.
핵심은 단순하다. 낯선 채용 과제는 “코드 리뷰 전 실행 금지” 대상이며, 이미지처럼 보이는 SVG도 실행 가능한 XML 기반 리소스로 점검해야 한다.
본론
공격 흐름: 채용 제안에서 개발자 단말 침해까지
관찰된 캠페인은 대체로 다음 흐름을 따른다.
- LinkedIn, 이메일, 메신저에서 채용 담당자나 헤드헌터로 접근한다.
- PDF 직무 설명서, 코딩 테스트 안내문, GitHub 저장소 링크를 전달한다.
- 지원자에게 로컬 환경에서 프로젝트를 설치하고 실행하라고 요청한다.
npm install,pip install -r requirements.txt,python app.py,npm start같은 익숙한 개발 절차를 감염 지점으로 사용한다.- 악성 로더가 브라우저 세션, SSH 키, 클라우드 자격 증명, 암호화폐 지갑, 소스코드 접근 토큰을 수집한다.
- 공격자는 확보한 토큰과 키를 이용해 개인 계정이나 기업 개발 환경으로 이동한다.
Unit 42가 분석한 Slow Pisces/Jade Sleet 캠페인에서는 채용 코딩 챌린지로 위장한 Python·JavaScript 프로젝트가 사용됐다. Python 체인에서는 원격 응답이 application/yaml일 때 PyYAML의 위험한 역직렬화 흐름을 통해 페이로드 실행으로 이어질 수 있었다. JavaScript 체인에서는 정상 API 호출과 공격자 제어 URL을 섞고, 원격 응답을 템플릿 렌더링 경로에 넣는 방식이 관찰됐다.
ReversingLabs가 다룬 VMConnect 및 ZetaNile 계열 사례도 같은 문제를 보여준다. 공격자는 정상 오픈소스 패키지처럼 보이는 PyPI·npm 패키지를 배치하거나 채용 과제 저장소의 의존성에 섞어 넣는다. 개발자는 과제를 풀기 위해 설치 명령을 실행하고, 이 단계에서 개발 환경의 민감 정보가 노출될 수 있다.
왜 SVG가 위험한 점검 대상인가
SVG는 이미지 파일처럼 다뤄지지만 내부 구조는 XML이다. 단순한 벡터 그래픽뿐 아니라 스크립트, 이벤트 핸들러, 외부 리소스 참조, foreignObject, data URI를 포함할 수 있다. 브라우저, 문서 뷰어, README 렌더러, 디자인 도구에서 어떻게 처리되느냐에 따라 위험도가 달라진다.
채용 과제 저장소에서 SVG는 아이콘, 국기 이미지, 로고, 상태 배지, README 시각 자료처럼 자연스럽게 포함될 수 있다. “그냥 이미지”라고 보고 넘어가면 내부의 난독화된 JavaScript, 외부 URL 호출, HTML 삽입 구조를 놓칠 수 있다.
특히 다음 패턴은 점검 대상이다.
<script>태그,onload=,onclick=같은 이벤트 핸들러href="javascript:"또는 JavaScript 실행을 유도하는 링크<foreignObject>안의 HTML, iframe, form 요소data:text/html,data:application/javascript, 긴 Base64 data URI<image href=...>,<use href=...>, CSSurl(...)형태의 외부 참조- 국기·아이콘 SVG 내부의 난독화 문자열, 원격 URL, 폼 제출 구조
SVG 자체가 항상 악성이라는 뜻은 아니다. 다만 채용 과제처럼 출처 신뢰가 약한 저장소에서는 코드 파일과 같은 수준으로 열어 보고 검사해야 한다.
영향 범위
개발자 단말은 일반 업무 단말보다 더 많은 권한과 비밀 정보를 갖고 있다. 공격자가 코딩 테스트를 통해 단말을 장악하면 피해는 개인 계정 탈취에서 조직 공급망 침해로 확대될 수 있다.
개인 개발자에게는 브라우저 세션, SSH 키, 암호화폐 지갑, 개인 클라우드 키 유출 위험이 있다. 기업 개발자에게는 GitHub·GitLab 토큰, CI/CD 시크릿, AWS·GCP 자격 증명, Kubernetes 설정, 내부 저장소 접근 권한이 노출될 수 있다. macOS 개발자도 예외가 아니다. 공개 분석 사례에서는 login.keychain-db, SSH 키, 클라우드 설정 파일 접근 시도가 언급됐다.
조직 관점에서는 소스코드 유출, 빌드 파이프라인 오염, 내부 패키지 저장소 접근, 공급망 공격으로 이어질 수 있다. 채용 피싱을 개인 보안 문제로만 다루면 대응 범위가 부족하다.
대응방안
1단계: 과제 실행 전 신뢰성 확인
채용 과제를 받으면 먼저 사람과 회사를 확인한다.
- 채용 담당자 이메일 도메인이 회사 공식 도메인과 일치하는지 확인한다.
- LinkedIn 계정의 생성 시점, 활동 이력, 회사 페이지 연결 여부를 확인한다.
- 회사 공식 채용 페이지에 같은 공고가 있는지 대조한다.
- 과제 제출 방식이 공식 도메인, 공식 ATS, 회사 소유 저장소와 연결되는지 확인한다.
- 급하게 설치·실행을 요구하거나 오류 해결 명령어를 복사해 실행하라고 하면 고위험으로 분류한다.
2단계: 저장소를 실행하기 전에 먼저 읽기
낯선 저장소는 실행보다 정적 점검이 먼저다. 최소한 아래 파일은 열어봐야 한다.
| 구분 | 점검 항목 | 확인 포인트 |
|---|---|---|
| Node.js | package.json |
preinstall, postinstall, prepare, 난독화 스크립트, child_process 사용 여부 |
| Python | requirements.txt, setup.py, pyproject.toml |
낯선 패키지, typosquatting 의심 이름, 설치 중 실행 코드 |
| 컨테이너 | Dockerfile, docker-compose.yml |
호스트 볼륨 마운트, SSH·클라우드 키 접근, 외부 다운로드 |
| CI/CD | .github/workflows/* |
토큰 출력, 외부 스크립트 다운로드, 의심스러운 secret 접근 |
| 리소스 | *.svg, README 이미지 |
스크립트, 이벤트 핸들러, 외부 URL, data URI |
Python 코드에서는 원격 응답을 yaml.load()에 직접 넣는 흐름, pickle, marshal, eval, exec, ctypes, subprocess, os.system 사용을 주의 깊게 본다. YAML 처리가 필요하다면 safe_load()만 허용하는 것이 기본이다.
JavaScript 코드에서는 eval, Function, child_process, 난독화된 Base64 문자열, 템플릿 엔진에 원격 응답을 직접 전달하는 흐름을 점검한다. EJS 같은 템플릿 엔진의 렌더링 경로에 외부 응답이 들어가면 코드 실행 위험으로 이어질 수 있다.
3단계: 격리 환경에서만 실행
채용 과제는 업무용 기본 단말에서 바로 실행하지 않는다. 다음 원칙을 적용한다.
- 일회용 VM이나 컨테이너에서 실행한다.
- 개인 GitHub, 회사 GitHub, 클라우드 계정에 로그인된 브라우저 세션과 분리한다.
~/.ssh,~/.aws,~/.gcp,~/.kube, 암호화폐 지갑 경로를 마운트하지 않는다.- 네트워크는 기본 차단 또는 제한 허용으로 시작하고, 필요한 도메인만 허용한다.
- 실행 전후 파일 생성, 프로세스 실행, 외부 연결 로그를 남긴다.
- 과제 완료 후 환경을 폐기한다.
컨테이너를 사용할 때도 호스트 홈 디렉터리나 SSH 키 폴더를 편의상 마운트하지 않아야 한다. 격리 실행의 목적은 “실행해도 잃을 것이 없는 환경”을 만드는 데 있다.
4단계: 탐지와 모니터링 포인트 만들기
보안팀은 개발자 단말과 코드 저장소에서 다음 신호를 모니터링할 수 있다.
- 채용 과제 저장소 실행 직후
~/.ssh,~/.aws,~/.kube, GCP 설정, macOS keychain 관련 파일 접근 package.json설치 스크립트에서 외부 스크립트 다운로드 또는 쉘 실행- Python 프로젝트에서 원격 YAML 응답 처리,
!!python/object/apply문자열 사용 - Node.js 프로젝트에서
child_process,eval,Function호출과 난독화 문자열 결합 - SVG 파일 안의
<script>,foreignObject, 외부 URL, 긴 data URI - 개발 도구 프로세스가 평소와 다른 국가·호스팅 사업자·신규 도메인으로 연결
수집 초안에 포함된 Unit 42 IOC도 탐지 참고값으로 둘 수 있다.
Domain: en.stockslab[.]org
URL: hxxps://en.stockslab[.]org/symbols/sp500
SHA256:
47e997b85ed3f51d2b1d37a6a61ae72185d9ceaf519e2fdb53bf7e761b7bc08f
937c533bddb8bbcd908b62f2bf48e5bc11160505df20fea91d9600d999eafa79
e89bf606fbed8f68127934758726bbb5e68e751427f3bcad3ddf883cb2b50fc7
IOC는 캠페인별로 빠르게 바뀐다. 따라서 해시와 도메인만으로 탐지하기보다 “채용 과제 실행 직후 민감 개발자 자산 접근”이라는 행위 기반 규칙을 함께 둬야 한다.
5단계: 조직 채용 프로세스에 보안 통제 추가
조직은 지원자와 내부 개발자를 모두 보호하는 방향으로 채용 절차를 정비해야 한다.
- 회사 공식 도메인과 공식 채용 플랫폼에서만 과제 안내를 발송한다.
- 과제 저장소는 회사 조직 계정 소유로 제공하고, 개인 계정 저장소 사용을 피한다.
- 지원자에게 로컬 설치가 필요한 과제를 줄 때는 의존성 목록과 실행 범위를 명확히 고지한다.
- 내부 개발자가 외부 채용 과제를 수행할 경우 회사 단말 사용 금지 또는 격리 환경 사용 원칙을 둔다.
- 보안 교육에 “과제 파일 실행 전 저장소 구조와 설치 스크립트 점검”을 포함한다.
- 보안팀은 개발자 대상 채용 피싱 신고 채널을 운영하고, 의심 저장소를 빠르게 분석할 수 있게 한다.
결론
SVG 위장 악성코드와 가짜 코딩 테스트는 모두 개발자의 신뢰 습관을 노린다. 파일 확장자가 이미지처럼 보이거나 저장소가 그럴듯하게 구성돼 있어도, 출처가 약한 채용 과제는 실행 가능한 코드 묶음으로 봐야 한다.
개발자는 실행 전 저장소와 SVG를 먼저 읽고, 의존성 설치와 프로젝트 실행은 일회용 격리 환경에서 수행해야 한다. 조직은 채용 피싱을 개인 주의에만 맡기지 말고, 개발자 단말 보호·토큰 관리·격리 실행·신고 절차를 함께 운영해야 한다. 코딩 테스트는 역량 검증 도구가 될 수 있지만, 공격자에게는 개발 환경으로 들어가는 설득력 있는 입구가 될 수 있다.
참고자료
- Unit 42: Slow Pisces Targets Developers With Coding Challenges and Introduces New Customized Python Malware
https://unit42.paloaltonetworks.com/slow-pisces-new-custom-malware/ - ReversingLabs: Fake recruiter coding tests target devs with malicious Python packages
https://www.reversinglabs.com/blog/fake-recruiter-coding-tests-target-devs-with-malicious-python-packages - ReversingLabs: ZetaNile: Open source software trojans from North Korea
https://www.reversinglabs.com/blog/zetanile-open-source-software-trojans-from-north-korea - ReversingLabs: VMConnect: Malicious PyPI packages imitate popular open source modules
https://www.reversinglabs.com/blog/vmconnect-malicious-pypi-packages-imitate-popular-open-source-modules
본 콘텐츠는 AI 기술로 작성된 분석 리포트를 포함하고 있습니다. 내용 중 사실과 다르거나 보완이 필요한 정보를 발견하셨으면 댓글을 통해 의견을 부탁드립니다. 여러분의 피드백은 더 정확한 보안 정보 공유에 큰 도움이 됩니다.
댓글 (0)
댓글을 작성하려면 로그인이 필요합니다.
로그인아직 댓글이 없습니다.
첫 번째 댓글을 작성해보세요!