четверг, 2 марта 2017 г.

Google: кто-то завладел вашим паролем



Ночью мне пришло письмо на резервную почту о том, что кто-то использовал мой пароль для доступа к почте GMail, и что Google отважно заблокировал негодяев. Ну и мне, конечно, необходимо срочно принять меры. Я немного удивился, что почта, которая заведена специально для PayPal оказалась кем-то взломана. Учитывая, что она почти нигде не засвечена и имеет сгенерированный высокоэнтропийный пароль, это казалось невозможным. Однако, я сменил пароль, внутренне уже приготовившись к СМС с информацией о снятии денег с карты. А после смены пароля я начал разбираться в произошедшем и вот что выяснилось...

Пароль взломать почти нереально, поэтому сначала я подумал, что это мошенническое письмо о взломе, чтобы добыть мои логин/пароль. Тем более, что Google предупреждает об этом:
К сожалению, иногда хакеры пытаются получить данные аккаунтов, копируя сообщения Google о подозрительной попытке входа. Не доверяйте сообщениям, в которых вас просят предоставить имя пользователя, пароль или другие персональные данные. Если сообщение содержит ссылку на сторонний сайт, не переходите по ней и не вводите на этом сайте никаких данных.

Но ссылки в письме вели на https://accounts.google.com и браузер говорил, что сайт не поддельный. Вот что я там увидел в списке устройств:


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

Из любопытства я решил проверить — не к Пентагону ли ведет трейс до этого адреса. Результат все расставил по местам:
traceroute to 2a00:1450:400c:c0c:0:0:0:211 (2a00:1450:400c:c0c::211), 30 hops max, 80 byte packets 
1 2600:3c01::8678:acff:fe0d:79c1 (2600:3c01::8678:acff:fe0d:79c1) 3.296 ms 3.057 ms 3.024 ms (United States) 
2 2600:3c01:3333:1::1 (2600:3c01:3333:1::1) 2.886 ms 2.970 ms 2.939 ms                     (United States) 
3 eqixsjc-v6.google.com (2001:504:0:1:0:1:5169:1) 2.866 ms as15169.sfmix.org (2001:504:30::ba01:5169:1) 3.986 ms 4.011 ms (United States) 
4 2001:4860:0:1004::2 (2001:4860:0:1004::2) 3.178 ms 2001:4860:0:1005::2 (2001:4860:0:1005::2) 2.576 ms 2.540 ms (United States) 
5 2001:4860::8:0:6117 (2001:4860::8:0:6117) 145.173 ms 141.854 ms 142.622 ms               (United States) 
6 2001:4860::c:4000:d20a (2001:4860::c:4000:d20a) 46.065 ms 40.774 ms 41.735 ms            (United States) 
7 2001:4860::8:4000:cbc2 (2001:4860::8:4000:cbc2) 49.985 ms 2001:4860::8:0:b0e2 (2001:4860::8:0:b0e2) 154.440 ms 154.322 ms (United States) 
8 2001:4860::c:4000:d2a0 (2001:4860::c:4000:d2a0) 59.087 ms 2001:4860::c:4000:d64b (2001:4860::c:4000:d64b) 154.324 ms 2001:4860::c:4000:d29f (2001:4860::c:4000:d29f) 90.399 ms (United States) 
9 2001:4860::8:0:bafa (2001:4860::8:0:bafa) 153.360 ms 2001:4860::8:4000:cd7f (2001:4860::8:4000:cd7f) 63.042 ms 2001:4860::8:0:bafa (2001:4860::8:0:bafa) 143.081 ms (United States) 
10 2001:4860::c:4000:d9af (2001:4860::c:4000:d9af) 170.679 ms 2001:4860::c:4000:d9ab (2001:4860::c:4000:d9ab) 139.273 ms 140.791 ms (United States) 
11 2001:4860::8:0:cc3f (2001:4860::8:0:cc3f) 145.014 ms 145.056 ms 2001:4860::8:4000:d324 (2001:4860::8:4000:d324) 144.381 ms (United States) 
12 2001:4860::2:0:76e7 (2001:4860::2:0:76e7) 144.918 ms 2001:4860::2:0:76e8 (2001:4860::2:0:76e8) 144.521 ms 2001:4860::2:0:76e7 (2001:4860::2:0:76e7) 145.444 ms (United States) 
13 * * *                                                                                   (?) 
14 * * *                                                                                   (?) 
15 * * *                                                                                   (?) 
16 * * *                                                                                   (?) 
17 * * *                                                                                   (?) 
18 * * *                                                                                   (?) 
19 * * *                                                                                   (?) 
20 * * *                                                                                   (?) 
21 mail-wr0-x211.google.com (2a00:1450:400c:c0c::211) 142.782 ms 143.318 ms 144.535 ms     (Ireland)
В конце указан mail-wr0-x211.google.com. Вот тут я и вспомнил, что пароль к этой почте знает сам же Google в другом аккаунте GMail, который аккумулирует почту с различных моих адресов. И в этот раз Google, видимо, стал проверять почту из другого датацентра, а не как обычно. И, подозреваю, что в этот момент не я один получил подобные письма о взломе. Тут я делаю вывод, что чехарда датацентров и оказалась причиной детектирования подозрительной активности. А может Google просто так форсирует людей включать дополнительные шаги аутентификации. А вы что скажете?

пятница, 25 ноября 2016 г.

Бесплатные технические книги в электронном виде

Коллекция ссылок на бесплатные (не ворованные) технические книги собрана на ресурсе devfreebooks.github.io. Там есть книги по различным языкам разработки, фреймворкам, протоколам. Некоторые книги доступны для скачивания, а некоторые только для чтения онлайн.

понедельник, 8 августа 2016 г.

Польза архитектуры для создания безопасных продуктов



Завтра (9 августа 2016) выступаю в Летней школе CTF с лекцией о пользе архитектурных артефактов для создания безопасных решений. Пока выяснял как туда лучше доехать выяснил интересный факт из жизни Подмосковья:
  • Маршрут Зеленоград — Университет Дубна: около 140 км на автомобиле и примерно 5 часов на общественном транспорте.
  • Маршрут Зеленоград — Мариинский театр: около 680 км на автомобиле и примерно 5 часов на общественном транспорте.
Отсюда выводы: во-первых, Питер стал невероятно близок к Москве после появления скоростных поездов, и это невероятно круто. Во-вторых, подмосковные центры научного притяжения до сих пор остаются сложнодоступными и это очень печально.

Видео доклада:

понедельник, 1 августа 2016 г.

Создаем и публикуем модуль Python



В прошлый раз я описал шаги по освоению Питона для разработчика С++. Теперь, разобравшись с основами, можно начинать создавать свои первые проекты. Как и в других языках для этой цели разработчики используют какой-либо фреймворк, который зачастую определяет структуру программы, но этот путь может быть опишу в другой раз. Сегодня посмотрим на структуру типичного пакета Python.

Разницы с C++ тут большой нет — программой может быть как один файл, так и группа файлов. Упрощенно можно сказать, что один файл — это модуль (module), а набор модулей в пределах одной директории — пакет (package) или библиотека. Пакет также может содержать в себе дочерние пакеты. Поскольку язык интерпретируемый, то запускать на выполнение отдельные файлы можно следующим образом:
$ python foo.py
Если у вас в системе установлен какой-либо пакет, либо вы просто находитесь в директории, где есть пакет, то запустить его можно так:
$ python -m bar.foo
Где foo — это файл foo.py в пакете bar. У пакетов есть также скрипты с зарезервированными названиями, которые запускаются автоматически. Так, если в пакете bar есть скрипт __main__.py, то он будет запущен автоматически при выполнении python -m bar.

Также стоит обратить внимание на файл __init__.py. Именно его наличие говорит Питону, что данная директория является пакетом. Часто бывает, что этот файл оставляют пустым, но можно там разместить какие-то общие для всех модулей вещи.

Теперь посмотрим на небольшой пакет из реальной жизни и его структуру. Для пояснений я буду использовать свой проект ZXTools, который предназначен для работы со старыми дисками от ZX-Spectrum. Как-нибудь я подробнее расскажу о процессе разбора дискет от Спектрума. Пока же посмотрим на структуру проекта. Он состоит из двух директорий (test и zxtools) и из нескольких файлов в корне. Далее рассмотрим зачем там каждый из них.

LICENSE

Файл LICENSE очень важен для публикации вашей работы и это касается не только Python. Текст лицензии позволяет другим понять можно ли использовать результаты вашего труда и если да, то как именно. GitHub при создании нового проекта предлагает создать этот файл включив туда одну из стандартных лицензий.

README.rst

Файл README также должен быть хорошо знаком тем, кто уже публиковал свои работы или использовал чужие. Тут указывается полезная информация о проекте, для чего он предназначен и как им пользоваться. Обратите внимание на формат файла. Чаще встречаются файлы README.md, что означает файл в формате Markdown, но для проектов на Python лучше использовать reStructuredText, так как только его корректно поддерживает Python Package Index. А ведь именно на PyPI публикуются пакеты, которые потом легко устанавливаются с помощью пакета pip. GitHub прекрасно поддерживает RST формат, поэтому вы ничего не потеряете.

Makefile

