воскресенье, 30 октября 2016 г.

OpenSSL: Ручная проверка сертификата по CRL

Перевод: OpenSSL: Manually verify a certificate against a CRL
Автор: Реми ван Элст (Remy van Elst)

Содержание
  1. Получение сертификата с CRL
  2. Получение цепочки сертификатов
  3. Соединение CRL и цепочки
  4. Проверка OpenSSL
  5. Отозванный сертификат
В этой статье будет показано, как можно вручную проверить сертификат по CRL. CRL означает Certificate Revocation List - список отозванных сертификатов - и является одним из способов проверки статуса сертификата. Этот способ является альтернативой для OCSP - Online Certificate Status Protocol - протокола интерактивного статуса сертификата.

Больше о CRL можно прочитать на Википедии.

Если нужно проверить сертификат по OCSP, обратитесь к другой моей статье.

Воспользуемся OpenSSL. Я использую такую версию:
$ openssl version
OpenSSL 1.0.2 22 Jan 2015
Получение сертификата с CRL

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

openssl s_client -connect wikipedia.org:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p'
Сохраним вывод в файл, например, wikipedia.pem:
openssl s_client -connect wikipedia.org:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > wikipedia.pem
Теперь проверим, есть ли у этого сертификата URI CRL:
openssl x509 -noout -text -in wikipedia.pem | grep -A 4 'X509v3 CRL Distribution Points'
X509v3 CRL Distribution Points: # Точки распространения X509v3 CRL
    Full Name:                                                                           # Полное имя
      URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl
Если ничего не выведено, значит у сертификата нет URI CRL. Его нельзя проверить по CRL.

Скачиваем CRL:
wget -O crl.der http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl
CRL имеет двоичный формат DER. Команде OpenSSL нужен файл в формате PEM (base64-кодированный DER), поэтому преобразуем его:
openssl crl -inform DER -in crl.der -outform PEM -out crl.pem
Получение цепочки сертификатов

Кроме проверяемого сертификата нужна цепочка сертификатов. Поэтому нужно получить цепочку сертификатов для проверяемого домена - wikipedia.org. Воспользовавшись опцией -showcerts команды openssl s_client, можно увидеть все сертификаты, принадлежащие цепочке:
openssl s_client -connect wikipedia.org:443 -showcerts 2>&1 < /dev/null
Будет выведено много текста, но нас интересует в нём следующее:
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
-----BEGIN CERTIFICATE-----
MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR
CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv
KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5
BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf
1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs
zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d
32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w
ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm
MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB
hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln
aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl
cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME
GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB
INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a
vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j
CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X
dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE
JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY
Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E=
-----END CERTIFICATE-----
Как можно увидеть, это номер 1. Номер 0 - это сертификат Википедии, который у нас уже есть. Если у проверяемого сайта в цепочке имеется больше сертификатов, они все будут отображены. Сохраним все сертификаты в том порядке, в котором их вывел OpenSSL (первый, который непосредственно выпустил сертификат проверяемого сервера, затем тот, который выпустил этот сертификат и так далее с корневым или самым корневым в конце файла) в файл с именем chain.pem.

Можно использовать следующую команду для сохранения всех сертификатов, выведенных командой OpenSSL, в файл с именем chain.pem. Обратитесь к этой статье за более подробной информацией.
OLDIFS=$IFS; \
IFS=':' certificates=$(openssl s_client -connect wikipedia.org:443 -showcerts -tlsextdebug -tls1 2>&1 < /dev/null \
                         | sed -n '/-----BEGIN/,/-----END/ {/-----BEGIN/ s/^/:/; p}'); \
