Tags: chrome js 

Rating: 3.0

В архиве находится *.crx* файл. Воспользовавшись собственными знаниями \ гуглом \ утилитой *file* выясняем, что это расширение для Google Chrome. Первая же ссылка по запросу "crx unpack online" приводит нас на [сайт](https://crxextractor.com/), где мы можем получить архив с распакованными файлами расширения. Из всех них нас интересует только *background.js*.

Скрипт делает примерно следующее. При каждом изменении кук в браузере (?) резолвит домен через google DNS, далее общается с сервером по полученному ip адресу, получает ключ для AES (мы его тоже можем получить, он потом понадобится), обфусцирует куку, выполняет ряд приготовлений перед непосредственно шифрованием, шифрует куку с использованием полученного ключа (пусть и после процедуры расширения ключа, она нас не особо интересует), отправляет зашифрованную куку на сервер (отметим, что название функции отправки *put_cookie* совпадает с URL на сервере, куда делается этот запрос).

Фукнция *get_cookie* помечена как *to be implemented*. Фактически, именно ее нам и надо сделать. Отправив запрос по адресу "http://"+ip+":5000/get_cookie" (понадеявшись, что имя функции опять совпадет с соответствующим на сервере), получим BASE64 строку.

Огромным подспорьем было то, что функция расшифровки уже была написана в том же скрипте, и для ее использования надо было всего лишь в одном месте изменить *AES_Encrypt(block, key)* на *AES_Decrypt(block, key)* и подать на вход шифротекст и ключ, полученные с сервера. В итоге получем ту самую строку, которая была после обфускации, но до шифрования. Остается только обратить обфускацию, что, на мой взгляд, и составляет основную сложность задания.

Обфускация состоит из двух частей, причем количество итераций второй части зависит от ключа, который ранее был использован для расшифрования. В нашем случае вторая часть будет выполняться 2 раза. Вот скрипт, который обратит обфускацию:

```
q = ['000000ba00yx',
'1c4058c059xx',
'00ba80b380yx',
'1e8052c055xx',
'00b0009900yx',
'1d0058004exx',
'00b980b100yx',
'0d805a4058xx',
'009880b980yx',
'3000b700b0xy',
'00b4009900yx',
'190050005fxx']

# revert second part
qq=[]
for i in q:
if i[-1]=='x':
qq.append( hex( int(i[:10],16) *2)[2:].zfill(10)+i[-2] )
else:
qq.append( hex( int(i[:10],16) +1)[2:].zfill(10)+i[-2] )

qqq=[]
for i in qq:
if i[-1]=='x':
qqq.append( hex( int(i[:10],16) *2)[2:].zfill(10) )
else:
qqq.append( hex( int(i[:10],16) +1)[2:].zfill(10) )
print(qqq)
ans = ''.join(qqq)[4:]
print(ans)

# revert first part
res=''
for i in range(0, len(ans), 4):
res += chr(int(ans[i+2:i+4],16)-1)
print(res)
```

Я где-то ошибся и на выходе флаг получается неверный, но его легко поправить руками - проблема в фигурных скобках, ASCII коды этих двух символов почему-то сместились на 2 в меньшую сторону.