1P by GN⁺ 3일전 | ★ favorite | 댓글 1개
  • 구글 계정 찾기 폼을 우회하여 특정 사용자 이름과 연결된 전화번호가 존재하는지 확인 가능함
  • 자바스크립트 비활성화 환경에서도 봇가드(BotGuard) 토큰을 의도적으로 삽입하여, IP 제한을 우회하는 공격 방식 구현 가능함
  • 네덜란드 등 일부 국가에서는 전화번호 포맷 특성상 1백만 개 미만 조합이 존재하여 현실적으로 프록시와 IPv6 회전을 통해 대규모 대입 가능함
  • 구글 계정의 디스플레이 네임을 Looker Studio를 이용해 피해자 임의 동작 없이 손쉽게 노출 가능함
  • 이 취약점은 구글에 보고 및 패치 완료되었으며, 실제 공격 체인은 자동화로 매우 빠른 시간 내에 전화번호를 확인 가능함

개요

이 글은 구글 계정의 전화번호를 무차별 대입(브루트포스) 공격으로 알아내는 방법, 그 과정, 그리고 방어 측의 대응까지 자세히 다루는 실제 사례임. 일반적으로 계정 찾기/복구 폼은 Javascript 환경과 봇 방지 체계를 이용하여 남용을 차단함. 그러나, JS가 꺼진 환경+특정 패턴으로는 이 체계를 우회할 수 있음을 증명하고 있음.

조사 배경 및 방식

  • 계정 사용자명을 찾는 구글 폼이 자바스크립트 없이 동작하는 점을 발견함
  • 폼은 특정 이름(Display Name)과 연동된 전화번호의 존재 여부를 HTTP 요청 2개로 확인함
    • 1차 요청 : 전화번호 기반으로 ess 값(세션 토큰) 획득
    • 2차 요청 : ess와 이름(GivenName/FamilyName) 파라미터로 계정 존재 여부 판별
  • 계정이 존재하면 usernamerecovery/challenge 리다이렉트, 없으면 noaccountsfound 리다이렉트로 응답

IP 제한 우회(프록시, IPv6 활용)

  • 초기에는 IP별 레이트 리밋과 캡챠로 무차별 대입이 불가했음
  • 네덜란드 모바일 번호의 경우 100만개 조합(앞자리가 정해져 있음)으로 프록시 사용 시 현실적이고,
  • AWS/Vultr 등 클라우드의 /64 IPv6 블록을 활용해 요청마다 다른 주소로 회전 가능, 서버도 IPv6 지원함

BotGuard 토큰 우회

  • JS 폼에서는 봇가드(BotGuard) 토큰이 필요함
  • No-JS 폼에서 bgresponse=js_disabled 파라미터 대신 JS 폼에서 수집한 토큰을 삽입하면 불제한 제출 가능
  • 멀티스레드 툴을 제작, 대량 전화번호를 입력해 신속하게 존재 계정 탐지 가능

오탐 거르기(필터링)

  • 동일 이름/번호 뒤 2자리 조건으로 여러 명이 걸릴 가능성 있음
  • 임의의 랜덤 성(last name)을 입력해 다시 테스트함으로써 오탐 여부를 자동으로 필터링하는 로직 추가

국가별 전화번호 포맷 및 네임 정보 수집

  • 복구 폼은 전화번호 마스킹 포맷만을 일부 제공함
  • 각국 전화번호 패턴(national format)은 구글의 libphonenumbers 정보 조사로 파악 가능
  • 피해자의 디스플레이 네임은 Looker Studio에서 소유권 변경 기능을 악용해 사용자 동작 없이 확인 가능

최적화 및 자동화

  • libphonenumbers로 각국 Prefix/길이/유효성 검증 규칙 딕셔너리 생성
  • Go 기반 chromedp로 BotGuard 토큰 자동 발급 API 제작, 실제 공격시 자동화 가능

실제 공격 절차

  1. Looker Studio 소유권 이전으로 피해자 이름(디스플레이 네임) 획득
  2. “비밀번호 찾기” 흐름에서 해당 이메일의 전화번호 일부 마스킹 수집
  3. gpb 툴을 통해 이름, 마스킹, 국가 코드 기반으로 대입 공격 실행

시간 및 효율성

  • 16 vcpu, 3000 스레드 서버 기준, 1초에 약 4만건 체크
  • 국가별 번호 조합/힌트 길이에 따라 미국(20분), 영국(4분), 네덜란드(15초), 싱가포르(5초)면 충분
  • 타 서비스에서 풀힌트 제공시(예: PayPal) 시간 더욱 단축

구글 및 패치 타임라인

  • 2025.4.14 : 구글에 리포트, 4.25 패널서 감사 표시
  • 2025.5 중 : $5,000 버그바운티 지급
  • 2025.5 : No-JS 폼 점진적 중단 및 대응 조치 적용
  • 2025.6.9 : 공식 취약점 공개