for certificate in ${certificates#:}; do \
  echo $certificate | tee -a chain.pem ; \
done; \
IFS=$OLDIFS
Объединение CRL и цепочки

Команде openssl для проверки нужны цепочка сертификатов и CRL в формате PEM, соединённые вместе. Можно пропустить CRL, но тогда проверка по CRL не будет выполнена, произойдёт проверка только сертификата по цепочке.
cat chain.pem crl.pem > crl_chain.pem
Проверка OpenSSL
Теперь у нас есть все данные, необходимые для проверки сертификата.
$ openssl verify -crl_check -CAfile crl_chain.pem wikipedia.pem
wikipedia.pem: OK
Результат показывает, что сертификат действительный.

Отозванный сертификат

Если имеется отозванный сертификат, его так же можете проверить способом, описанным выше. Ответ будет выглядеть следующим образом:
$ openssl verify -crl_check -CAfile crl_chain.pem revoked-test.pem
revoked-test.pem: OU = Domain Control Validated, OU = PositiveSSL, CN = xs4all.nl
error 23 at 0 depth lookup:certificate revoked                                    # ошибка 23 на 0 глубине поиска: сертификат отозван
Имея сертификат и цепочку, эти проверки можно выполнить странице Verisign для проверки отозванных сертификатов: https://test-sspev.verisign.com:2443/test-SSPEV-revoked-verisign.html.

воскресенье, 23 октября 2016 г.

Команды OpenSSL для преобразования сертификатов на своём компьютере

Перевод: SSL Converter

Воспользуйтесь этим преобразователем SSL для преобразования сертификатов SSL между различными форматами, такими как pem, der, p7b и pfx.

Разные платформы и устройства требуют преобразовывать сертификаты SSL в разные форматы. Например, Windows-сервер экспортирует и импортирует файлы .pfx, а сервер Apache использует отдельные файлы PEM (.crt, .cer). Чтобы воспользоваться преобразователем SSL, просто выберите файл сертификата и его текущий тип (произойдёт попытка определить тип по расширению файла), затем выберите тип, в который нужно преобразовать сертификат и нажмите Преобразовать сертификат. Подробности о различных типах сертификатов SSL и о том, как можно преобразовать сертификаты на своём компьютере с помощью OpenSSL, смотрите ниже.

Формат PEM

Формат PEM - наиболее распространённый формат сертификатов, выпускаемых удостоверяющими центрами. Сертификаты PEM обычно имеют расширения .pem, .crt, .cer и .key. Это ASCII-файлы с информацией, закодированной в Base64, и содержащие выражения "-----BEGIN CERTIFICATE-----" и "-----END CERTIFICATE-----". Сертификаты сервера, промежуточные сертификаты и приватные ключи могут быть записаны в формате PEM.

Apache и другие подобные серверы используют сертификаты в формате PEM. Несколько сертификатов PEM и даже приватный ключ можно поместить в одном файле друг за другом, но большинство платформ, таких как Apache, берут сертификат и приватный ключ из отдельных файлов.

Формат DER

Формат DER - это просто двоичный вид сертификата, в отличие от PEM, который закодирован в символы ASCII. Иногда встречается расширение файла .der, но чаще у файла бывает расширение .cer. Чтобы узнать, имеет ли этот файл формат DER или PEM, можно открыть его в текстовом редакторе и поискать выражения BEGIN и END. Все типы сертификатов и приватных ключей могут быть представлены в формате DER. Обычно DER используется на платформе Java. Инструмент для преобразования SSL умеет преобразовывать в формат DER только сертификаты. Если нужно преобразовать в формат DER приватный ключ, воспользуйтесь командами OpenSSL, приведёнными на этой странице.

Формат PKCS#7/P7B

Формат PKCS#7 или P7B обычно сохраняется в виде ASCII, закодированным в Base64, и имеет расширение .p7b или .p7c. Сертификаты P7B содержат выражения "-----BEGIN PKCS7-----" и "-----END PKCS7-----". Файл P7B содержит только сертификаты и цепочки сертификатов, но не приватные ключи. Некоторые платформы поддерживают файлы P7B, в том числе Microsoft Windows и Java Tomcat.

Формат PKCS#12/PFX

Формат PKCS#12 или PFX - это двоичный формат для хранения сертификата сервера, промежуточных сертификатов и приватного ключа в одном зашифрованном файле. Файлы PFX обычно имеют расширение .pfx или .p12. Файлы PFX обычно используются на компьютерах под управлением Windows для импорта и экспорта сертификатов и приватных ключей.

При преобразовании файла PFX в формат PEM, OpenSSL поместит все сертификаты и приватный ключ в один файл. Для этого нужно открыть файл в текстовом редакторе и скопировать каждый сертификат и приватный ключ (включая выражения BEGIN/END) в отдельные текстовые файлы и сохранить их под именами certificate.cer, CACert.cer и privateKey.key соответственно.

Команды OpenSSL для преобразования сертификатов SSL на своём компьютере

Настоятельно рекомендуется преобразовывать файлы .pfx на своём компьютере с помощью OpenSSL. Это позволит сохранить приватный ключ в тайне. Воспользуйтесь следующими командами OpenSSL для преобразования сертификата SSL в различные форматы на своём компьютере:

Преобразование PEM с помощью OpenSSL
  • Преобразование PEM в DER:
    openssl x509 -outform der -in certificate.pem -out certificate.der
  • Преобразование PEM в P7B:
    openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfile CACert.cer
  • Преобразование PEM в PFX:
    openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt
Преобразование DER с помощью OpenSSL
  • Преобразование DER в PEM:
    openssl x509 -inform der -in certificate.cer -out certificate.pem
Преобразование P7B с помощью OpenSSL
  • Преобразование P7B в PEM:
    openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
  • Преобразование P7B в PFX:
    openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
    openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.pfx -certfile CACert.cer
Преобразование PFX с помощью OpenSSL
  • Преобразование PFX в PEM:
    openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes

воскресенье, 16 октября 2016 г.

Наиболее часто используемые команды OpenSSL

Перевод: The Most Common OpenSSL Commands

Одна из наиболее многофункциональных утилит SSL - это OpenSSL, которая является реализацией протокола SSL с открытым исходным кодом. Существуют версии OpenSSL почти для каждой платформы, включая Windows, Linux и Mac OS X. OpenSSL чаще всего используется для создания запросов на подпись сертификата и приватных ключей для множества различных платформ, включая Apache. Однако, есть ещё сотни различных функций, которые позволяют увидеть информацию из запроса на сертификат или из сертификата, сравнить хэш MD5 сертификата и приватного ключа (чтобы убедиться в том, что они соответствуют друг другу), проверить, что сертификат веб-сайта установлен правильно, преобразовать сертификат в другой формат. Скомпилированную версию OpenSSL для Windows можно найти здесь.

Если вам не хочется разбираться с OpenSSL, то многое из этого можно сделать при помощи наших инструментов для сертификатов SSL. Ниже мы привели наиболее часто используемые команды OpenSSL:

Общие команды OpenSSL

Эти команды позволят вам сгенерировать запрос на подпись сертификата, сертификат, приватный ключ и решить другие задачи.
  • Создание нового приватного ключа и запроса на подпись сертификата:
    openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key
  • Создание самозаверяющего сертификата (за дополнительной информацией обратитесь к статье Как создать и установить самозаверяющий сертификат в Apache):
    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt
  • Создание запроса на подпись сертификата для существующего приватного ключа:
    openssl req -out CSR.csr -key privateKey.key -new
  • Создание запроса на подпись сертификата на основе имеющегося сертификата:
    openssl x509 -x509toreq -in certificate.crt -out CSR.csr -signkey privateKey.key
  • Удаление ключевой фразы из приватного ключа:
    openssl rsa -in privateKey.pem -out newPrivateKey.pem
Проверка при помощи OpenSSL

Если нужно проверить информацию в сертификате, в запросе на подпись сертификата или в приватном ключе, воспользуйтесь следующими командами. Также можно проверить запрос на подпись сертификата и проверить сертификат с помощью наших интерактивных инструментов.
  • Проверка запроса на подпись сертификата:
    openssl req -text -noout -verify -in CSR.csr
  • Проверка приватного ключа:
    openssl rsa -in privateKey.key -check
  • Проверка сертификата:
    openssl x509 -in certificate.crt -text -noout
  • Проверка файла PKCS#12 (.pfx или .p12):
    openssl pkcs12 -info -in keyStore.p12
Отладка с помощью OpenSSL

При получении сообщения об ошибке, что приватный ключ не соответствует сертификату или что сертификат, установленный на веб-сайт, не заслуживает доверия, попробуйте одну из следующих команд. Если нужно проверить, правильно ли установлен этот сертификат SSL, попробуйте также наш инструмент для проверки SSL.
  • Проверить, что хэш MD5 публичного ключа соответствует указанному в запросе на подпись сертификата или в приватном ключе:
    openssl x509 -noout -modulus -in certificate.crt | openssl md5
    openssl rsa -noout -modulus -in privateKey.key | openssl md5
    openssl req -noout -modulus -in CSR.csr | openssl md5
  • Проверить подключение SSL. Должны отобразиться все сертификаты (включая промежуточные):
    openssl s_client -connect www.paypal.com:443
Преобразование с помощью OpenSSL

Эти команды позволяют преобразовать сертификаты и ключи в различные форматы, совместимые с определёнными типами серверов и программного обеспечения. Например, можно преобразовать обычный файл PEM, который используется с Apache, в файл PFX (PKCS#12) и использовать его с Tomcat или IIS. Воспользуйтесь нашим инструментом для преобразования SSL, чтобы преобразовать сертификаты без помощи OpenSSL.
  • Преобразование файла DER (.crt .cer .der) в PEM:
    openssl x509 -inform der -in certificate.cer -out certificate.pem
  • Преобразование файлов PEM в DER:
    openssl x509 -outform der -in certificate.pem -out certificate.der
  • Преобразование файла PKCS#12 (.pfx .p12), содержащего приватный ключ и сертификат, в PEM:
    openssl pkcs12 -in keyStore.pfx -out keyStore.pem -nodes
    Можно добавить опцию -nocerts, чтобы вывести только приватный ключ, или опцию -nokeys, чтобы вывести только сертификат.
  • Преобразование файла сертификата и приватного ключа PEM в PKCS#12 (.pfx .p12):
    openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

воскресенье, 9 октября 2016 г.

Хакинг TV Motion Detector VG

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

Для начала несколько слов о самой программе. Программа предназначена для мониторинга аналоговых телеканалов и, насколько я могу судить, довольно популярна у операторов кабельного телевидения. Программа поочерёдно переключает каналы на ТВ-тюнере и проверяет, есть ли на канале звук, двигается ли изображение. Программа умеет вызывать другие программы в случае если проблема была только что обнаружена, обнаружена повторно или произошло восстановление вещания. Подробнее о TV Motion Detector VG можно почитать на официальном сайте. Ещё один немаловажный момент - программа бесплатная. Пусть это будет ещё одним аргументом в пользу того, что эта заметка написана не за деньги и не является скрытой рекламой :)

TV Motion Detector VG использует файл scanfreq.txt со списком частот каналов и файл channels.sqlite со списком каналов в таблице channels, журналом событий в таблице log и списком запланированных задач в таблице scheduler. Имеется база данных, в которой инженеры головной станции поддерживают актуальный список каналов с их номерами, частотами и названиями. Специальная самописная программа запрашивает список каналов из базы данных, наполняемой инженерами головной станции, формирует эти два файла и через Zabbix API создаёт нужные элементы данных и триггеры для каждого канала. В сформированном файле channels.sqlite в таблице scheduler создаются записи, которые предписывают каждый час вызывать bat-файл, который завершает TV Motion Detector VG, вызывает программу, обновляющую Zabbix и эти два файла, а потом запускает TV Motion Detector VG снова. В таблице channels из файла channels.sqlite для каждого канала указываются скрипты, которые надо вызывать в случае проблем на канале, в случае продолжающихся проблем и в случае восстановления канала. В качестве таких скриптов используется утилита zabbix_sender. Программа TV Motion Detector VG прописана в автозагрузку Windows. В Zabbix кроме состояния каналов контролируется ещё и момент, когда в последний раз приходили данные от TV Motion Detector VG. Таким образом получаем практически полностью автономно работающую систему из трёх звеньев - базы каналов, TV Motion Detector VG и Zabbix.

Ручное вмешательство бывает нужно, если компьютер с TV Motion Detector VG был перезагружен. В этом случае в Zabbix срабатывает триггер о том, что давно не поступали данные из TV Motion Detector VG. Дежурный инженер заходит на компьютер с Windows по RDP, TV Motion Detector VG автоматически запускается, а дежурный инженер отсоединяется от сеанса. Дальше всё продолжает работать.

Бывает, что требуется ручное вмешательство другого рода. Если в частотном плане появляются новые частоты или пропадают старые, то TV Motion Detector VG (или драйвер ТВ-тюнера) сходит с ума и реально настраивается не на те каналы, которые соответствуют частоте канала в таблице channels из файла channels.sqlite. В таком случае помогает простое лечение - нажать кнопку Scan, дождаться окончания сканирования, после чего можно обновить файлы channels.sqlite, scanfreq.txt и запустить TV Motion Detector VG снова.

Вмешательства такого рода требуются довольно редко. А вот следующий недостаток изрядно подрывает всю кропотливо выстроенную систему.


Если приглядеться, то в нижней строчке под списком каналов программы можно увидеть текст "count: 50". Дело в том, что после перезапуска программа считает, что есть только 50 каналов. Только по ним она и проходится циклически, оставляя за пределами контроля ещё 11 каналов. Если вручную потянуть линейку прокрутки в списке каналов до конца, то программа отображает остальные каналы и после этого уже начинает проходиться циклически по каждому из 61 каналов. Но, напомню, программа в описанной выше схеме перезапускается каждый час. Поэтому ручное вмешательство не годится.

Первым делом я подумал, что программа при запуске выполняет SQL-запрос на получение списка каналов с ограничением LIMIT 50. Я открыл EXE-файл в шестнадцатеричном редакторе и нашёл все запросы SELECT. Был среди них такой запрос "SELECT COUNT(inc) as countinc, MAX(number) as maxnumber FROM channels;". Я проверил, что он возвращает и убедился, что обнаруживается ровно 61 канал.

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

Снова попробовал поискать что-нибудь в шестнадцатеричном редакторе. Естественно, таких мест оказалось довольно много. Не знаю, что натолкнуло меня на мысль попробовать ArtMoney, потому что изначально было ясно, что даже если я и найду эти счётчики в оперативной памяти, то как потом мне найти и исправить их в файле EXE? Если они не хранятся в секции .BSS или подобной ей, то найти нужные константы в ассемблерном коде будет непросто. Да и даже если они хранятся в такой секции - у меня нет опыта правки EXE-файлов. Всё же решил для любопытства найти этот счётчик при помощи ArtMoney.

Попытка поиска увенчалась успехом - я нашёл аж две ячейки памяти, в которых хранились 32-битные числа, соответствовавшие количеству каналов в списке. Попытки исправить это число на 61 давали эффект ровно до того момента, когда программа заканчивала просмотр пятидесятого канала и пыталась приступить к следующему. Дальше программа ежесекундно выбрасывала окошки с сообщениями об ошибке до тех пор, пока я не возвращал в обе ячейки прежнее число 50.

Потом я сделал перерыв на обед. Пока шёл в столовую, подумал что свойства компонентов на форме могут оказаться прописаны в ресурсах Windows, вшитых в EXE-файл. Когда вернулся с обеда, решил проверить это предположение. В прошлом я доставал из EXE- и DLL-файлов встроенные в них пиктограммы, курсоры и картинки с помощью программы ResEdit. Скачал программу с официальной страницы. Из всех ресурсов наиболее многообещающим выглядел ресурс с именем TFORMMAIN. Но ResEdit отображал этот ресурс как блок двоичных данных.

Интересующий меня ресурс начинался с сигнатуры TPF0. Я поискал в интернете и понял, что это формы Delphi. В проекте Delphi у файлов этих форм бывает расширение DFM. Решил поискать, чем можно открыть такой файл на просмотр и редактирование. Вышел на программу ResourceHacker, которую можно скачать на странице разработчика - Ангуса Джонсона. Скачал программу и открыл интересующий меня ресурс на просмотр и редактирование. Стал изучать, какие компоненты присутствуют на форме и какие их свойства можно было бы поправить.

В процессе изучения, сопровождавшегося поиском в интернете, понял, что программа для доступа к SQLite использует компоненты AnyDAC Дмитрия Арефьева. К сожалению, документацию на AnyDAC найти в Интернете мне не удалось. Дело в том, что AnyDAC была продана фирме Embarcadero и превратилась в FireDAC. Удалось найти документацию только на библиотеку FireDAC. Оставалась слабая надежда на то, что библиотека изменилась не очень сильно и опции из FireDAC подойдут для AnyDAC.

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

Верное направление для поисков было нащупано в ветке форума на www.sql.ru, где обсуждался FireDAC. Список всех возможных значений нашёлся в статье документации FireDAC.Stan.Option.TFDFetchOptions.RecordCountMode. На каком-то этапе я попробовал вставить в описание объекта ADTableChannels после 1738 строчки декомпилированного ресурса TFORMMAIN свойство FetchOptions.RecordCountMode = cmTotal:

Затем скомпилировал изменения нажав на зелёный треугольник и перезаписал файл EXE. Когда запустил программу, то увидел в строчке count вожделенное значение 61. Оставалось убедиться, что после 50 канала программа переключится на 51 канал и дойдёт до конца списка. Всё сработало, как надо:

В этот момент я испытал облегчение, радость и удивление от того, что поиски и эксперименты в конечном итоге привели к успеху. С одной стороны, я не надеялся на успех. Уж слишком были призрачными надежды на него. У читателей этого блога может сложиться впечатление, что все задачи, которые я перед собой ставлю, в конечном итоге завершаются успешно. Однако это не всегда бывает так. Иногда эксперименты заходят в тупик и очередная задача так и остаётся нерешённой. Раз нет решения, то и писать не о чем. С другой стороны, пока голова не перестала генерировать новые предположения и пока они все не проверены, остаётся надежда на успех. В этот раз мне повезло :)

