Watch dogs function что это

Обновлено: 04.07.2024

Параметр, включающий функцию сторожевого таймера. Сторожевой таймер - это счетчик времени, идущий внутри системы (отдельная микросхема на материнской плате, или функциональный блок внутри другой микросхемы) и постоянно сбрасываемый работающей программой (БИОС, UEFI, операционная система).

Постоянный сброс таймера говорит его контроллеру о том, что программа не зависла и работает. Если сброc этого таймера не происходит в течение определенного времени, это дает сигнал контроллеру на перезагрузку компьютера, т.к. программа зависла. В дополнение к этом может происходить сброс настроек БИОС (UEFI) до заводских. Так как часто "зависание" компьютера, неудача при загрузке связаны с неправильной настройкой параметров БИОС при разгоне компонентов компьютера.

Возможные варианты значений:
Disabled - Сторожевой таймер отключен.
Enabled - Сторожевой таймер включен.

Аппаратный «watchdog» или незаменимый помощник в борьбе с зависанием

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

В итоге мы получили устройство, которое подключается к расширительному спаренному USB-разъему на материнской плате.



Данное устройство имеет следующие возможности:

  1. Имитация нажатия кнопок POWER и RESET;
  2. Управление питанием USB-устройством (при условии, что у него нет отдельного источника);
  3. Управление гальванически развязанной контактной группой (реле). Можно поставить в разрез цепи питания;
  4. Индикаторные светодиоды (одним можно управлять, второй показывает режимы работы).

Алгоритм работы прост: внутри находятся два настраиваемых таймера, которые постоянно отсчитывают заданное время, по истечению которого имитируется нажатие соответствующих кнопок (POWER и RESET). Чтобы предотвратить случайную перезагрузку, необходимо периодически послать команду сброса таймера.

Лучше, чтобы за процедуру сброса таймеров отвечало целевое приложение, а не стороннее или системное (Cron, служба расписаний) по причине того, что вероятность сбоя в системе меньше, чем в приложении (хотя, у кого как).
Обмен информацией аналогичен консольному.

команда Описание Пример
help Краткая справка по командам help
LED1 Управление светодиодом, по умолчанию выключен LED1 ON
LED1 OFF
RELAY Управление реле, по умолчанию включено RELAY ON
RELAY OFF
KEY1 Имитация нажатия кнопки 1, по умолчанию не нажата KEY1 ON
KEY1 OFF
KEY2 Имитация нажатия кнопки 2, по умолчанию не нажата KEY2 ON
KEY2 OFF
C1 Управление таймером 1, связанным с кнопкой 1.
Установка времени в секундах, максимальное значение 32767.
Для отключения функции таймера, необходимо задать время равное 0.
C1 RES
C1 SET 60
C1 SET 0
C2 Управление таймером 2, связанным с кнопкой 2.
Установка времени в секундах, максимальное значение 32767.
Для отключения функции таймера, необходимо задать время равное 0.
C2 RES
C2 SET 60
C2 SET 0
USB Управление питанием USB, по умолчанию включено USB ON
USB OFF

В случае удачного выполнения команды возвращает «OK».
В случае некорректных данных возвращает «ERROR».
Признаком конца строки служит символ возврата каретки «\r». Также поддерживается режим «\r\n».


Устройство выполнено на базе контроллера STM32F103CA с аппаратной поддержкой USB. Библиотека работы с USB версии V4.0.0. Напряжение работы 3.3В получаем с помощью линейного стабилизатора из 5В на USB. Во всех управляющих цепях используются транзисторы в ключевом режиме. Также не забываем про защитный диод от токов самоиндукции в катушки реле (в моем случае он оказался встроенным).

Arduino watchdog или автоматический RESET в случае зависания



Речь пойдет о том, как держать Arduino всегда в работоспособном состоянии. Механизм watchdog встроен в контроллеры Atmega, но, к сожалению, не всякий загрузчик (bootloader) Arduino правильно обрабатывает эту функцию. Попробуем разобраться с этой проблемой.

Итак, что такое watchdog? Простыми словами — это встроенный таймер на определенное время (до 8 сек в зависимости от чипа), который можно запустить программно. Как только таймер «дотикает» до нуля, контроллер подает правильный сигнал сброса (RESET) и всё устройство уходит в hard перезагрузку. Самое главное, что этот таймер можно сбрасывать в начальное состояние также программным способом.

  • Правильный сигнал сброса — достаточный по длительности для того, чтобы контроллер начал перегружаться. Иногда есть соблазн подключить к RST входу какой-либо цифровой выход Arduino и устанавливать его в 0 когда надо перегрузиться. Это плохой подход к решению проблемы, т.к. такого сигнала может быть недостаточно по времени, хотя и не исключено, что в некоторых случаях это тоже будет работать..
  • hard перезагрузка это самая настоящая перезагрузка, которая происходит при нажатии на кнопку RESET. Дело в том, что есть еще понятие soft перезагрузки — это программный переход на 0-вой адрес. В принципе, это тоже полезная вещь, но с помощью нее невозможно перегрузить зависший контроллер Ethernet или взглюкнувший LCD.
