# разбор таска Отсылка на ДжоДжо 1

Для начала, посмотрим что происходит на странице. Для этого, зайдем в исходный код. На странице выполняется скрипт, который сначала открывает `WebSocket`. Чтобы узнать что это, загуглим. Это соединение с сервером, которое обменивается текстовыми данными. Все что есть в скрипте помимо этого является оберткой над этим соединением, по типу добавления сообщения в страницу. Так что дальше исследовать страницу мало пользы, можно исследовать соединение.
Погуглив, можно узнать что общение по вебсокетам доступно в python3, что мы и будем использовать. Программа дальше открывает соединение, отправляет `init` и печатает все ответы от сервера.
Напишем на python скрипт с использованием библиотеки websocket_client:
```python
import websocket as ws
c=ws.create_connection('wss://jojo1.ctfmay.sch9.ru/ws/')
c.send('b')
while(1):
    print(c.recv())
```
Вывод:
> photo 3

Следующий запрос соединение воспримет как попытку угадать фразу. Так как у ДжоДжо изначально 4 ХП, то можно узнать 4 идущие подряд фразы. Дальше, можно воспользоваться данным в условии словарем глаголов, для всех глаголов заменить их номерами и посмотреть на результат. Пример:\
Фразы:
> Я хочу выйти чтобы рвать, а потом родиться и, будучи победителем, приказать оставить тебе, ДжоДжо, так сильно пытающийся велеть!!!\
> Я хочу определять чтобы попадать, а потом грозить и, будучи победителем, приказать решиться тебе, ДжоДжо, так сильно пытающийся мыть!!!\
> Я хочу утверждать чтобы хранить, а потом согласиться и, будучи победителем, приказать хотеться тебе, ДжоДжо, так сильно пытающийся смеяться!!!\
> Я хочу обращаться чтобы совершить, а потом возражать и, будучи победителем, приказать меняться тебе, ДжоДжо, так сильно пытающийся сравнивать!!!\
> Я хочу понравиться чтобы следовать, а потом нравиться и, будучи победителем, приказать сметь тебе, ДжоДжо, так сильно пытающийся миновать!!!

Номера в 0-нумерации:\
41, 924, 260, 514, 210, 565\
100, 204, 727, 514, 637, 905\
159, 483, 195, 514, 65, 246\
218, 762, 662, 514, 492, 586\
277, 42, 130, 514, 919, 926\

Можно заметить, что номер первого глагола изменяется на одинаковое число каждый раз, возвращаясь в 0 если увеличивается до 999, т.е. "ходит по кругу из чисел от 1 до 999" (), то же верно и для остальных номеров. Можно ещё несколько раз позапускать соединение чтобы убедиться что это всегда так и что номер (?????) глагола - всегда 514. Теперь, с помощью этого замечания попробуем угадать одну фразу. Кроме того, попробуем автоматически генерировать ответ, т.к. в дальнейшем это придется сделать 1000 раз.
```python
import websocket as ws                                   #подключаем библиотеку
a=open('glags.txt','r').read().split('\n')[:-1]          #Загружаем файл, записываем в массив


c=ws.create_connection('wss://jojo1.ctfmay.sch9.ru/ws/') #Начинаем соединение
c.send('init')                                           #Посылаем 'init' в соединение
print('recieve:',c.recv())                               #Выводим на экран ответ (photo 3)
c.send('b')                                              #Посылаем что-то чтобы узнать первую фразу
s=c.recv()                                               #Считываем фразу из соединения
print('recieve:',s)                                      #Выводим её на экран
print('recieve:',c.recv())                               #Считываем оставшиеся фразы
print('recieve:',c.recv())                               #
print('recieve:',c.recv())                               #
print('recieve:',c.recv())                               #
words=[s[s.find('хочу')+5:s.find('чтобы')-1],            #Вытаскиваем из фразы только 5 глаголов, которые изменяются...
        s[s.find('чтобы')+6:s.find('а потом')-2],        #   ...и записываем их в массив
        s[s.find('а потом')+8:s.find('и, будучи')-1],    #
        s[s.find('и, будучи')+33:s.find('тебе,')-1],     #
        s[s.find('пытающийся')+11:s.find('!!!')]]        #
print('words in phrase:',words)                          #Выводим на экран массив слов
oidx=[a.index(words[i]) for i in range(5)]               #Записываем индексы слов в массиве a (словаре) в массив
print('indexes in dictionary:',oidx)                     #И выводим этот массив
c.send('b')                                              #Повторяем операцию для следующей фразы
s=c.recv()
print('recieve:',s)
print('recieve:',c.recv())
print('recieve:',c.recv())
print('recieve:',c.recv())
print('recieve:',c.recv())
words=[s[s.find('хочу')+5:s.find('чтобы')-1],
        s[s.find('чтобы')+6:s.find('а потом')-2],
        s[s.find('а потом')+8:s.find('и, будучи')-1],
        s[s.find('и, будучи')+33:s.find('тебе,')-1],
        s[s.find('пытающийся')+11:s.find('!!!')]]
print('words in phrase:',words)
idx=[a.index(words[i]) for i in range(5)]
print('indexes in dictionary:',idx)
d=[(idx[i]-oidx[i])%len(a) for i in range(5)]            #Cчитаем изменение номера для каждого глагола
print('differences:',d)                                  #Выводим его на экран
for i in range(5):                                       #Угадываем глаголы третьей фразы
        idx[i]+=d[i]                                     #Пересчитываем массив idx
        idx[i]%=len(a)
        words[i]=a[idx[i]]                               #Выбираем нужные глаголы
c.send(f'Я хочу { words[0] } чтобы \                     #Выводим угаданную фразу
{ words[1] }, а потом { words[2] } и, будучи \           #
победителем, приказать { words[3] } тебе, ДжоДжо\        #
, так сильно пытающийся { words[4] }!!!')                #

while(1):
        print(c.recv())                                  #Выводим остаток ответов от сервера.
```
Видим, что на этот раз вывод другой и ХП снялись уже не у ДжоДжо, поэтому продолжаем отгадывать фразы таким же образом. Начальный код остается таким же, но после выбора нужных глаголов код будет:
```python
for i in range(1000):                                    #Повторяем столько раз, сколько ХП у противника
        c.send(f'Я хочу { words[0] } чтобы \             #Отправляем сгенерированную фразу
{ words[1] }, а потом { words[2] } и, будучи \
победителем, приказать { words[3] } тебе, ДжоДжо\
, так сильно пытающийся { words[4] }!!!')
        s=c.recv()                                       #Выводим ответ от сервера
        print('recieve:',s)
        print('recieve:',c.recv())
        print('recieve:',c.recv())
        print('recieve:',c.recv())
        print('words in phrase:',words)
        print('idxs:',idx)
        for i in range(5):                               #Пересчитываем массивы
                idx[i]+=d[i]
                idx[i]%=len(a)
                words[i]=a[idx[i]]
c.send('h')                                              #Выводим что-то чтобы получить ответ от сервера
while(1):
        print(c.recv())                                  #Выводим остаток ответов от сервера.

```
Таким образом, получаем флаг.
Флаг: `ctf{guess_reverse_jusddf}`