P.S. Несколько замечаний о законности описанной выше модификации программы.
УК РФ, Статья 272. Неправомерный доступ к компьютерной информации.

(в ред. Федерального закона от 07.12.2011 N 420-ФЗ)

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

наказывается штрафом в размере до двухсот тысяч рублей или в размере заработной платы или иного дохода осужденного за период до восемнадцати месяцев, либо исправительными работами на срок до одного года, либо ограничением свободы на срок до двух лет, либо принудительными работами на срок до двух лет, либо лишением свободы на тот же срок.
Источник - сайт компании "КонсультантПлюс". УК РФ, Статья 272. Неправомерный доступ к компьютерной информации

Однако, в комментариях к УК РФ имеются следующие оговорки:
1. Модификация информации - внесение изменений в компьютерную информацию (в том числе изменение её параметров) без согласия её законного обладателя. Действующим законодатесльством разрешены следующие виды легальной модификации программ, баз данных лицами, правомерно владеющими этой информацией: а) модификация в виде исправления явных ошибок; б) модификация в виде внесения изменений в программы, базы данных для их функционирования на технических средствах пользователя; в) модификация в виде частной декомпиляции программы для достижения способности к взаимодействию с другими программами.
Источник - книга "Комментарий к Уголовному кодексу Российской Федерации (постатейный), Том 2" под редакцией Бриллиантова А.В. Глава 28. Преступления в сфере компьютерной информации. Статья 272. Неправомерный доступ к компьютерной информации

