Как стать IT-принцессой

от автора

image
Каждая девочка мечтает стать принцессой, быть самой красивой, самой умной и обязательно встретить принца. Множество маркетологов и 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *