Como contornei a proibição da API de mensagens através da documentação do Vkontakte

Olá a toda a comunidade Habro. Para mim, este primeiro artigo é escrito sob uma certa euforia; portanto, não julgue este artigo estritamente para a parte literária. Mas bem, menos palavras e vamos direto ao assunto.

Como tudo começou


Todos sabemos que o VC tem uma API e tenho certeza de que a maioria das pessoas tentou usá-la para seus próprios fins. Pessoalmente, tenho muitos projetos relacionados a ele: partes de 5 bots poderosos, compilando conjuntos de dados em larga escala de postagens de grupo etc. E não é de surpreender que meus amigos tenham me pedido algumas vezes para baixar músicas dos anexos do diálogo, fotos ou salvar o texto da correspondência com alguma pessoa em um arquivo separado.

Mas uma vez que chegou, e a partir desse momento a implementação de solicitações tão pequenas deixou de ser uma tarefa trivial:

imagem

e assim, alguns dias atrás, para me livrar desse problema de uma vez por todas, decidi escrever meu wrapper por meio de solicitações http, fingindo ser um usuário comum, para que tenha a mesma ferramenta poderosa que a API oficial da seção de mensagens.

Vamos ao que interessa


Então, eu comecei com autorização. Armado com o sniffer https e o Firefox, pude passar por todas as "etapas" da autorização e obter os cookies finais. A partir de agora, resta apenas entender como as consultas foram feitas. Verificou-se que a maioria dos dados é recebida por uma solicitação POST de https://vk.com/wkview.php , apenas os parâmetros para diferentes situações mudam a cada vez. Consegui escrever funções para bombear absolutamente todos os tipos de investimentos, mas não entraremos em detalhes, porque em um momento tudo mudou drasticamente.
Link para o arquivo para receber cookies de autorização (eu o escrevi apenas para autenticação de dois fatores, pois custa a maioria das pessoas)

Descoberta inesperada


Eu estava trabalhando em um laptop quando um amigo me procurou e perguntou o que eu estava fazendo. Como não consegui explicar rapidamente a ele todo o problema, abri a documentação oficial na seção de mensagens e fiquei surpreso ao ver o que havia na descrição principal desses métodos "proibidos":

imagem

Não, você me entendeu corretamente, não sou o primeiro apenas veja esta oportunidade. Usei-o muitas vezes com outros métodos, mas não conseguia nem pensar que a função "solicitação de amostra" permanecesse com os métodos da seção de mensagens. E ainda mais forte foi a minha surpresa quando subi no tráfego. Essas eram apenas solicitações de API comuns, apenas no site, que apenas nomes de parâmetros ligeiramente diferentes no formulário da web e tinham algum tipo de hash-ID.

imagem

Em alguns minutos, percebi que o hash-ID é apenas uma string localizada no atributo data-hash da tag button, e depois de alguns minutos eu já estava tentando implementar a emulação de "solicitações de teste" e não acreditava plenamente que funcionaria. Afinal, com certeza essas solicitações têm algum tipo de limite no número ou algo assim. Mas qual foi a minha surpresa quando este roteiro de 30 linhas (sem contar o recebimento de cookies), que estava escrito de joelhos, foi capaz de extrair mil e quinhentas imagens dos anexos do diálogo em 4 minutos.

imagem

Eu aplico o código usado
import requests, pickle, re, json

with open('cookies_vk_auth.pickle', 'rb') as handle:
    cookies_final = pickle.load(handle)

session = requests.Session()
peer_id = int(input('  :  '))

response = session.get(f'https://vk.com/dev/messages.getHistoryAttachments', cookies=cookies_final)
hash_data =  re.findall(r'data-hash="(\S*)"', response.text)[0]

session = requests.Session()
response = session.post(f'https://vk.com/dev',
            data=f'act=a_run_method&al=1&hash={hash_data}&method=messages.getHistoryAttachments&param_count=20&param_max_forwards_level=45&param_media_type=photo&param_peer_id={peer_id}&param_photo_sizes=0&param_preserve_order=0&param_v=5.103', cookies=cookies_final)

count=20

for i in range(200):
    response_json = json.loads(json.loads(response.text[4:])['payload'][1][0])['response']['items']

    for photo in response_json:
        ph = photo['attachment']['photo']['sizes'][-1]['url']
        r = session.get(ph, timeout=10)
        
        if r.status_code == 200:
            with open(f'D://dev/'+str(ph.split('/')[-1]), 'wb') as f:
                f.write(r.content)

    m_id = photo['message_id']
    response = session.post(f'https://vk.com/dev',
            data=f'act=a_run_method&al=1&hash={hash_data}&method=messages.getHistoryAttachments&param_count=20&param_start_from={m_id}&param_max_forwards_level=45&param_media_type=photo&param_peer_id={peer_id}&param_photo_sizes=0&param_preserve_order=0&param_v=5.103', cookies=cookies_final)


Fiquei tão impressionado que, neste momento, decidi me acalmar e tentar implementar outro método (de repente, eu estava enganado). Peguei o método History e o resultado foi semelhante. Só tive que definir um atraso de 0,1 segundos para que o servidor não desse um erro sobre muitas solicitações. (Se alguém repetir, lembre-se de que, ao alterar o método, você também precisará alterar o URL da documentação, de onde vêm os dados hash). Ou seja, esse método realmente tornou possível acessar a seção de mensagens através da documentação oficial, usando apenas a senha e o login do usuário. Por questões de confiabilidade, tentei executar as mesmas etapas em outra conta e obtive o mesmo resultado.

Resumir


Acho que todo mundo já percebeu que isso é uma violação da proteção de nossos dados pessoais, que está na documentação há um ano e não se sabe quantas pessoas já o usaram. Além disso, essa lacuna é muito grande e precisa ser fechada em breve. E para provar mais uma vez que isso não deve funcionar dessa maneira, citarei os próprios desenvolvedores da VK:
Se você planeja começar a desenvolver um messenger, após 15 de fevereiro de 2019, precisará obter acesso de teste no Suporte, o que implica o trabalho dos métodos da seção Mensagens com as chaves dos administradores do seu aplicativo Independente.

Ou seja, mesmo para obter um token de um aplicativo interno que terá acesso à correspondência do usuário, você precisa de uma permissão pessoal da VK, sem falar no acesso com uma senha e login regulares.

Minha opinião pessoal


A proibição da seção de mensagens não trouxe mudanças fundamentais na segurança dos usuários. Ele acabou de designar a fronteira e interrompeu um grupo de "sub-hackers" que, sem entender o que estavam fazendo, podiam obter acesso total aos dados. Para o resto das pessoas, com mais experiência em programação, obter acesso à correspondência é apenas uma questão de tempo. E, na primeira parte do artigo, provei com meu próprio exemplo, depois de criar um programa para extrair anexos, que o surgimento de uma biblioteca que pode fingir ser um usuário não está longe. Talvez eu mesmo o encerre e os desenvolvedores do VK precisem estar preparados para isso e encontrar maneiras de reconhecer atividades muito suspeitas do usuário se a privacidade de nossos dados for realmente importante para eles.

PS
, ) , .

All Articles