Ещё один источник - сайт адвокатского бюро "Домкины и партнёры". Методические рекомендации по осуществлению прокурорского надзора за исполнением законов при расследовании преступлений в сфере компьютерной информации

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

воскресенье, 2 октября 2016 г.

Настройка ipfw во FreeBSD

Некоторое время назад наводил порядок в фаерволлах на серверах FreeBSD, доставшихся в наследство от прошлых системных администраторов. Захотелось сразу продумать фаерволл таким образом, чтобы потом в нём было легко ориентироваться и было очевидно, как в него добавить новое правило. Использовался фаерволл ipfw и его таблицы. Я решил не менять фаерволл на ipf или pf, а просто последовательно преобразовывать имеющиеся правила в понятную структуру, пока меня не устроит конечный результат. Результатом и хочу поделиться, как одним из примеров того, как можно организовать фаерволл.

Включение фаерволла

В файле /etc/rc.conf должны быть две строчки, предписывающие включить фаерволл и использовать правила из файла /etc/firewall.conf:
firewall_enable="YES"
firewall_script="/etc/firewall.conf"
Написание правил

Теперь приведу упрощённый пример файла /etc/firewall.conf:
fw='/sbin/ipfw -q'
${fw} -f flush

${fw} add pass all from any to any via lo0
${fw} add deny all from any to 127.0.0.0/8
${fw} add deny all from 127.0.0.0/8 to any
${fw} add check-state
${fw} add allow ip from me to any keep-state