결론

이 사례는 계정 복구 흐름, 전화번호 마스킹, 디스플레이 네임 등 여러 정보의 조합만으로 대규모 자동화 공격이 가능함을 보여줌. 구글은 절차 내 취약점 보완 및 관련 폼을 폐쇄함으로써 대응을 완료함.

문의는 신호/이메일(원문 참고)로 가능함

Hacker News 의견
  • 이 글에서 흥미로운 점은, 대부분의 호스팅 제공업체나 ISP가 최소한 하나의 /64 IPv6 블록을 제공한다는 사실임에도 불구하고, 여전히 대부분의 레이트 리밋이나 IP 차단은 단일 IP에 대해 적용된다는 점임. IPv6 환경에서는 전체 /64 블록을 기준으로 레이트 리밋이나 차단이 이뤄져야 한다고 생각함

    • 이런 문제를 관리해야 할 책임이 있거나 그걸로 돈을 벌고 있는 기업들조차 IPv6 관리에 있어 엉뚱한 대응을 하는 모습을 자주 봄. 내가 일하는 회사는 유명 CDN 서비스를 쓰고 있는데, 같은 /64 블록 내에서 접속해도 '이상한 IP에서 접속함' 같은 터무니없는 보안 알림을 받는 경우가 있음

    • IPv6 등장 이후로 기존 IP 차단 방식이 크게 무력화됐다고 생각함. 일반 가정용 인터넷 사용자라도 DHCPv6 Prefix Delegation으로 /56이나 /48 블록을 자동으로 받을 수 있음. 예를 들어 나는 Comcast를 통해 /56을 받았고, 이는 최대 65536개의 /64 블록으로 쪼갤 수 있음. IPv6에서 효과적인 IP 필터링을 하려면 기존 단일 IP 기반을 /64로 단순 교체하는 걸로는 부족함

    • /64 블록으로 레이트 리밋을 걸어도 충분하지 않을 수 있음. /48 블록을 받는 것도 너무 쉬움. 최적의 제어를 위해선 ASN별로 분류하고, 각 사업자가 어떻게 IP를 분배하는지까지 살펴 granularity를 조정하는 고민이 필요함

    • IPv6에서 /64 단위 레이트 리밋은 이미 업계에서 잘 알려져 있고, Google도 타 서비스에 적용하고 있음. 이건 IPv6 도입 시 제대로 기존 정책을 업데이트하지 않은 결과라고 판단함

    • BuyVM 같은 저가 호스팅 업체도 가장 저렴한 상품에 /48 단위 주소를 제공함($2/월, 현재는 $7/월만 재고 있음). 그래서 수상한 운영자들이 애용하는 경향이 있음

  • 예전에 페이스북에서 특정인의 전화번호를 찾으려고 비슷한 방법을 시도함. 비밀번호 재설정 과정에서 페이스북이 전화번호 대부분을 보여주길래, 그 숫자를 vcard 파일로 정리해서 내 폰에 불러온 뒤 사진으로 대조함. 이 방식이 예상 외로 효과적이었음

    • 구글 프로필 사진이나 구글 앱에도 비슷한 허점이 있음. 예를 들어 구글 지도 리뷰에 John Smith라고 뜨면, 여러 이메일 변형(johnsmith@gmail.com, smithjohn@gmail.com 등)을 행아웃에 추가하고 프로필 사진을 확인해서 동일인을 추적할 수 있음

    • 이런 이유로 내 실전화번호는 절대 입력하지 않음. 서비스 운영에 꼭 필요하지도 않으니까

  • 한 사람이 장기간 동안 4만 건의 요청을 초당 서버에 날려도 리소스가 크게 치솟거나 경보가 울릴 일이 없었다는 점이 인상적임

    • 실제 알람이 울렸을 가능성도 있는데, 행동이 금방 중단되거나 상황이 빠르게 복구되어 엔지니어가 대시보드에 접근할 때쯤이면 이미 정상화됐을 수도 있음. 4만 QPS는 Focus나 Google API의 트래픽 규모에선 크게 튀지 않고, 다양한 IP 및 IPv6 /64 블록으로 분산되면 눈에 띄지 않게 넘어가는 경우도 있음. 이번 사례의 핵심은 모니터링이 아니라 JS 비활성화 플로우(이전 JS 활성화 플로우에서 빌린 토큰 사용)에 전혀 레이트 리밋이 없었다는 점이라고 봄

    • 혹시 봇넷을 썼을까 생각도 드는데, 요청마다 IP를 달리한 것 같기도 함

  • 이런 유형의 버그 바운티는 보상 금액이 터무니없이 적은 편임. 안타까움

    • 보상을 자꾸 줄이면 결과적으론 자기 발등 찍는 격임

    • 이런 보안 이슈에 10만 달러 미만 지급은 정말 초라함

  • 레거시 웹페이지를 유지·관리하는 일이 엄청난 부담임을 자주 느낌. 몇십 년 된 코드와 페이지까지 계속 유지해야 하는 사이트가 많고, 모든 조합을 테스트하는 것도 사실상 불가능함. Gmail 설정 안쪽을 파고들다 보면 아직도 2004년 스타일의 오래된 팝업이 뜨는 걸 직접 볼 수 있음

    • 버그 바운티 프로그램은 아주 효율적인 비용 활용 같음. 수천 달러만 들여도 극한의 엣지 케이스를 찾아주는 자발적 인력을 동원할 수 있음. 사내 인력을 쓴다면 훨씬 더 큰 비용이 들었을 거라 생각함

    • 이게 바로 기업들이 예전 서비스와 제품을 공격적으로 폐기하려 하는 가장 큰 이유임. “그냥 그대로 두면 되는 거 아니냐”라는 질문에 대한 답은, 결국 모든 레거시 서비스가 보안 구멍이 되기 때문임. 진짜 안전한 코드는 아예 없는 코드뿐임

    • 페이스북의 “톡” 기능 같은 걸 누가 담당하고 있는지 늘 궁금함

    • 대형 기업 내부에도 비슷한 레거시 인프라가 계속 굴러감. 예를 들어 내 친구는 글로벌 대기업 내에서 내부 링크 단축 앱을 유지보수하는데, 거의 사용량 폭주에도 노드 버전 업데이트 등 매우 단순한 이유로 매번 한두 건 티켓만 들어옴. 모니터링조차 정상 동작하지 않아도 버그 리포트가 드물 정도임

    • 최근에 나도 구글에서 예전(~2013년) Catull 로고가 뜨는 페이지를 만난 적이 있음

  • “2025-05-15 – 패널이 $1,337 + 스웨그 지급. 근거: 익스플로잇 가능성 낮음(lol)”이라는 내용을 언급했는데, 실제로는 익스플로잇 가능성이 매우 높다고 생각함. 노출되는 전화번호 당사자는 많지 않을 수 있지만, 필요만 하면 사설탐정, 범죄자, 조사관 등 누구나 실제로 이 취약점을 활용할 거라 확신함

  • 비밀번호 찾기 플로우에서 전화번호 일부를 힌트로 주는 것이 실제로는 보안 위험임을 이번에 새롭게 깨달음. 만약 여러 서비스가 각기 다른 순서로 마스킹된 전화번호/이메일 힌트를 제공한다면 위험도가 더 커짐

    • 위로가 될지 모르겠지만, 2FA 등 각종 이유로 수백/수천 개 서비스가 이미 내 전화번호를 수집했고, 동의 여부와 무관하게 상당수가 이미 유출됨. 실명-이메일-전화번호 조합은 거의 무조건 공개 데이터에 덤프된 상태임

    • 이런 정보들을 찾아주는 텔레그램 봇도 존재함. 이런 식으로 브루트포스 취약점이 드러나면 자동화 도구를 쓰던 이용자들도 불쾌함을 느끼는 듯함(EoG 봇이 대표적임)

    • 이런 개인 정보를 자동으로 모아주는 유료 서비스들도 이미 오래전부터 존재함. 이메일, 전화번호 등 다양한 정보가 여러 소스에서 쌓이고, 전 세계적으로 유인이 충분해 적극적으로 서비스 보안 허점을 공략함. 결국엔 대량 유출과 연결되는 구조임

    • 과거엔 한 회사 고객센터에 카드 뒷자리 4개를 물어보고, 그걸로 다른 회사 본인 인증을 풀어낸 소셜 엔지니어링 사례도 있었음

    • 나도 대학 시절, 신용카드도 이런 식으로 정보를 획득할 수 있다는 보안 연구자 발표를 들은 기억이 있음

  • 2025년, 2023년, 2021년에도 “방지할 방법 없다”는 기사와 대규모 데이터 유출이 반복됨. 2025년 버전, 2023년 버전, 2021년 버전이 계속 반복됨. 어떤 버전이 더 웃긴지 고민함

  • 이번 사례는 매우 창의적이고 멋지다고 생각함. Brutecat이 또 한 건 했음

  • Google이 이제 진짜 유령선처럼 느껴짐. $5,000 버그 바운티는 모욕 수준이고, 이런 소액으로 시작했다는 자체가 Google이 사용자 데이터 보호에 진지하지 않다는 결정적 증거 같음

    • 버그 바운티 참여는 강제사항이 아님. 보상이 마음에 안 들면 그냥 안 하면 됨. 결국 이 프로그램들도 지속 가능한 모델 한계가 있음