%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%

  The remote system reboot.

%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%

  - Введение. Идея проекта.
  - Описание проекта.
  - Код + комментарии.
  - Недостатки проекта. Методы обхода механизма авторизации.
  - Заключение.


%$%;%;%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%$%


  I. Введение. Идея проекта.

   Данная  идея  зародилась  у  меня  не случайно.  Когда-то  мне пришлось
   столкнуться  с  такой  проблемой:   надо  было  организовать  доступ  к
   Интернету для нескольких компьютеров (находящих в одной локальной сети)
   через другой компьютер-сервер.  Решение было стандартное  (для подобной
   ситуации) и принято сразу - установить на сервер WinGate  (это одна  из
   лучших программ, предназначенных для этой цели).  Всё было  бы  хорошо,
   если бы не одна проблема.  Частые зависания WinGate и некоторые  другие
   проблемы с сервером,  портили  всю картину. Кто-то должен был постоянно
   следить за работоспособностью системы, потому что если  шлюз  повис, то
   все,  кто  использовал  этот  канал,  оставались  на день без  выхода в
   Интернет.  Ситуация была понятна - сделать  каким либо образом,  что бы
   все клиенты могли своими силами удаленно перезагружать сервер,  но  тем
   самым не создать потенциальную цель для  злоумышленников.  Сначала была
   идея  поставить   RemoteAdmin  и  всем  раздать  пароли,   но  кому  бы
   захотелось,  что бы в твоё отсутствие  кто-то полностью  управлял твоим
   компьютером?  Тем более что RAdmin ещё и ресурсы немного забирает  (для
   слабенькой шлюзовой машины это было бы весьма значительно).  Нужна была
   программа,  которая  бы дала возможность удалённо перезагружать систему
   определённым пользователям и не чего больше.  На примере этой статьи вы
   увидите, как решить весьма стандартную задачу  с наименьшими  усилиями.
   В качестве языка  программирования  для  написания server'a и client'a,
   по разным причинам,  был выбран ASM.  Поэтому  вы  получите  не  плохой
   урок по кодингу сетевых-приложений на низком уровне.


  II.	Описание проекта.

   Наш проект будет состоять из двух частей: сервер и клиент. Сервер будет
   установлен  и постоянно "висеть" на главном компьютере,  через  который
   остальные пользователи получают доступ в Интернет (там же будет запущен
   WinGate server).  Состоять  он  будет  из  двух  больших  частей:   1 -
   авторизация,  2 - перезагрузка (это образно).  Клиентская  часть  будет
   использоваться только  теми юзерами,  которым  мы  хотим  дать доступ к
   системе перезагрузки.  Она будет  запускаться  только  в случае,  когда
   клиенту нужно быстро перезагрузить шлюзовую машину.  Теперь ещё немного
   теории по  поводу алгоритма  авторизации для нашего  проекта.  Я  решил
   сильно не  мудрить и  достаточно просто  решил эту задачу.  Наш сервер,
   будет постоянно запущен на определённом порту и находиться в  состоянии
   ожидания входящего соединения по протоколу TCP.  После того, как сервер
   получает запрос на соединение от нашего клиента, он определяет OS, MAC-
   адрес,  имя  компьютера  и  IP-адрес  запросившей  машины.  Далее  идет
   сравнение полученных данных по базе, хранящейся в специальном файле,  в
   которую  заранее будут  внесены все  параметры на каждого из  клиентов,
   в таком виде:

 -----accept.ini---------------------------------------
 ;Config file for accepted users
 ;Format is: <IP>\t<MAC>\t<NAME>\t<OS>
 ;==============================================================
 ;
 ;First of all: all values are divided by
 ;TABS (TAB key on your keyboard :) - it is VERY IMPORTANT!!
 ;
 ;The second: values check is case insensitively,
 ;therefore you can write 'COMP' or 'comp' for user name.
 ;
 ;And the last: if instead of value stands 0 it means,
 ;that this value is not checked by the program
 ;===============================================================
 10.0.0.1	00:80:48:15:68:B7	client	XP
 -----END-----------------------------------------------



   Если данная конкретная связка IP+MAC+NAME+Версия ОС находится  в  нашем
   конфиге,  сервер  посылает  ответ  клиенту, где просит ввести секретный
   ключ. Пусть в нашем случае это будет:

     W3Tt456GGbsOyDSGDSmnGH%gSZG@#FSjkljl632

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

   Этот  способ  авторизации  достаточно  прост,  но в  тоже  время весьма
   рационально  выбран для нашего случая и достаточно надежен.  Его  можно
   сравнить  с  авторизацией  по  культурному  признаку  (например,  когда
   охранник  опознаёт своего  босса  по  ряду  признаков:  большой  живот,
   борода,  пропуск на пиджаке).  Вот так и тут,  мы опознаем  клиента  по
   ряду признаков, это первый этап нашей авторизации. Не самый достоверный
   способ отличить компьютер злоумышленника от машины доверенного клиента,
   так как, и IP-, и MAC-адрес, и версию ОС,  можно  подменить (не  говоря
   уже о имени системы). Правда стоит  заметить,  что  в  современных LAN,
   умные  администраторы  уже  давно научились  настраивать  блокировку на
   свитче попыток незаконного захода под чужим IP. Поэтому в некоторых LAN
   весьма трудно выдать себя за другого пользователя.  Обычно,  как только
   сетевая карта приобретает IP,  который не соответствует её  MAC-адресу,
   происходит блокировка  этой карты и дальше  без участия  администратора
   ничего сделать не удастся. Второй этап  -  это авторизация по ключу, он
   весьма надежен!  Ключ большой длинны будет очень сложно подобрать  даже
   массовым брутфорсом. А если ещё и написать блокировку клиентов, которые
   неправильно  ввели  ключ  более  n раз,  то мы  вообще  не дадим  почти
   никакого шанса горе-хакерам получить доступ к нашему серверу.

   Теперь,  когда вы  понимаете  алгоритм авторизации  и работы программы,
   можно  поближе  подобраться  к  практике.   Сервер   запускается   так:
   server.exe <port> <password> [config].   Сначала  идет  путь  к  нашему
   server.exe,  затем порт,  на  котором  сервер  будет  ожидать коннекта,
   дальше  пароль который  будет запрашиваться  у клиента  и затем  путь к
   config  файлу (желательно  указывать  полный  путь).  Введённый  пароль
   шифруется с помощью MD5 и хранится в памяти. Пример запуска:

    d:\server.exe 25646 m45bdg9gdsb5 d:\accept.ini
    RemReboot server v0.1 by dstaff

    Shutdown privilege enabled
    Waiting connection...

   Всё,  теперь программа установила  нужные привилегии для  осуществления
   перезагрузки  и  находится  в  ожидании  соединения.  Теперь  запускаем
   клиент: client.exe <address> <port>.  Тут всего два параметра: IP-адрес
   нашего  сервера и порт  на котором  сервер ожидает  соединения.  Пример
   запуска:

    d:\client.exe 10.0.0.1 25646

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

    RemReboot server v0.1 by dstaff

    Shutdown privilege enabled
    Waiting connection...

    Incoming connection!                # получили входящие соединение.
    Client IP:		10.0.0.2                # Определили IP клиент.
    MAC address:	00:80:48:15:68:B7      # MAC адрес.
    Computer Name:	client               # Имя компьютера.
    Client OS:		Windows XP              # Версию OS.

 # Далее идет поиск информации в accept.ini В данном случае информация не
 # найденна:

    The client is not recognized.       # Отключает клиента.
    Waiting connection...               # Ожидает нового соединения.
 
  1 случай:

    RemReboot client: Sorry, your connection is not allowed.

   В данном случае мы присоединились к серверу, но наша информация не была
   найдена в конфиге accept.ini, поэтому поризошёл разрыв соединения.  2-й
   случай:

   Если  наши  данные  (IP+MAC+NAME+OS)  найдены  в  accept.ini,  то  шлюз
   переходит ко второй части авторизации - просит ввести пароль. Введённый
   ключ шифруется  с помощью  MD5 на клиентской  стороне и полученный  хеш
   передается серверу.  После  этого  он сравнивает  два хэша  и если  они
   равны - осуществляет  перезагрузку компьютера.  В  результате  в  нашем
   проекте  мы  используем вполне  безопасный метод  передачи данных.  Ещё
   один плюс в нашу копилку.

   Более подробно  обо всех  тонкостях запуска  и  настройки  вы  узнаете,
   просмотрев  исходные   коды  с  достаточно   подробными  комментариями.
   Последнее, что стоит упомянуть - это редактирование accept.ini. Тут всё
   просто:  вы можете сами решать, сколько параметров будет определяться у
   клиента (все они разделены табуляцией).  Например,  если  вам  не нужно
   идентифицировать машины по имени компьютера,  поставьте 0 в 3-ей графе.
   По своему  желанию  вы  можете  вообще  оставить  один  лишь IP  адрес,
   например  в  том  случае,  если  с  определением  MAC-адреса  возникают
   проблемы (так же и с определением OS).

   Конечно, в проекте реализовано не всё, что хотелось бы.  Можно добавить
   такие вещи:

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

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

  - Если  попытался подключиться  клиент с "неверными" данными,  то его IP
  заносится в black list.

  - Можно добавить функцию оповещения администратора на e-mail,  ICQ или с
  помощью SMS на сотовый телефон при попытке взлома  (например при попытке
  подбора ключа).

  - Прописать наш сервер в автозагрузку.

   Всё зависит от вашей фантазии!  Можно сделать вполне полезную программу
   и  добавить в неё любые другие функции (при  желании  можно сделать  из
   этой полезной тулзы - вредоносную ;)


  III.	Код + комментарии.

   Код  программы  пришлось  выложить  в  отдельных  файлах,  так  как  он
   достаточно большой.  Полные исходники с подробными комментариями на RUS
   и ENG  языках  вы найдете  в папке  /include/remreboot/. Там  же  будут
   находиться откомпилированные версии.

   Некоторые замечания по коду:

  1) Конфиг  -  очень чувствительная вещь,  поэтому  стоит  оформлять  его
  правильным  образом.  Например,  все значения  в нем разделяются ТАБАМИ.
  Можно было бы сделать так, чтобы разделять пробелами  -  но он некрасиво
  бы  выглядел :)  Если  есть  желание,  можете  это  дописать  сами.  Всю
  остальную информацию вы найдете в самом конфиге.


  2) В коде используются посторонние модули, как то:

    а) Для генерации md5 хэша используется код by roy|crisis crackers.

    б) Для разбора значений конфига  используется код by  Digital Monkey с
    нашими небольшими исправлениями (точнее  -  убрано  ограничение  на 1к
    входящего текста). Исходники прилагаются.

    в) Для работы со строками используются макросы by Four-F.


  3) При тестировании  на  некоторых  машинах  обнаружился такой  забавный
  глюк: если в  командной  строке  задавать имя  конфига,  который следует
  использовать, то в некоторых случаях программа не может его найти. Чтобы
  это обойти, используйте не относительный, а полный путь к этому файлу.


  4) Для   определения   версии   ОС   используется  специфическая функция
  NetWkstaGetInfo, которая требует NetBIOS-имя пользователя.  Поэтому если
  не получится определить имя компьютера - не получится определить и ОС.

  Вообще код не очень сложный. Может быть написан немного сумбурно, но что
  поделаешь :)


  IV. Недостатки проекта. Методы обхода механизма авторизации.

   Мы написали сервер, написали клиент,  разобрали механизм  авторизации и
   его  положительные  стороны.   Теперь  пора  поговорить  и  о  грустных
   моментах.  Я надеюсь,  что каждый  читатель  осознаёт тот факт,  что не
   существуют  100%  методов  защиты данных.  Постоянно  появляются  новые
   механизмы атаки и в таком же быстром темпе  появляются совершенно новые
   методы защиты от них.  То есть,  мы можем  наблюдать процесс "эволюции"
   методов атаки  и защиты в  соответствии друг с  другом.  Как  уже  было
   сказанно, первый этап авторизации не достаточно надёжный.  Что  бы  его
   обойти, нам необходимо приложить совсем немного усилий.  Сразу  отмечу,
   что все нижепреведенные действия лучше проводить заранее отключив сеть(
   физически, с помощью firewall или каким либо другим способом  -  решать
   вам).

   А теперь по пунктам:
 
  - Никто  нам не запрещает поменять свой IP адрес на чужой (это  делается
  в настройках TCP/IP протокола).  ПУСК  ->  Панель управления  -> Сетевые
  подключения  ->  Подключение  по  локальной сети -> Протокол интернета (
  TCP/IP)

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


  - MAC-адрес (Media Access Control) это номер сетевой устройства  (иногда
  его называют  уникальным  идентификатором,  что  впринцепе одно и тоже),
  который  хранится  в Memory  Information  Block. Многие считают что MAC-
  адрес подменить сложнее чем IP, но это не так.  Просто это менее понятно
  для обычного  пользователя.  Сменить  MAC можно  разными  способами, всё
  зависит от модели вашей карты.  Существует большое  количество  программ
  которые  облегчают нашу задачу.  Например  популярная SMAC 1.1 позволяет
  изменять MAC в  OS семейства  Windows.  Но все подобные программы меняют
  MAC совершенно одинаковыми способами:


          А) Изменяют значение в реестре. Откройте regedit и поищите строку
            "NetworkAddress" в реестре. (далее понятно) 
             Данный метод работает только для сетевых карт которые используют
             функцию NdisReadNetworkAddress.

          B) Перепрошивают сетевую карту. На этом мы не будем останавли- 
             ваться. Это уже отдельная статья.

          D) Если дело касается *nix OS. Всё намного проще: 
             # ifconfig eth0 down
             # ifconfig eth0 ether 00:20:78:07:63:57
             # ifconfig eth0 10.0.0.2 up
             # ifconfig eth0
             В нашем случае мы говорим только про Win платформы, так что это
             только для общего развития.

   Можно упомянуть,  что  существуют  программы  противополжные  по своему
   действию программе SMAC.  Например "IP Change Monitor" используется для
   мониторинга изменений IP-адресов в локальной сети.

  - С версией OS сложнее. Тут нужно исходить из функции которую использует
  сервер для  определения OS  клиента  -  NetWkstaGetInfo  и  особенностей
  некоторых протоколов.  Это достаточно сложно и требует отдельной статьи.
  Поэтому я считаю,  что если злоумышленник будет пытаться  выдать себя за
  настоящего  пользователя целесообразней было бы поставить ту версию Win,
  например, на виртуальную машину. Про смену  имени компьютера мы говорить
  не будем. Если  вы  не знаете,  как  это сделать  -  идите читать хакер-
  мурзилку, а не наш журнал.
 

   Теперь немного поговорим про теоретические  методы обхода второго этапа
   авторизации.  Предположим,  что злоумышленнику  удалось выдать  себя за
   настоящего клиента. Но какой толк, если он не знает пароля? Всё было бы
   просто,   если   бы   наш   пароль   передовался   в   открытом   виде.
   Воспользовавшись обычным сниффером мы могли бы узнать пароль и получить
   доступ к серверу.  В нашем  же случае  передаётся лишь  MD5 хэш  нашего
   пароля.  Злоумышленник потратит  огромное кол-во времени на перебор.  А
   если пароль 9 символов или 10?  Единственный путь  узнать длину пароля,
   так называемый "сёрфинг на плече". Что естественно почти не реально :)
 
  V.	Заключение.

   Цель этой статьи  не просто дать  вам готовый код,  который вы  сможете
   использовать в своих целях. Мы преследовали несколько другие цели:

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

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

  - Привести пример решения стандартной задачи, нестандартными методами.