성인 동영상 페이지의 정보 탈취 코드 분석, 실제 유출·자산 이전은 미확인
disconinja의 11월 3일 분석은 성인 동영상 사이트 HTML이 숨은 iframe과 JavaScript를 불러와 쿠키·저장소·입력값과 브라우저에 공개된 지갑 정보를 수집하려는 구조를 확인했습니다. 가짜 MetaMask와 송금 요청 코드도 있었지만 구현 결함이 발견됐고, 관측된 HTTP 요청만으로 실제 정보 유출이나 암호화폐 이전을 입증하지 못했습니다.

본문
일본어 개인 기술 블로그 Weekend Researcher Tsurezure Diary의 공개 계정 disconinja는 11월 3일 성인 동영상 사이트 페이지에서 정보 수집을 시도하는 JavaScript 코드군을 분석한 글을 게시했습니다. Censys 스캔 결과와 확보한 HTML, 연결된 스크립트를 살핀 조사입니다. 페이지가 여러 숨은 프레임과 스크립트를 불러오고 쿠키, 저장소, 폼 입력, 키 입력, 브라우저에 공개된 암호화폐 지갑 정보를 수집하려는 구조를 확인했습니다. 가짜 MetaMask 화면을 이용한 송금·토큰 승인 코드도 있었지만, 실제 정보 유출이나 자산 이전은 입증하지 못했습니다.
페이지가 로더 역할을 하고 스크립트가 정보를 나눠 수집합니다
확보한 HTML은 일반적인 동영상 사이트 화면과 앱용 JavaScript 외에 DOM 조작 코드를 포함했습니다. 이 코드는 화면에 보이지 않도록 설정한 iframe과 외부 스크립트를 동적으로 추가합니다. 정적으로 살핀 HTML에는 비표시 iframe 3개와 외부 script 5개를 불러오는 구성이 있었습니다. 이후 페이지를 다시 관찰했을 때는 메인 페이지와 두 iframe에서 main-stealer.js, stealer-7.js, stealer-8.js, stealer-auto.js 같은 리소스도 확인됐습니다. 첫 HTML에 적힌 항목과 나중에 브라우저에서 확인한 리소스는 서로 다른 관찰 시점의 결과입니다. 일부는 JavaScript 파일을 iframe 주소로 지정했습니다. 글은 이 방식에서 실제 코드 실행이 보장되지 않는다고 설명했습니다.
로드된 코드들은 브라우저의 서로 다른 입력과 저장 위치를 대상으로 삼았습니다. 쿠키와 localStorage, sessionStorage를 읽거나 IndexedDB를 열어 데이터를 가져오려는 함수가 있었고, 폼 제출 시점이나 페이지에 입력된 값을 살피는 코드도 포함됐습니다. 여러 파일은 키 입력을 기록한 뒤 일정한 입력 횟수나 시간이 지나면 전송을 시도하도록 작성됐습니다. 코드에 기능이 적혀 있다는 사실과 해당 기능이 실제 실행됐다는 관측은 별개입니다.
암호화폐 지갑 관련 코드는 페이지에 공개된 Web3 프로바이더를 확인해 지갑 종류와 연결 상태, 공개 주소, 네트워크 정보를 얻으려 했습니다. 분석한 코드에서 지갑의 개인키를 추출하는 기능은 발견되지 않았습니다. 일부 코드는 복사·붙여넣기 문자열 가운데 영문 단어 12개 또는 24개로 된 문구를 시드 문구 후보로 골라 별도 경로로 전송하려 했습니다. 다만 BIP-39 단어 목록이나 체크섬을 검사하지 않아 일반 문장을 잘못 탐지할 수도 있습니다.
클립보드 내용을 고정된 TRON 주소로 바꾸려는 코드도 여러 파일에서 발견됐습니다. 복사한 문자열이 지갑 주소처럼 보이면 교체를 시도하는 방식입니다. 그러나 해당 이벤트 처리에는 기본 복사 동작을 취소하는 처리가 없어 실제 클립보드 변경 성공은 확인되지 않았습니다. 주소처럼 보이는 범위가 넓은 문자열 조건을 쓰는 샘플도 있어 지갑 주소가 아닌 텍스트를 대상으로 삼을 가능성도 있습니다.
지갑 전송 코드는 있었지만 자산 이동은 확인되지 않았습니다
stealer-auto.js는 다른 정보 수집 스크립트와 달리 암호화폐를 옮기려는 요청을 담았습니다. 코드가 의도한 순서는 가짜 MetaMask 확인창을 페이지에 표시하고, 지갑 잔액을 읽은 뒤 네이티브 자산 송금과 ERC-20 토큰 승인 요청을 보내는 것입니다. 하지만 코드에 적힌 수신 주소는 유효한 EVM 주소가 아닌 자리표시자였고, 가스 값 형식과 승인 요청 인자에도 오류가 있었습니다. 승인 요청만으로 토큰을 옮기는 후속 처리도 없었습니다. 글은 해당 파일에서 구문 오류도 확인했습니다. 분석으로 드러난 것은 자산 이동을 노린 코드와 그 결함이며, 실제 지갑 자산 이전은 관측되지 않았습니다.
다른 파일에서도 실행을 막거나 일부 기능을 중단시킬 수 있는 결함이 발견됐습니다. 예를 들어 stealer-7.js는 정의되지 않은 변수를 참조해 수집 절차가 중단될 수 있습니다. 다만 오류가 발생하기 전에 등록한 통신 감시나 이벤트 리스너는 남을 가능성이 있다고 글은 설명합니다. stealer-8.js에도 구문 오류가 있어 코드에 적힌 모든 수집·전송 기능이 실행됐다고 볼 근거는 없습니다.
브라우저 관찰에서 확인한 네트워크 정황은 관련 JavaScript 리소스가 개발자 도구에 나타난 점과 POST /rec/batch 요청에 HTTP 200 응답이 돌아온 점입니다. 조사자는 이 요청을 만든 코드와 전송 본문을 특정하지 못했습니다. 따라서 해당 요청이 앞서 분석한 수집 스크립트의 결과인지 알 수 없으며, 민감 정보가 전송됐다는 사실도 확인되지 않았습니다. 글은 피해자 수와 사이트에 코드가 들어간 경위, 운영자 신원도 확인하지 못했다고 밝혔습니다.
자료: Weekend Researcher Tsurezure Diary / 정리·해설: Trawling