python

Сам себе Руссинович

  • четверг, 26 марта 2015 г. в 02:10:56
http://habrahabr.ru/post/253939/

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

Согласно требованиям безопасности, да и просто здравой логике, любые мало-мальски важные данные нужно прятать под матрас шифровать, а пренебрежительное отношение, как показывает практика, касательно приватности данных приводит пусть и не к самым суровым репрессиям, но все же последствиям весьма неприятным; это — простительно рядовым пользователям, но никак не системным администраторам, программистам и уж тем более специалистам с именем — как никак на кону репутация.

А началось все с изучения API не нуждающегося в представлении сервиса VirusTotal, с которым стал интегрировать некоторые из своих утилит Марк Руссинович. Прочтя документацию, мне стало любопытно насколько защищен ключ «вшиваемый» Руссиновичем в свои утилиты. Но к моему удивлению и разочарованию одновременно ключ никак не защищен.

>>> from os import name, path, system
>>> #просто для удобства
>>> def cls(): system('cls' if name == 'nt' else 'clear')
...
>>> #где сидит фазан?
>>> sig = path.abspath('sigcheck.exe')
...
>>> from re import compile, findall
>>> with open(sig, 'rb') as fs:
...     buf = fs.read()
...
>>> #длина ключа 64 символа
>>> for i in compile('[\x20-\x7E]{64,}').findall(buf.decode('ascii', 'replace')): print(i)
...

Вообще, идея проверить наличие незашифрованного ключа по его длине была спонтанной. С другой стороны, можно ли однозначно утверждать, что:

>>> key = compile('[\x20-\x7E]{64,}').findall(buf.decode('ascii', 'replace'))[3]

и есть ключ? Просто проверяем подстановкой.
>>> cls()
...
>>> from urllib.parse import urlencode
>>> from urllib.request import urlopen
>>>
>>> par = {'resource':'habrahabr.ru', 'apikey':key}
>>> with urlopen('http://www.virustotal.com/vtapi/v2/url/report', bytes(urlencode(par), 'utf8')) as req:
...     json = req.read()
...
>>> #парсим полученные данные
>>> from json import loads
>>> loads(str(json, 'utf8'))['positives']
1

Да ладно! Глянем результаты сканирования.
>>> res = loads(str(json, 'utf8'))['scans']
>>> for i in sorted(res): print("%-27s%s" % (i, res[i]['result']))
...

Впрочем, я отвлекся от основной темы.

Со всем этим я обратился к самому господину Руссиновичу, но никакой реакции, за исключением деактивации возможности оставлять комментарии к результатам сканирования с данного ключа, не последовало. Что в общем-то логично: какой смысл шифровать уже вскрытый ключ? Впрочем, даже смена ключа ни к чему не обязывает, если вникнуть в то, как именно он генерируется, но это уже тема отдельного разговора.