Thursday, November 27, 2014

Признавать свои ошибки

."На чужих ошибках учится только мудрый гений, на своих - умный, дурак - не учится вовсе"
Из личного опыта


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

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

Если Web-компания, постоянно пентестит свои внешние сервисы, находит в них уязвимости и патчит их - круто, что они вообще этим занимаются, понимают, что это надо делать, делают это и исправляются (== становятся лучше!). Если они при этом еще публикуют технические описания этих уязвимостей - совсем хорошо, так как это дает возможность продвинутому читателю понимать уровень сложности и качество проводимых ими аудитов, что характеризует, опять же, уровень технологической зрелости. 

Аналогично, если компания пишет софт, и ресурсами своей продуктовой безопасности (если есть профессиональная продуктовая безопасность, которая ломает по-всякому только-то вышедший из-под программиста код - это уже прорыв!) или внешнего аудитора (но, конкретно в данном случае, мне кажется, свои - лучше, так как они "больше в теме", а "замыливания глаза" у них нет, так как все-таки код они не пишут, а только исследуют его) находит баги, исправляет их, и публично пишет об этом - это неплохо.

Но не только технологические вещи здесь применимы (кстати, мы начали с неидиота, осознавшего свои слабости) - вполне, компания может анализировать свои бизнес-процессы, находить в них уязвимости, скажем, приводящие к мошенничеству или низкой эффективности, исправлять их, а затем публиковать информацию об этих, уже исправленных, проблемах. Да любой рассказ о том, что кто-то что-то где-то преобразовал - не что иное, как рассказ о своих преодоленных слабостях, исправленных уязвимостях...

Итак, если вы осознаете свои проблемы, работаете над ними и измеряете степень успешности этой работы, вам обязательно следует это публиковать, хотя бы потому что:
  1. это опыт, которым стоит делиться;
  2. это демонстрирует вашу модель зрелости во всех перспективах: технологической, организационной, процессной, пр.;
  3. это позволяет сделать мир лучше.

Friday, November 21, 2014

Качество/Цена

Не раз я порочил и поносил критерий "минимальной цены" при выборе победителя в конкурсе на услуги безопасности, вот еще пост в копилку ЗА более интеллектуальный подход к выбору поставщика услуг, чем сравнение стоимости предложений.

Один мой приятель, генеральный директор и основатель успешной компании, оказывающей услуги в области ИБ, во время проведения с ним "эффективных переговоров" о необходимости снижения цены сказал: "Я могу выполнить любые работы за любые деньги, вопрос только в качестве". Те переговоры были действительно "нереально эффективными" - была получена большая скидка от первоначального предложения, но об успешности результата этих работ я так позитивно отозваться не могу :(. Теперь тот случай я рассказываю как притчу для тех, кто испытывает позывы выбрать на выполнение консалтинговых услуг явно демпингующего поставщика.

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

  1. В тендерной документации требуйте предоставление плана работ с указанием трудоемкости по каждому пункту, исполнителей, полный состав проектной команды с подтверждением их квалификации. Если есть возможность можно еще тупо спросить ставки.
  2. В конкурсной комиссии должны быть эксперты по предметной области, способные: оценить адекватность плана, указанной трудоемкости работ, требуемого состава исполнителей и их квалификации. Эксперт должен знать рынок, должен иметь представление о стоимости на рынке специалистов указанной квалификации, что крайне полезно, если ставки остались не известны (на практике это не большая проблема, так как вполне нормально требовать стоимость по каждому пункту плана, а имея стоимость и трудоемкость пункта плана работ - предположение о ставке исполнителей делается очевидным образом).
  3. Все радикальные расхождения в представленных на конкурс планах должны в обязательном порядке анализироваться и, в конечном счете, этому должно быть найдено объяснение. Если причиной расхождений является неоднозначность задания, надо переигрывать конкурс.
  4. Все радикальные расхождения в стоимости предложений разных конкурсантов должны также обязательно анализироваться, и этому также должно быть найдено адекватное объяснение.
  5. Не надо выбирать предложение, заявленная стоимость которого ниже рассчитанной экспертом (с учетом пунктов плана, их трудоемкости, состава исполнителей и их квалификации).
  6. Не надо вестись на эксклюзивные предложения со стоимостью явно ниже рассчитанной экспертом себестоимости работ. Все эти "скидки" в конечном счете будут вашими издержками: либо вы будете работать больше, либо дальнейшая перспектива взаимоотношений с этим поставщиком для вас явно не будет характеризоваться адекватностью стоимости работ.
Рынок, если он конкурентен, - нормальный способ регулирования соотношения Качество/Цена, пытайтесь прогнозировать последствия ваших решений - увидев сыр, попытайтесь увидеть и мышеловку и, уверен, все получится, как планировали, хотя бы на треть :).
 

Thursday, November 20, 2014

Шпаргалка по certutil

certutil - отличный инструмент, но с одной проблемой - у него как и у openssl куча параметров, которые знать/помнить невозможно, особенно в условиях, когда этим пользоваться часто нет необходимости, поэтому привожу наиболее часто используемые из собственной практики.

1. Посмотреть сертификаты в хранилище сервера. Это то же самое что видно в ветке peronal оснастки Certificates/Local Computer.
Certutil –store My
Любопытно, что там есть сертификаты у DC, которые аутентифицируют клиентов по токену (нужен для возможности подключения к CA для аутентификации), но там нет сертификатов у прочих серверов, которые также могут аутентифицировать клиентов по сертификату. 


2. Посмотреть сертификаты, хранимые в AD. Там хранятся сертификаты самих удостоверяющих центров.
Certutil -store -enterprise NTAuth
Для логона по смарткартам в этом сторе должны лежать сертификаты УЦ, выдающих сертификаты на смарткарты. NTAuth живет в AD, и на каомпьютеры домена распространяется групповой политикой. Если на компьютере не будет корректной копии NTAuth, вход по смарткарте на него будет невозможен.

3. Проверить, что сертификат проверяем по CRL (Certificate Revocation List) по CDP (CRL distribution point) указанным в сертификате.
Certutil –verify -urlfetch –v certificate.cer, где certificate.cer - имя файла, куда экспортирован сертификат.
Команда может использоваться как для проверки сертификатов пользователей, так и для проверки сертификатов компьютеров).


4. То же самое, что и п.1, но графическая:
Certutil –viewstore My

5. Запрос можно сгенерить вручную, вручную отнести на CA и получить на него сертификат. Команды приводить не буду (так как ни разу пока не делал, но приведу, где почитать, ибо был в двух шагах от этой необходимости, материал может пригодиться)
 - Ответ товарища Valergo на форуме: http://social.technet.microsoft.com/Forums/ru-RU/windowsserverru/thread/69a887f0-8719-4a22-bde8-728d2d38d117/#a4f1dc1c-4f54-43d5-aed6-265b315e2e36
 - Статья в TechNet: http://technet.microsoft.com/ru-ru/library/cc783835%28WS.10%29.aspx

6. Проверить, что по URL в CDP можно вытащить CRL.
Графически: Certutil –url certname.cer и нажать кнопку Retrieve.
Текстово, вывод лучше отправить в файл: Certutil –v –verify –urlfetch certname.cer >c:\certcheck.txt

7. Работа с криптопровайдером (CSP - Crypto service provider):
Certutil /scinfo   - информация о текущем.
Certutil -csplist  - список всех.
Certutil -csptest "cspname" (например: Certutil -csptest "Microsoft Strong Cryptographic Provider") - информация конкретном CSP.