Функции Watchdog

Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку:

Теперь нам доступны следующие три функции:

1. Запуск таймера watchdog:

Таймер будет считать ровно столько, сколько указано в константе. По истечении этого времени произойдет перезагрузка.

2. Сброс таймера watchdog:

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

3. Отключение watchdog:

Отключение таймера watchdog.

Собственно, на этом можно было бы и закончить наше повествование о watchdog… но дело в том, что все это работает только в Arduino Uno, а на Arduino Mega, Mini и Nano все это работает ровно наоборот, т.е. не работает совсем :)

Почему watchdog не работает на большинстве современных плат Arduino

Дело в том, что после перезагрузки, которая была вызвана watchdog, контроллеры последних выпусков оставляют включенным watchdog на минимальный период, т.е. 15ms. Это нужно для того, чтобы программа как-то узнавала, что предыдущая перезагрузка была по watchdog. Поэтому первоочередная задача загрузчика (или вашей программы, если она запускается первой) — сохранить информацию о том, что перезагрузка была «неожиданной» и сразу же выключить watchdog. Если этого не сделать, то система уйдет в bootloop, т.е. будет вечно перегружаться.

Как известно, в Arduino есть специальный загрузчик, который выполняется в первую очередь после перезагрузки системы. И, к огромному сожалению, стандартный загрузчик не сбрасывает watchdog! Таким образом, система заходит в жестокий bootloop (состояние «crazy led», при котором светодиод на 13-м пине мигает как сумасшедший).

Пути решения проблемы

Если посмотреть на исходники стандартного загрузчика (они есть в поставке платформы), то код отключения watchdog есть (!), но этот код вынесен под условную компиляцию и, по всей видимости, стандартный загрузчик скомпилирован без поддержки watchdog. По крайней мере в пакете платформы версии 1.5.2 (последней на момент написание статьи) дело обстоит именно так.

Для решения проблемы я даже прочитал man-ы самой платформы (:) и вроде бы там описана эта проблема и даже приведен код, который должен сделать всех счастливыми:


Здесь описывается функция get_mcusr(), которая должна вызываться сразу после сброса. Это достигается макросом "__attribute__((section(".init3")))". Я пробовал прописывать эту функцию во все секции, которые только возможно — да, она действительно запускается до функции setup() из скетча, но, к сожалению, гораздо позже 15ms (минимальная константа watchdog) после сброса…

Короче говоря, как я ни рыл интернет в поисках легкого решения проблемы, так ничего найдено не было. Я нашел только один способ заставить watchdog работать — перепрошить загрузчик… чем мы сейчас и займемся.

Проверка работоспособности watchdog

Прежде чем что-то прошивать, нужно проверить — вдруг ваша Arduino поддерживает watchdog. Для этого я написал небольшой скетч для теста. Просто залейте его, откройте монитор порта и смотрите, что будет происходить.

После перезагрузки (или подключения монитора к порту) встроенный светодиод мигнет, сигнализируя о том, что запустился загрузчик. Далее в секции setup происходит включение watchdog с таймером на 8 сек. После этого светодиод отсчитает нам это время и должна произойти перезагрузка.

Далее начинается самое интересное — если перезагрузка произошла и все повторяется в такой же последовательности, то вы имеете на руках Arduino, в которой загрузчик правильно обрабатывает watchdog. Если же после перезагрузки светодиод на 13-м пине начинает бесконечно мигать, то значит загрузчик не поддерживает watchdog. Здесь даже кнопка сброса не поможет. Для последующей прошивки нужно плату отключать от питания и после включения успеть прошить до первой перезагрузки.

Я протестировал 4 вида плат и только загрузчик в Arduino Uno сработал так как надо:

Платы Arduino

Watchdog не поддерживается загрузчиком:
image

Watchdog поддерживается загрузчиком:



Как легче всего прошить новый загрузчик?

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

Я не буду в этой статье описывать все премудрости создания программатора на основе Arduino, т.к. эта тема довольно подробно описана в интернете. В качестве программатора я использовал Arduino Uno. Как известно, прошивка производится через отдельный разъем ICSP, который есть почти на всех платах. В случае прошивки Arduino Pro Mini, у которого нет IСSP, подключение производится непосредственно к выводам.

image

image

Где взять загрузчик, который поддерживает watchdog?

Эта глава напоминает танцы с бубном и скорее всего можно сделать все как-то проще, но, увы, у меня по-другому не получилось.

Рекомендуется использовать загрузчики из пакета optiboot. В принципе, эти загрузчики идут в инсталляции самой платформы Arduino, но лучше скачать и установить последнюю версию optiboot отсюда. Установка заключается в двух шагах (возможно, это можно сделать как-то по-другому):

  1. Папка bootloaders\optiboot перезаписывается в C:\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\optiboot
  2. Файл boards.txt дописывается к файлу C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt

Далее перегружается среда разработки и в меню Сервис/Плата можно наблюдать новые платы с пометкой [optiboot]. К сожалению, при выборе этих плат происходят какие-то непонятные ошибки компиляции и появляются всякие другие странности… поэтому делаем еще проще. Открываем в любом текстовом редакторе файл C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt и меняем следующие строчки:

Для Arduino Nano:
menu.cpu.nano.atmega328.bootloader.file=optiboot/optiboot_atmega328.hex

Для Arduino Mini:
menu.cpu.mini.atmega328.bootloader.file=optiboot/optiboot_atmega328.hex

Следующая проблема в том, что загрузчика optiboot для платы Arduino Mega не существует в природе, т.к. в Mega больше памяти и используется другой протокол. Поэтому мы используем стандартный, но модифицированный загрузчик, который качаем отсюда. Файл переименовываем в stk500boot_v2_mega2560_2.hex и записываем в папку C:\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\stk500v2.

Далее меняем в уже знакомом файле boards.txt следующую строчку:
mega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560_2.hex

Не пугайтесь, что файл модифицированной прошивки для Mega в 2 раза меньше стандартного — так вроде бы должно быть.

Процесс прошивки

После всех изменений можно прошивать загрузчики, выбирая в меню плат обычные платы (не [optiboot]!). В этом случае прошиваться будут именно те файлы hex, которые мы указали в файле board.txt.
Процесс прошивки может не стартовать и выдаваться ошибка:

Для решения этой проблемы откройте скетч программатора и в секции setup выберите другую скорость последовательного порта.
Во время заливки в Arduino Mega может появляться ошибка, которую следует игнорировать:

Заключительные манипуляции

Загрузчики optiboot имеют еще одну особенность — они увеличивают скорость загрузки скетчей, поэтому при использовании плат с optiboot нужно внести соответствующие изменения в boards.txt:

Для Arduino Nano:
menu.cpu.nano.atmega328.upload.speed=115200
Для Arduino Mini:
menu.cpu.mini.atmega328.upload.speed=115200

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

Watch Dogs в реальной жизни, или серьезные уязвимости в СКУД

Мне кажется, что многие парни, особенно в юном возрасте, хотели быть крутыми хакерами. Взламывать сайты, телефоны, системы доступа. Вот и у меня немного остался этот мальчишеский задор. Поэтому периодически ковырялся в различном ПО и ничего стоящего не находил. Но однажды, мне подвернулась удача, да еще какая! СКУД, полная уязвимостей, которые позволяют получить доступ к управлению всей системой (открытие/закрытие дверей, добавление своей карты прохода и т.д.).

Интересно? Тогда добро пожаловать под кат!

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

СКУД — система контроля и управления доступом

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

image


Примерная схема работы СКУД

Я начал изучение с базы данных. Сервер СКУД работает с БД firebird 2.5. Логин и пароль к ней оказались стандартными, что уже очень насторожило, но пароль можно задать в настройках программы. Пароли в БД к учетным записям хэшированы, но без соли, что плохо, но опять же некритично. В ней хранятся все зоны прохода, пользователи, номера их карт, доступы и адреса контроллеров.

image


БД

Дальше берем какую-нибудь программу для сниффинга трафика (я взял “SmatrSniff”, первое попавшееся, что может просматривать трафик localhost) и смотрим, что шлет клиент к серверу. Все данные идут по TCP и часть по UDP в незашифрованном виде. И тут начинается самое интересное. Сервер сначала отсылает в открытом виде пароль от БД, ее месторасположение и только потом проверяет логин и пароль!

image


Пароль от базы "masterkey"

Получается, что, не зная логина и пароля, мы можем получить полный доступ к базе данных, что дает нам практически безграничные возможности. Мы можем выдать себе карту с доступом на любой объект. Прописать другому пользователю свою карту и заходить под его именем. Но чтобы эти данные загрузились на контроллеры, надо дать команду серверу из клиента. Хоть мы и можем взять пароль к клиенту из БД воспользоваться открытыми базами MD5 и попробовать подобрать пароль к хэшу (напомню, что пароли в базе без соли), но если пароль задан сложный, то скорее всего ничего не выйдет. Придется ждать, когда кто-нибудь нажмет на кнопку полной выгрузки.

Дальше я посмотрел, а влияет ли вообще на что-то авторизация. Для этого я попробовал повторять запросы к серверу с помощью “TCP / IP Builder”. И да, последующие запросы на сервер, без авторизации не работают (присылает в ответ отказ). Тут я немного приуныл, потому что для интеграции придется реализовывать повторение всей цепочки авторизации и только потом отправлять пакет для загрузки данных в контроллер.

Напоследок я решил повторить запрос перевода двери в открытый режим. Сервер ответил «ok», а дверь запищала. Без какой-либо авторизации. Я повторил это же с другого компьютера в локальной сети и это тоже сработало.

image


Примерный вид пакета

Это значит, что мы можем открыть/закрыть любую дверь с любого компьютера в локальной сети. Прописать себе карту и сразу загрузить эти данные в контроллеры. После чего спокойно пройтись по объектам и удалить все логи нашего посещения.

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

Читайте также: