Na toca do coelho

Nos shoppings, aeroportos e portões de universidades ainda podemos encontrar ofertas de brindes duvidosos ao fechar um pacote de assinaturas de revistas que deixaram até de ocupar lugar em salas de espera por aí. Na era da internet essas ofertas ainda existem, mas seu alcance é maior, enquanto o esforço para alcançar o potencial consumidor é significativamente menor.

Lembro que na primeira década dos anos 2000 fiquei fascinado com a possibilidade de receber itens de graça pela internet. Existiam serviços que enviavam adesivos, pulseiras e até — dizem por aí, já que espero a minha até hoje — bolas de golfe. Também foi assim que tive a minha primeira experiência com Ubuntu, através dos CDs enviados pela Cannonical. Pedi uns 10 e distribuí para alguns amigos nerds na escola que usaram também.

Quase 20 anos depois, a prática de enviar amostras grátis de produtos para consumidores que se cadastram em sites continua. O ecossistema, porém, é diferente. No lugar do boca a boca dos fóruns de antigamente, entraram os links patrocinados. No lugar do funcionário explorado e ignorado pelos caminhantes enquanto segura sua prancheta, a própria pessoa preenche e entrega, com a velocidade das teclas do computador, os próprios dados para Deus-sabe-lá-quem.

O post de hoje é sobre dados pessoais, golpes virtuais e saber a hora de parar.

Tão estranho que parece golpe

Desde 2020 até o final de 2024 atuei como cientista de dados em uma agência de notícias especializada em combater a desinformação. Durante esse tempo, analisando dados de redes sociais durante uma pandemia mundial, uma eleição presidencial e duas eleições municipais no Brasil, fui me familiarizando um pouco com as marés dos discursos e identificando tendências daqueles que praticam e se especializaram a arte do migué.

Desinformar vai além da óbvia atividade política-partidária e alcança vários espaços em nossa vida, chegando até ao campo da fraude e golpes. Golpes não são novidade, assim como também não é novidade também a desvirtuação da frase “Todo dia saem um malandro e um otário de casa. Quando se encontram, dá negócio.”. Hoje poderia ser “Todo dia um malandro e um otário se conectam na internet...

E foi pensando nisso que, em outubro de 2024, em plena campanha eleitoral em que o migué atingiu níveis nunca antes vistos, enquanto percorria a biblioteca de anúncios da Meta, percebi a chamada para um site que oferecia produtos grátis mediante cadastro. A prática é corriqueira e ocorre quase sempre da mesma maneira: o produto aparece em uma loja falsa, o usuário é levado a uma página que imita a identidade visual de uma grande operadora de pagamentos e e ele só precisa pagar o frete. É Mentira.

Primeiros passos

Com esse protocolo em mente, comecei a vasculhar a sua estrutura tentando entender quais pistas foram deixadas para trás que me permitiriam enteder como o golpe funcionava, como seria possível prová-lo e, quem sabe, identificar autoria.

O primeiro lugar que visito, na esmagadora parte dos casos, é arquivo sitemap.xml na raiz do domínio. Em outras palavras, isso significa digitar www.nomedosite.com.br/sitemap.xml na barra de endereços e conferir se consigo chegar em uma página com conteúdo. Caso exista, tenho — literalmente — em mãos um mapa do site.

Esse arquivo é utilizado, dentre outras formas, para facilitar o trabalho de indexadores de conteúdo da Internet — os robôs do Google, Bing e outros, que vasculham a internet e guardam os registros do que veem em seus bancos de dados o utilizam para agilizar seus algoritmos.

Em sites fraudulentos este é um bom ponto de partida de investigações porque podemos , por exemplo: – Encontrar dados interessantes, como os nomes de usuários registrados na plataforma – Encontrar páginas que não estão linkadas em nenhuma outra página. – Verificar datas de criação e modificação das páginas, o que permite criar uma linha do tempo da atividade do site.

Escrevi, então, rapidamente um script em Python para raspar as informações das páginas do sitemap:

import requests
from bs4 import BeautifulSoup as bs
from datetime import datetime
import pandas as pd

def extract_info_from_xml(page:str)-> None:
    r = requests.get(page)
    soup = bs(r.content, features='xml')
    # A página raiz do sitemap distribui as demais páginas em tags `sitemap`
    # O mesmo não ocorre dentro das páginas filha, que distribuem os outros endereços
    # em tags `url`
    rows = soup.find_all('sitemap')
    rows.extend(soup.find_all('url'))
    
    for row in rows:
        date = row.find('lastmod').get_text()
        date = datetime.strptime(date, '%Y-%m-%dT%H:%M:%S+00:00')
        URL = row.find('loc').get_text()
        info.append((date, URL))
        if URL.endswith('.xml'):
            extract_info_from_xml(URL)

info = []

extract_info_from_xml('https://www.endereco_do_site.com.br/sitemap.xml')
info = pd.DataFrame(info, columns=['date', 'URL'])
info.to_csv('URLs-and-dates.csv', index=False)

Esse script acessa, recursivamente, os endereços contidos no mapa de páginas e armazena o endereço e data de modificação em um pequeno arquivo CSV. Simples e útil. Finalmente podemos checar como o site foi se modificando com o tempo:

Os gráficos ilustram a quantidade de modificações ao longo do tempo. Em durante quatro anos a quantidade de modificações aumentou gradativamente, com picos em junho de 2022 e primeiro semestre de 2024.

Até aí tudo bem