«Что в проекте на Python делает Makefile?» — спросите вы. А делает он то же, что и в C++ — автоматизирует некоторые шаги. В моем проекте он используется для удобной очистки директории (знакомая цель clean), для запуска юнит-тестов (цель test), для анализа тестового покрытия (цель coverage) и для статического анализа (цель lint). Если вы ведете разработку под Windows, то Makefile возможно окажется не самым привычным средством. Тогда используйте привычный и удобный именно вам механизм, но не слишком усложняйте.

setup.py

Файл setup.py нужен для автоматизации публикации и установки вашего пакета. По сути, это очередной файл на Питоне, в котором вы вызываете функцию setup пакета setuptools. В функцию setup вы передаете параметры, которые описывают ваш пакет: имя пакета, номер версии, тип лицензии, описание, имя автора, ссылки на документацию и исходные файлы, список дочерних пакетов, список зависимостей, классификаторы. В примере есть все, что вы захотите использовать вначале. Но подробнее про все параметры можно посмотреть в документации.

Полезно тут же указать какие командные скрипты необходимо создать при установке. Такие скрипты сильно упрощают использование вашего пакета, так как не нужно будет помнить в каком пакете находятся нужные команды и не нужно писать длинную строку их вызова. В примере можно видеть раздел entry_points, в котором определены две команды:
entry_points={
        'console_scripts': [
            'zeus2txt = zxtools.zeus2txt:main',
            'hobeta = zxtools.hobeta:main',
        ],
    },
Команды имеют следующий формат: <имя пакета>.<имя модуля>:<имя функции>.

Также стоит обратить внимание на параметр test_suite. В нем указывается пакет, который отвечает за тестирование вашего проекта. В данном случае указан пакет test.

Публикация, запуск тестов и continuous integration

Я уже упоминал, что самое популярное место для публикации пакетов — это индекс PyPI. Помимо этого, для открытых проектов TravisCI предоставляет бесплатную возможность запуска тестов на каждый коммит, а codecov.io позволяет отслеживать изменение покрытия и сигнализирует о проблемах. Именно эти средства я использовал в ZXTools. В следующий раз подробнее расскажу как опубликовать пакет, автоматически запускать проверку тестов, считать покрытие и как добавить красивые бейджики с информацией об этих процессах.

Книги по теме:

  1. Марк Лутц. Программирование на Python. Том 1
  2. Марк Лутц. Программирование на Python. Том 2

понедельник, 6 июня 2016 г.

 Мой путь из C++ в Python

Этот текст кратко поясняет как мне удалось быстро начать писать программы на Python. Все, что описывается, основывается на личном опыте и ощущениях, и поэтому может не описывать тот самый единственно верный путь. Тем не менее, изложенная информация агрегирует знания, которые пришлось собрать, чтобы создавать собственные проекты на Python. Для начала не огромные высокопроизводительные системы, но и на C++ вы тоже не сразу стали выдавать шедевры. Если у кто-то посчитает, что тут не хватает важных вещей, о который обязательно нужно сказать, то в комментариях можно это отметить.

Начинать разработку конечно нужно с установки интерпретатора. Повезло тем, у кого установлена операционная система семейства Linux — тогда вопрос установки скорее всего не стоит и интерпретатор Python уже установлен. Если Python не установлен, то инсталлятор для всех популярных ОС совершенно бесплатно можно скачать с официального сайта.

После этого можно попробовать запустить Python, но никакой среды разработки вы не увидите, а увидите интерактивную консоль:

Из интересного на картинке — версия языка. Очень много кода и библиотек существует для версии 2.7 и поэтому повсеместный переход на ветку 3.5 слегка затянулся. Но все-таки я рекомендую изучать именно 3.5. При необходимости вы сможете писать и для 2.7, при этом будете знать более современную редакцию.

Хотя этот вопрос и не такой популярный как про выход из Vim, но сразу подскажу, что выйти из интерактивного режима можно написав quit().

Если очень хочется какую-нибудь среду разработки, то PyCharm мне показалось наиболее удобной (помимо платной версии есть и Community Edition). Под Windows конечно еще есть привычная Visual Studio с Python Tools.

С инструментами покончено, время понять какие важные отличия от C++ нужно сразу усвоить. Во-первых, Python использует duck typing. Это означает, что если в какой-то момент выполнения программы объект имеет все свойства класса, то он в этот момент считается объектом этого класса. Если сравнивать с C++, то ближе всего к этому концепты (Concepts), которые кстати не попадут в C++17.

If it looks like a duck, swims like a duck and quacks like a duck, then it probably is a duck.

Во-вторых, многопоточности в Python нет. Если вы будете мучить Google на эту тему, то скорее всего наткнетесь на GIL (Global Interpreter Lock), но это совсем не та многопоточность, к которой привыкли C++ разработчики. Схематично принцип такой многопоточности показан на картинке — тут хорошо видно, что параллельно никакие потоки не выполняются, даже если у вас многоядерный процессор:

GIL description