8. Посмотреть мои сертификаты:
certutil -store -user my > my.txt
Экспорт в PFX (PKCS#12):
certutil -p test -user -exportPFX 0123456788e8cb1a18e cert.pfx В качестве параметров указывается серийник и пароль (через -p)
Импорт:
certutil -p test -user -importpfx cert.pfx

9. Хорошая помщь по certreq: http://support.microsoft.com/kb/931351
(см. раздел "How to use the Certreq.exe utility to create and submit a certificate request that includes a SAN" в конце статьи).
Официальная помощь: http://technet.microsoft.com/en-us/library/cc736326%28WS.10%29.aspx
certreq -new hrctforms.inf hrctforms.reqcertreq -submit -config "SERVER_NAME\CA NAME" hrctforms.req hrctforms.cer ,

где "SERVER_NAME\CA NAME" - название УЦ с именем сервера.

Простейший варинт файла .inf:
[Version]

Signature="$Windows NT$

[NewRequest]
Subject = "E=hrctforms@tnk-bp.com,CN=hrctforms,OU=TBInform,O=TNK-BP,L=Moscow,S=Moscow,C=RU"
Exportable = TRUE
KeyLength = 1024
ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"
   
[RequestAttributes]
CertificateTemplate = SMIMEforServices

10. Резервное копирование ключей УЦ:
certutil –backupKey 11. certutil -pulseЗапустить autoenrollment.


12. certutil -getkey - извлекает из УЦ зашифрованный ключом Агента восстановления (KRA - Key recovery agent) BLOB депонированного ключа. Команду следует запускать от пользователя с правами администратора на УЦ. определяет какие ключи доставать. Это может быть имя пользователя или серийный номер сертификата. определяет имя выходного файла. Пример:
certutil -getkey 40a2c77f0001000000fc data.blb, где
40a2c77f0001000000fc - серийный номер сертификата, ключ которого надо восстановить.

13. certutil -recoverkey - расшифровывает BLOB и восстанавливает депонированный ключ в PKCS#12 (файл с расширением .pfx). Команда должна выполняться от пользователя в профиле которого есть сертификат Агента восстановления с секретным ключом.  Если ошибок не было, то команда спросит пароль для шифрования PFX-файла, который будет записан в . Продолжим пример п.12:
certutil -recoverkey data.blb username.pfx



Официальный справочник параметров certutil: https://technet.microsoft.com/en-us/library/cc732443(v=ws.11).aspx


Wednesday, November 19, 2014

Операционная отчетность

К сожалению, большинство коллег, с которыми мне приходилось общаться, считают отчетность ненужной рутиной и, тем более, не рассматривают ее как тактический инструмент совершенствования своей СУИБ. Такое отношение порождает неверный подход к изобретению отчетности: в лучшем случае - это демонстрация выполненных работ, типа "вот как я много всего сделал", в худшем - это просто демонстрация чего-угодно, "чтобы только отстали". Это неправильно, так как выходные данные моего operations-а являются входными данными для моей СУИБ, а транспортом этих данных является не что иное как отчетность! Ну и как же это сделать?

Прежде всего надо определиться с целями, я люблю использовать термин "отчетность по цели", тогда в общем виде построение "отчетности по цели" будет выглядеть так: 
  1. определяем цели;
  2. определяем метрики, т.е. как понять степень достижения целей;
  3. понимаем как можно отобразить недостатки, т.е. причины неполного достижения целей.

Мутновато, поэтому поясню на примере. Например, у меня есть куча систем мониторинга безопасности и целью отчетности я ставлю - выработка плана развития моих технических средств обеспечения ИБ. Под "планом развития" будем понимать модернизацию/модификацию существующих и/или внедрение новых СЗИ. Имея такую цель попробуем определить метрики: 1) по каждому инциденту определять с использованием какой системы он был а) обнаружен, б) расследован, в) локализован и т.п.; 2) по каждому инциденту определять какие системы должны были, но ничего не сделали (false negatives); 3) особо следует отразить ложные срабатывания (false positives); 4) крайне полезно раскладывать инциденты по векторам атак, например: 1) внешняя почта, 2) внешний веб, 3) съемные носители, 4) подключаемая в сеть некорпоративная техника, 5) ошибки групп эксплуатации при реализации изменений, и т.п.

Получив все эти данные самое время подумать над п.3 нашего общего плана построения "отчетности по цели" - как отобразить эти метрики наиболее наглядным образом (это и будет наша отчетность!). Имея распределение инцидентов по векторам атак, а по каждому инциденту перечень систем безопасности (инструментов) с помощью которых мы управляли инцидентом, получаем распределение систем по векторам с подтверждением их эффективности, поскольку инцидент подтверждает эффективность системы безопасности. Ну, скажем, у нас стоит какая-то система мониторинга и защиты внешней почты, однако, при работе ни с одним инцидентом прилетевшим по почте она не использовалась - с этим надо что-то делать. Или у нас стоит дорогущая система контентной фильтрации, однако все внешние взломы через Веб мы фиксировали уже по успешным отстукам ботов на свои C&C по логам внутренней IDS - свидетельствует что все либо ходят мимо нашего прокси, либо он настроен некорректно...

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





Sunday, November 16, 2014

ZeroNights2014

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


Демонстрационное видео, традиционно, у Миши в канале:
Извлечение неэкспортируемого контейнера секретного ключа из APDU-трафика:
http://www.youtube.com/watch?v=9ugl1Xwh5s4
Извлечение неэкспортируемого контейнера секретного ключа при помощи утилиты Antitoken (эмуляция работы приложения криптопровайдера):
http://www.youtube.com/watch?v=TrcBM_bBq6E
Извлечение неэкспортируемого контейнера секретного ключа при помощи утилиты secretdump4cp (патчинг флага неэкспортируемаости в памяти процесса):
http://www.youtube.com/watch?v=7Jg73qbZqC0
Атаки на пароль пользователя:
http://www.youtube.com/watch?v=v4Q4d-i04lk

Все используемые утилиты доступны в Git: https://github.com/votadlos/Antitoken