########## ping ##########
${fw} add allow icmp from any to me in via em0 keep-state

########## ssh ##########
table_ssh=100
${fw} table $table_ssh flush
${fw} add allow tcp from "table($table_ssh)" to me 22 in via em0 keep-state

# lan gateway
${fw} table $table_ssh add 192.168.0.1
# office computers
${fw} table $table_ssh add 192.168.0.128/25

#########################################
${fw} add deny ip from any to any
Фаерволл разрешает серверу устанавливать любые исходящие подключения. Любому внешнему сетевому узлу разрешается выполнять ICMP-запросы (среди которых могут быть не только запросы Ping). Последнее правило запрещает любой входящий трафик, который не разрешён явным образом.

В начале файла есть команда, которая очищает текущий список правил фаерволла:
${fw} -f flush
При очистке списка правил таблицы остаются нетронутыми. Поэтому внутри каждого блока, разрешающего доступ к определённому сервису на сервере, выполняется очистка соответствующей таблицы:
${fw} table $table_ssh flush
После очистки таблицы в списке правил фаерволла создаётся необходимое правило, а затем наполняется таблица, связанная с этим правилом.

Наибольший интерес представляет блок, разрешающий подключения по SSH и продолжающийся вплоть до последнего правила. Чтобы разрешить доступ к ещё одному сервису, можно скопировать блок, переименовать переменную, хранящую номер таблицы, поменять сам номер таблицы. Затем нужно заменить имя таблицы в последующих строчках, отредактировать само правило и изменить список разрешённых IP-адресов и сетей, которые будут добавлены в таблицу. Например, можно добавить блок, разрешающий доступ по HTTP:
########## http ##########
table_http=110
${fw} table $table_http flush
${fw} add allow tcp from "table($table_http)" to me 80 in via em0 keep-state

