Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

Latest commit

 

History

History
59 lines (42 loc) · 3.25 KB

WRITEUP.md

File metadata and controls

59 lines (42 loc) · 3.25 KB

Юртогонки! Write-up

«Юртогонки» — это почти как популярный когда-то сайт «Клавогонки»: вы соревнуетесь с противником в скорости и точности печати на клавиатуре. Здесь, правда, вы соревнуетесь не с компьютером, а с человеком. И компьютер хорош — следовательно, придётся хитрить.

Хитрость первая: автоматический ввод с клавиатуры

Можно было воспользоваться каким-нибудь средством для автоматизации пользовательского ввода — например, библиотекой pyautogui. Но это бы не сработало, потому что клиентская часть игры проверяла скорость ввода и не давала печатать быстрее компьютера:

const handlePress = e => {
    e.preventDefault();
    now = Date.now()
    // 6 ms is the world record. no way a user types faster
    if (now - lastInput < 6) {
        alert("Обнаружена попытка накрутки скорости печати. Игра всё.");
        socket.close();
    }
    lastInput = now;
    socket.send(e.charCode);
};

Функция handlePress объявлена константой, и переопределить на ходу её нельзя. Но можно скачать фронтенд игры к себе, отредактировать код как вздумается, и запустить его — здорово, если сработает.

Хитрость вторая: пишем свой клиент

Изучив исходники игры, видим, что общение между клиентом и сервером происходит через WebSockets. Нетрдуно проследить, как именно:

  • клиент по каждому нажатию клавиши на клавиатуре передаёт код соответствующего символа;
  • сервер отвечает состоянием игры в формате JSON.

Осталось только свой клиент, который решает игру во мгновение ока. Возьмём для этих целей модную асинхронную библиотеку aiohttp:

import aiohttp
import asyncio


async def solve():
    url = 'wss://urtracing.s.2021.ugractf.ru/token/ws'
    async with aiohttp.ClientSession() as s:
        async with s.ws_connect(url) as ws:

            # получаем текст
            text = (await ws.receive_json())['text']

            # отправляем его посимвольно назад
            for c in text + " ":
                await ws.send_str(str(ord(c)))

            # проверяем ответы сервера на наличие приза-флага
            async for msg in ws:
                if flag := msg.json()['prize']:
                    print(flag)


asyncio.run(solve())

Флаг: ugra_etot_paren_byl_iz_teh_842386f02628a069