Полноценная многопоточность обычно реализуется за счет запуска отдельных процессов. Для начала это все, что нужно знать про многопоточность в Python.

Остальные вопросы, которые часто возникают у новичков, и ответы на них можно найти на StackOverflow.com в секции с часто задаваемыми вопросами. Стоит просмотреть первых штук 50.

Из этих вопросов вы узнаете, что файлы на Python имеют расширение py и их стоит начинать со следующей строки:

#! /usr/bin/env python
Это позволяет запускать скрипт в виртуальных окружениях с разными версиями Python. Сам же Python выполняет файл последовательно с первой строки и далее. При этом нет никакой функции main, как в C или C++. Хотя часто в скриптах встречается строка if __name__ == "__main__", которую ошибочно можно принять за точку входа. Но нет, если за пределами этого выражения будет другой код, то он также выполнится. А само выражение удобно использовать для создания и запуска тестов в подключаемых модулях.

В следующий раз расскажу как создать модуль и тесты для него, и как это потом опубликовать и «непрерывно интегрировать». А ниже моя первая программа на Python:

#! /usr/bin/env python
# vim: set fileencoding=utf-8 :
""" Hello world in Python """

def main():
    print("Hello world!")

if __name__ == "__main__":
    main()

Книги по теме:

  1. Марк Лутц. Программирование на Python. Том 1
  2. Марк Лутц. Программирование на Python. Том 2

вторник, 17 мая 2016 г.

hex dump


Постоянные пользователи Vim наверняка слышали об утилите xxd. Она позволяет вывести дамп указанного файла. Выглядит это следующим образом:
$ xxd -l 64 db.sqlite3 
0000000: 5351 4c69 7465 2066 6f72 6d61 7420 3300  SQLite format 3.
0000010: 0400 0101 0040 2020 0000 0013 0000 0024  .....@  .......$
0000020: 0000 0000 0000 0000 0000 0017 0000 0004  ................
0000030: 0000 0000 0000 0000 0000 0001 0000 0000  ................
Параметр -l 64 указывает, что нужно вывести только первые 64 байта. Есть еще один любопытный параметр (-i), который позволяет сгенерировать код, и его можно сразу вставлять в C или C++ файл:
$ xxd -i -l 64 db.sqlite3
unsigned char db_sqlite3[] = {
  0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61,
  0x74, 0x20, 0x33, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x40, 0x20, 0x20,
  0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  0x00, 0x00, 0x00, 0x00
};
unsigned int db_sqlite3_len = 64;
Параметров для генерации кода для других языков не предусмотрено. Но это поправимо. Например, мне понадобилось вставить код в модульные тесты на Python 3. Помог в этом потоковый редактор sed:
$ xxd -l 64 -g 1 -u db.sqlite3 | sed -e 's/.\+: /b"\\x/g' -e 's/  .*/"/g' -e 's/ /\\x/g'
b"\x53\x51\x4C\x69\x74\x65\x20\x66\x6F\x72\x6D\x61\x74\x20\x33\x00"
b"\x04\x00\x01\x01\x00\x40\x20\x20\x00\x00\x00\x13\x00\x00\x00\x24"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x04"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
И кстати, вскоре я поделюсь опытом как быстро начать писать программы на Python.


Книги по теме:
  1. Дню Нейл. Практическое использование Vim
  2. Марк Лутц. Программирование на Python. Том 1

вторник, 5 апреля 2016 г.

В Visual Studio добавилась поддержка сборки под Linux



Итак, в Visual Studio теперь можно компилировать и отлаживать проекты под Linux. Можно было бы подумать, что это первоапрельская шутка, но нет — новость была выложена 30 марта. Кроме того, я уже попробовал — это реально работает.

Visual Studio использует доступ по ssh на удаленную машину с Linux. Туда автоматически копируются необходимые исходные файлы, которые потом там же и компилируются. При необходимости запускается gdbserver для организации удаленной отладки. Все это делается незаметно и не требует ручной настройки. Надо учитывать, что это самая первая версия и для продакшена пока не годится.

На первый взгляд видятся следующие недостатки:
  1. Копирование файлов на удаленную машину не выглядит безопасным. Канал конечно защищен, но вот сама удаленная машина может контролироваться потенциальным нарушителем.
  2. Копирование большого проекта может занять продолжительное время.
  3. На удаленной машине элементарно может не быть места для всех сорсов и объектных файлов.

Также пока не реализовано отображение стандартного вывода в Output в самой Visual Studio. То есть, программа удаленно работает и что-то пишет в консоль, но прочитать это нельзя. Но этот недостаток скоро исправят, так как он уже есть в бэклоге команды разработки.

Подробнее: https://blogs.msdn.microsoft.com/vcblog/2016/03/30/visual-c-for-linux-development/