Alguns detalhes até agora: – A página mais antiga, de acordo com o sitemap, é a termos-de-uso, criada em Julho de 2021. – O primeiro pico de alterações aconteceu somente em Junho de 2022, com 69 modificações num dia. e 42 no dia anterior. – A maioria dessas modificações, na verdade, ocorreram na forma de criações de páginas dentro de um diretório chamado newsletter. Essas páginas foram batizadas com o nome — presumo — das pessoas que se cadastraram para receber informações sobre o produto ou empresa. – No primeiro semestre de 2024 o site foi encontrado por um robô que, sem contexto, tentou utilizar o formulário de inscrição da newsletter como caixa de mensagens e criou vários registros por engano. Desconsiderando as pegadas desse robô, o último ano de modificações é ilustrado da seguinte maneira: – Desconsiderando a quantidade de alterações criadas pelo robô que enviou SPAMs, somente um pico de alterações aconteceu durante 2024

Por essa eu não esperava

A base de páginas tem 7994 registros, sendo que 7732 deles pertencem ao diretório de newsletters com nomes de pessoas. Em outras palavras: só 262 páginas compõem o site “de verdade”. Simplesmente por excluir essas páginas desinteressantes meu trabalho acabou de ser reduzido em 96%!

Uma das primeiras páginas que me chamou a atenção foi uma que possuía o endereço parecido com www.endereco_do_site.com.br/exporta_dados, com algumas estatísticas do produto ofertado na propaganda encontrada na biblioteca de anúncios e um grande botão escrito “Exportar”.

Detalhe importante: Os dados exportados são nada menos do que 57 mil linhas de dados pessoais de indivíduos que inseriram ali suas informações e o produto que gostariam de receber, assim como eu fiz com os meus, 20 anos atrás, para receber uma bola de golfe de graça.

Comecei a escrever funções para obfuscar os dados mais sensíveis para serem apresentados no blog...

def obfuscate_email(email:str) -> str:
    try:
        at_pos = email.index('@')
        username = email[:at_pos]
        domain = email[at_pos:]
        new_email = (
            username[:2] # aproveita os dois primeiros caracteres do username 
            + ('*' * (len(username) - 2)) # cria a quantidade necessárias de asteriscos para igualar o tamanho original do username
            + domain # junta com o dominio do e-mail novamente
            )
        return new_email
    except AttributeError as not_string:
        return None

df["Email"] = df["Email"].apply(obfuscate_email)

E quais foram os meses com mais usuários registrados...

subs_month = (
    df
    .groupby(pd.Grouper(
        key='Data',
        freq='ME')
        )
    .agg(
        unique_CPF=pd.NamedAgg(
            column='CPF',
            aggfunc='nunique'),
        unique_address=pd.NamedAgg(
            column='CEP_Numero',
            aggfunc='nunique'
        )
        )
)

subs_month = subs_month.drop(
    subs_month[
        (subs_month['unique_CPF'] == 0) &
        (subs_month['unique_address'] == 0)
    ].index
)

Além disso: – Números de telefones foram checados utilizando o Whatsapp – Endereços foram visitados no Google Maps. – Calculei quantas ocorrências se registraram com dados diferentes, mas pediram que o produto fosse enviado para o mesmo endereço – Verifiquei se os CPFs inseridos passavam por algum tipo de validação

Até que a ficha do que estava fazendo finalmente caiu: O que uma era uma vez uma suspeita de golpe se tornou uma certeza de exposição de dados pessoais sensíveis.

Não há dúvidas de que se eu entrasse em contato com alguma dessas 57 mil (!) pessoas e tentasse verificar estes dados, estaria colocando-as em situação complicada, afinal de contas estaria pedindo para elas repetirem o erro de compartilharem suas informações pessoais novamente. Eu também estaria em risco, pois poderiam me achar o comportamento suspeito — e com razão — e me denunciarem.

Neste momento a melhor decisão, na minha opinião, é entender o lugar que o analista ocupa. Se não houve permissão para obter esses dados, fechar os arquivos e conferir esporadicamente se as estatísticas do site se alteravam é a melhor opção.

Amarrando as pontas soltas

Um último passo para tirar o peso da consciência a respeito da existência do golpe foi a verificação do domínio utilizando a ferramenta whois do Registro.Br. O domínio possui final .com.br, então os dados das pessoas responsáveis estão disponíveis para consulta.

Checando o domínio dos e-mails (corporativos) associados e o Linkedin das pessoas, todas apontam ao detentor da marca de fato.

Ainda em Dezembro de 2024 uma versão resumida deste post foi enviada ao Ministério Público Federal em forma de Manifestação, incluindo os links relevantes e arquivos que comprovam o vazamento. Tão logo eu receba uma notificação de que o site e os dados das pessoas envolvidas forem tornados inacessíveis eu considerarei editar este texto e incluir informações faltantes.

Esse é um caso que ilustra. de forma clara, como o vazamento de dados pessoais não é culpa do indivíduo que abriu mão deles em troca de um benefício qualquer. Também é: – Do time de pessoas que planejou uma campanha publicitária que normalizou a ideia de abrir mão dos dados pessoais. – Como não é a primeira e única vez que este tipo de campanha aconteceu, há a necessidade de se questionar a respeito da cultura deste tipo de campanha que permanece. – Do time que construiu a plataforma de forma apressada e não praticou a higiene necessária. – Do time jurídico que resumiu a Lei Geral de Proteção de Dados (LGPD) em poucos artigos e orientou a empresa a “apenas focar em evitar multas”.

Não era e — acredito que — não foi uma fraude em nenhum momento. Foi descaso.