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

от автора

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

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

А началось все с изучения 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'])) ... 

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

ссылка на оригинал статьи http://habrahabr.ru/post/253939/