LIMB
Вход Регистрация

тема

Российская жилка. Получаем платное за бесплатное.

bezmyatezhnost · · 0 ответов · 255 просмотров

Не удалось прогрузить медиа

​
Все мы люди, а в частности люди из СНГ, где принято исподковырнуться, исподвыебнуться, и сделать еще 1000 шагов, лишь бы не платить за какой-либо платный материал, не так ли? Я лично сам из таких, сегодня разберем как по-мне одну из глупейших ошибок, которую можно было допустить, но сначала слегка предыстории. Довольно часто я сижу в тики-токах, и там мне попалось видео, которое гласит - "Новая онлайн игра, где вы можете быть детективом", видос был хороший, заинтересовал. Перешел на сайт, регнулся, а оказывается..- С меня хотят взять денег! Так быть не должно, считает моя русская жилка, как вы поняли исходя из пары тройки предложений ранее, и значит, надо что-то придумывать.. Поехали.

Не удалось прогрузить медиа

​
Вроде бы какие да никакие навыки у меня в вебе есть, а тут как раз таки то самое, ну значит "ломай меня полностью". На платформе, как бы в виде заманухи был вариант поиграть в бесплатную игру, чтоб понять - "што ето вообще такое? стоит ли платить за это гроши?". И с именно с этой заманухи сия акт ломания и начался.. 

Не удалось прогрузить медиа


И именно будет по-факту, входной точкой, да и можно сказать конечной, при создании игры отправляется такой замечательный пост-запрос.
Не удалось прогрузить медиа

Не удалось прогрузить медиа


Меня тут заинтересовал больше всего пэйлод, а именно purchasedCaseId, понимаете чем пахнет, да? Это потенциал на иДоРчИк - уязвимость в приложениях, которая возникает, когда разработчики неправильно обращаются к данным или ресурсам в приложении. Это означает, что злоумышленник может получить доступ к конфиденциальным данным или ресурсам путем манипулирования ID объекта в URL или запросе. Окей, давайте чуть-чуть подумаем головой. Я зарегался, мне дали бесплатный кейс, нажал "играть", улетел запрос с purchasedCaseId равным 1280. А что такое этот purchasedCaseId вообще? Это же не тип кейса, это ID конкретной покупки. Когда ты покупаешь кейс, в базе создается запись: "юзер такой-то купил кейс такой-то", и этой записи присваивается порядковый номер. 1, 2, 3, 4, 5... Мой бесплатный кейс получил номер 1280. А что под номерами 1, 2, 3, 4? Правильно, чьи-то чужие покупки. Платные покупки. За которые реальные люди заплатили реальные деньги. И тут возникает вопрос, который просто обязан был возникнуть в голове у разработчика, но видимо не возник: а проверяет ли сервер, что purchasedCaseId принадлежит именно тому юзеру, который отправляет запрос? 

Меняю purchasedCaseId с 1280 на 1200, отправляю. Получаю

Code:
{"success":true,"message":"Игра успешно создана","gameId":2353}
Шта? Я только что создал себе игру по чужой покупке. Какой-то бедолага заплатил за кейс, а я просто подставил его purchasedCaseId и получил тот же кейс бесплатно. Иду смотрю что там.

Не удалось прогрузить медиа


Платный кейс. За ноль рублей. Спасибо, чужой человек, за оплату. 

Не удалось прогрузить медиа


Если purchasedCaseId это инкрементный глобальный айдишник, то все покупки всех юзеров лежат в одном ряду. Юзер купил кейс - purchasedCaseId=100. Другой юзер купил - purchasedCaseId=101. И так далее. Значит, перебрав все айдишники, я могу создать игры по ВСЕМ покупкам ВСЕХ юзеров. Накидал скрипт.

Code:
for pid in range(1, 1200):
    r = s.post(
        'https://api.kodgoroda.games/client/games/create',
        json={'purchasedCaseId': pid},
        timeout=10
    )
    if r.status_code == 200:
        print(f"[+] VALID: purchasedCaseId={pid}")
    elif "максимальное количество" in r.text:
        print(f"[!] EXISTS: purchasedCaseId={pid} (limit)")

И побежало. Результат был такой: на большинство айдишников API отвечает ошибкой (покупки не существует), но на конкретные номера отвечает либо 200 (создана игра), либо 400 с текстом "Вы уже создали максимальное количество игр для этого кейса". Вторая ошибка самая показательная, она означает, что я УЖЕ использовал чужую покупку и исчерпал лимит попыток. Не мою покупку. Чужую. А сервер даже не моргнул.

Не удалось прогрузить медиа




Классический, хрестоматийный IDOR. Сервер должен был проверять одну простую вещь: "этот purchasedCaseId принадлежит юзеру из токена?". Один запрос к базе: "SELECT * FROM purchased_cases WHERE id = ? AND client_id = ?". Одна строчка кода. Но её нет. А самое ироничное знаете что? У них же есть лимит на попытки. То есть кто-то сел, написал логику "если юзер уже создал 3 игры для этого кейса, не давай создавать ещё". Потратил время, протестировал, задеплоил. Но при этом не подумал проверить, а его ли это вообще кейс.Ну, а дальше я сделал то, что должен был сделать, написал разработчикам. 

Не удалось прогрузить медиа


Хотя, конечно, ирония в том, что мне предложили промокод на бесплатную игру, которую я и так только что получил бесплатно через их же баг. Но это мелочи. Вся эта история, это один запрос, одна циферка, и полный доступ ко всему платному контенту. Без каких-то сложных цепочек эксплойтов. Ну, а мне пора идти играть в детектива. Бесплатно. Не болейте!
👍19 ❤️3 🤔4

Гостевой просмотр. Чтобы отвечать и ставить реакции, войдите или зарегистрируйтесь.