# office computers
${fw} table $table_http add 192.168.0.128/25
# zabbix server
${fw} table $table_http add 192.168.0.2
Применение правил

Как видно, всё очень просто. Для применения изменений нужно выполнить всего одну команду:
# /etc/rc.d/ipfw restart
Будьте внимательны, не допускайте ошибок в файле - иначе он может выполниться не до конца и можно потерять удалённый доступ к серверу. Советую первыми в список включать правила для SSH - тогда они будут отрабатывать раньше, чем интерпретатор дойдёт до строки с ошибкой и отбросит весь остаток файла. Вероятность того, что правила SSH будут применены при ошибках в других более часто редактируемых правилах, будет выше. А ещё лучше перед применением отредактированного файла изменить значение переменной fw с этого:
fw='/sbin/ipfw -q'
На вот это:
fw='/sbin/ipfw -q -n'
Команды не будут выполняться реально, будет только проверен их синтаксис. Если сообщений об ошибках не получено, то можно вернуть значение fw на исходное и снова выполнить команду, уже для реального применения изменений.

Вид правил в системе

Ещё одно достоинство этого фаерволла - он получается простым, т.к. в самом фаерволле есть всего несколько правил. Для наглядности приведу реальный список правил в фаерволле на одном из серверов:
# ipfw list
00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
00400 check-state
00500 allow ip from me to any keep-state
00600 allow icmp from any to me in via em0 keep-state
00700 allow tcp from table(110) to me dst-port 3306 in via em0 keep-state
00800 allow tcp from table(111) to me dst-port 10054 in via em0 keep-state
00900 allow tcp from table(112) to me dst-port 80 in via em0 keep-state
01000 allow tcp from table(116) to me dst-port 22 in via em0 keep-state
01100 allow udp from table(117) to me dst-port 69 in via em0 keep-state
01200 allow tcp from table(118) to me dst-port 48048 in via vlan32 keep-state
01300 allow udp from table(119) to me dst-port 162 in via em0
01400 deny ip from any to any
65535 deny ip from any to any
Трудно запутаться в семи существенных правилах, не так ли?