Выступление снималось, вероятно, будет видео.

Несколько слов об обсуждении с залом.
Посыл из зала 1: Данная схема с токенами не предполагает использование на скомпрометированном компьютере.
Ответ 1: Вся презентация про то, что токен нужен только для того, чтобы ключ там хранился неизвлекаемым образом. Если ключ из токена неизвлекаем, то токен безопасно вставлять в скомпрометированный компьютер - ключ из токена не будет утащен. Верно и другое утверждение: если для использования токена мы требуем доверенность компьютера (т.е., что токен можно использовать исключительно на нескомпрометированном компьютере), то токен нам не нужен: действительно, если компьютер не может быть взломан, то ключ из компьютера не может быть извлечен :)
Посыл из зала 1': Если токен, даже с неизвлекаемым ключом будет использоваться на скомпрометированном компьютере, то эта схема не будет безопасной, так как злоумышленник сможет генерить подпись (и прочие криптопреобразования) не экспортируя при этом ключ.
Ответ 1': Вот с этим согласен! Но этот случай несколько более сложен, чем просто скопировать (экспортировать) ключ и далее использовать его по своему усмотрению.
Посыл из зала 2: То что вы показали - это верно для КС1, а для КС2 так не сработает.
Ответ 2: Во-первых, я не знаю где взять нормальное техническое описание КС1, КС2 и пр. Технические спецификации этих КС* также защищены "дополнительным уровнем защиты" о котором упомянуто на слайде 8. А во-вторых, мы исследовали самую распространенную схему применения ГОСТовой криптографии, причем эта схема позволяет подпись считать квалифицированной. В моем понимании безопасность должна постоянно адаптироваться под среду, о чем я не раз писал, поэтому надо строить защиту не от каких-то сферических моделей нарушителей в вакууме, а от наиболее распространенных сценариев атак. К сожалению, на практике мы имеем, что самая распространенная схема использования ГОСТовой криптографии с токенами вместе с тем является самой небезопасной, при том, что есть более безопасные схемы.


Saturday, November 8, 2014

ELK в технологии

Переменка.
Тренировался в способах импорта данных в Elasticsearch, так же хотелось поиграться с "интенсивными и объемными" данными. Попросил данные у метрологов за месяц. Отдали с улыбкой, сказав, что какая-то жутко прогрессивная и дорогая система визуализации данных не справилась с их объемами, поэтому анализ больше чем за 1 день сделать не получается.
Получите и распишитесь.

Характеристика данных:
1. Объем данных 7.2 гб
2. Количество записей 122 000 000
3. Количество параметров: 713
4. Период месяц

Старый десктоп и пара ноутбуков (2-4 CPU, 4Gb RAM) собранные в кластер делают месячную выборку по 4м параметрам за несколько секунд.

Схема или, в терминах эластика, mapping:
 "sdku_type": {  
  "_all" : {"enabled" : false},    
  "_source" : {"enabled" : false},    
  "properties": {  
  "@timestamp": {  
   "type": "date",  
   "format": "dateOptionalTime"  
  },  
  "field": {  
   "type": "string"  
  },  
  "value":{  
   "type": "double"  
  }  
  }  
 }  

Скрипт для импорта:

 #!/usr/bin/python  
 import csv, sys, time, json, elasticsearch  
 from elasticsearch import helpers  
 es = elasticsearch.Elasticsearch(['localhost:9200'])  

 csvfile = 'MyTable.csv'  
 jdata = dict()  
 actions = list()  
 i = 0  

 with open(csvfile, 'rb') as file :  
   line = csv.reader(file, delimiter = ',', skipinitialspace = True)  
   for row in line :  
      i += 1  
      ptime = time.strptime(row[0][0:19], "%Y-%m-%d %H:%M:%S")   
      ctime = time.strftime('%Y-%m-%dT%H:%M:%S', ptime)   
      jdata = { '@timestamp': ctime, 'field': row[1], 'value': float(row[2]) }  
      action = { '_index': 'sdku', '_type': 'sdku_type', '_id': i, '_source': json.dumps(jdata, separators=(',', ':'))}  
      actions.append(action)  
      if i % 1000000 == 0:  
        elasticsearch.helpers.bulk(es, actions)  
        print "Indexed %d, working on next 100000" %(i)  
        actions = list()  
   elasticsearch.helpers.bulk(es, actions)  
   print "Indexed %d, finishing." %(i)  

Результат:

Возникла дилемма - показать результат и оказаться втянутым в работу метрологической службы или сделать вид, что проиграл?

Wednesday, November 5, 2014

ELK: Анализ почтовых журналов. Подготовка

Продолжим тематику визуального анализа журналов. С журналов доступа в сеть Интернет переключимся на почтовые.
Начнем с получения журналов с почтового сервера и их подготовку к передаче ELK.
Так получилось, что в моей сети в качестве внутреннего почтового сервера используется Microsoft Exchange 2003. Каким-то неведомым мне образом, раз в сутки в почту падает файл с архивом почтового журнала сервера за предыдущий день. Мы пытались настоять на том, чтобы журналы отправлялись по протоколу syslog c помощью snare, но в этом было отказано под "уважительным" предлогом "высокой чувствительности пользователей к минимальным задержкам в работе сервиса".
Сначала письмо, как и множество других, проходит через procmail. Оно попадает под действие правила:
 :0:  
 * ^Subject(.*Exchange log file*)  
 {  
   :0 Bcw  
   | /home/sa/bin/logs/ExtractAttachment.pl  
   :0 a  
   | /home/sa/bin/logs/ImportMaillog.pl  
   :0  
   inbox/mailstat/.  
 }  

Скрипт "/home/sa/bin/logs/ExtractAttachment.pl" является вариантом этого скрипта.
За скрипт "home/sa/bin/logs/ImportMaillog.pl" не судите строго. Он писался в режиме "быстрее хоть что-нибудь" и сейчас исправлять его не хочется, потому-что "работает!".
 use strict;  
 use Encode qw(decode);  
 use Time::Local;  
 use Sys::Syslog;  
 use open qw(:std :utf8);  
 my $configfile = "/home/sa/bin/logs/rcfile";  
 my $conf = new Config::General("$configfile");  
 my %config = $conf->getall;  
 open (FILE, "<:encoding(utf8)", "/tmp/maillog.tmp") or die "Can't open file /tmp/maillog.tmp!\n";  
 open (OFILE, ">/tmp/maillog") or die "unable to open /tmp/maillog !";  
 openlog("Secure_Maillog", "ndelay", "local0");  
 while (<FILE>) {  
   s/\<\>/postmaster\@udmurtneft.ru/g;  
   my @str = split(/\t/);  
   my $str18 = "";  
   if ( $str[8] =~ /102[80]/ ) {  
      if ( $str[18] =~ /=?/ ) {  
        $str[18] =~ s/UNICODE-1-1-UTF-8/UTF-8/g;  
        $str[18] =~ s/unicode-1-1-utf-7/UTF-8/g;  
        $str[18] =~ s/x-user-defined/UTF-8/g;  
        $str[18] =~ s/gb18030/windows-1251/g;  
        $str[18] =~ s/window-1251/windows-1251/g;  
        $str[18] =~ s/UNKNOWN/windows-1251/g;  
        $str[18] =~ s/134/windows-1251/g;  
        my $flag = utf8::is_utf8($str[18]);  
           $str[18] = Encode::decode('MIME-Header',$str[18]);  
           $str18 = $str[18];  
      }  
      $str[1] =~ s/ GMT//g;  
      my $time = $str[0]." ".$str[1];  
      my @t = ($time =~ /^(\d{4})-(\d{1,2})-(\d{1,2})\s(\d{1,2}):(\d{1,2}):(\d{1,2})/);  
      $t[1]--; $t[3] = $t[3]+4;  
      if ( $t[3] > 23 ) { $t[3] = $t[3] - 24 };  
      my $timestamp = timelocal 0,@t[4,3,2,1,0];  
      print OFILE "\t$timestamp\t$str[19]\t$str[7]\t$str[12]\t$str[18] \n";  
      syslog('mail|info', $timestamp."\t".$str[19]."\t".$str[7]."\t".$str[12]."\t".$str[18]);  
   }  
 }  
 closelog();  
 close(OFILE);  
 system("mysqlimport --local logs /tmp/maillog --user=$config{db}->{user} --password=$config{db}->{password}");  
 unlink("/tmp/maillog.tmp");  
 unlink("/tmp/maillog");  
 unlink("/tmp/report.zip");  
Важные строки выделены жирным. Первая из них передает строку журнала в syslog, а оттуда в logstash. Вторая записывает в олдскульный sql для тяжелого анализа.
В следующий раз, чтобы разбавить тему анализа глазами. рассмотрим что можно достать из SQL.
PS. Если вы захотите отметить, что хранить временные файлы в общей директории /tmp не безопасно, то ответа будет два:
1. На сервере, куда падают журналы, все пользователи имеют доступ к ним.
2.
 $ cat /etc/profile | grep umask  
 umask 077