Второе достоинство фаерволла - он достаточно быстр, т.к. сравнение IP-адресов клиентов происходит с использованием таблиц, а не при помощи отдельных правил, которые просматриваются последовательно. Посмотреть текущее содержимое любой из таблиц тоже довольно просто:
# ipfw table 118 list
10.1.206.0/24 0
10.1.217.0/24 0
Динамически обновляемые таблицы

Если нужно сделать так, чтобы IP-адреса и сети в таблицу добавлялись динамически, каким-нибудь внешним скриптом, то достаточно не вписывать команды, очищающие таблицу и добавляющие в неё какие-то правила. Например, вот так:
########## tftp ##########
table_tftp=120
${fw} add allow tcp from "table($table_tftp)" to me 69 in via em0 keep-state
Таким образом, при применении изменённых правил, динамически добавленные в таблицу адреса не исчезнут из таблицы.

Динамические правила

Поскольку мы настроили фаерволл с поддержкой состояний, то правила для обратного трафика будут добавляться в него динамически. Таким образом, нужно следить за тем, чтобы список динамических правил не переполнялся. Контролировать текущее количество динамических правил в списке и их максимальное возможное количество можно при помощи утилиты sysctl:
# sysctl net.inet.ip.fw.dyn_count
net.inet.ip.fw.dyn_count: 656
# sysctl net.inet.ip.fw.dyn_max
net.inet.ip.fw.dyn_max: 8192
Если значение первого счётчика будет близко подбираться к значению второго, то максимальное количество динамических правил можно увеличить при помощи sysctl:
# sysctl -w net.inet.ip.fw.dyn_max=16384
И чтобы это значение восстанавливалось при перезагрузке, нужно прописать его в файл /etc/sysctl.conf:
net.inet.ip.fw.dyn_max=16384