Как стать автором
Обновить

Комментарии 57

Любопытно. Для каких-то локальных сетей удобнее разослать пачку ICMP без установки полноценного TCP-коннекта. Но выглядит жутко опасно, если такое вдруг начнет торчать в интернет.

Из структуры с IP-хедером можно взять source, но чтобы он не был захардкожен надо дополнительно заморочиться, потребуется больше времени и разработки. Это пара строк дополнительного кода, но решение не идеальное. Хочу найти какие-нибудь примитивы, которые позволят обеспечить симметричное шифрование вместо авторизации по источнику и префикса с паролем, надеюсь, кто-нибудь подскажет.

Из структуры с IP-хедером можно взять source

Но ведь такой пакет легко подделать

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

Я, пожалуй, подскажу небольшой чеклист, по которому следует проверить то, что Вам предложат для шифрования.
1. Что будет, если злоумышленник подслушает зашифрованный пакет и через некоторое время пошлёт его повторно? Не выполнится ли команда повторно?
2. Предположим, злоумышленник поменял порядок прохождения пакетов. К чему это приведёт?
3. Предположим, злоумышленник перехватил все пакеты и не пустил ни один из них к серверу. А потом через несколько дней сам начал отправлять перехваченные пакеты на сервер. Что будет?
4. Предположим, злоумышленник подслушал два зашифрованных пакета и произвёл над ними, например, операцию XOR. Не получит ли он в результате XOR от посланных на сервер команд?
5. Предположим, злоумышенник некоторое время слушал трафик, а потом устроил маски-шоу и получил доступ к серверу и хранящемуся на нём паролю. Не сможет ли он после этого расшифровать отправленные на сервер команды?
6. Предположим, злоумышленник знает, какую команду Вы хотите отправить. Он перехватил пакет. Не получится ли у него изменить несколько байтов в зашифрованном пакете и заставить сервер выполнить _другую_ команду?
7. Не получится ли у злоумышленника подобрать пакет, который пройдёт проверку, измеряя время от получения ICMP-пакета до отправки ответа на него? Если пакет, не прошедший проверку, отвергается, то следует рассмотреть случай, когда злоумышленник отправляет _два_ пакета, первый из которых содержит payload, требующий проверки, а второй является обычным ping'ом.

Спасибо, полезно. Я успел обеспокоиться только о получении ключа на основании предсказуемого содержимого пейлода. К мусору надо ещё время добавить и проверять, чтобы исключить реплей-атаку.

НЛО прилетело и опубликовало эту надпись здесь

Одного, поэтому ICMP-пакет и не требует тройного рукопожатия. Но для модуля ядра это не должно быть проблемой, TCP-пакет можно принять и обработать в любом виде, без установки полноценного соединения.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

IP — сетевой уровень. TCP, UDP, ICMP работают поверх IP — на транспортном уровне.

НЛО прилетело и опубликовало эту надпись здесь
>Иначе у вас, на выбор, ничего не запустится или вы получите kernel panic.

От чего это зависит?

Если в хуке вызывать юзерспейс-программу не ожидая её выполнения, с аргументом UMH_NO_WAIT, то ничего не произойдёт. Думаю, что хук завершается вместе со всеми потомками. Если вызывать с UMH_WAIT_EXEC или UMH_WAIT_PROC, то ядро крашится.

А команда выполнится, если пакет дропнуть в конце хука?

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

MAX_CMD_LEN 1976 — каков максимальный размер ICMP payload? Подозреваю, что немного меньше.
Было бы интересно увидеть реализацию отправки «ответа» в icmp reply.
Реализовать полноценное шифрование в данной схеме — задача куда более сложная. Но почему бы и нет?
И, самое главное, в боевых условиях проверяли? Будет ли оно работать когда уже свалился shh? Подозреваю, что вызов /bin/sh не пройдет.
каков максимальный размер ICMP payload?

Сам ICMP-пакет по размерам не ограничен, но есть ограничения на IP-пакет, 65535 байт. Из этого вычитаем 20 байт на заголовок IP-пакета и 8 байт на заголовок ICMP-пакета, получается намного больше, чем моё ограничение.


Было бы интересно увидеть реализацию отправки «ответа» в icmp reply.

Думаю, что это технически невозможно. Как раз потому что ядро крашится, если ждать даже начала выполнения команды.


Будет ли оно работать когда уже свалился shh?

Конкретно это не проверял, /bin/sh никак не зависит от SSH-сервера. Кроме того, SSH работает по TCP, а в моём модуле TCP никак не затрагивается.

Сам ICMP-пакет по размерам не ограничен, но есть ограничения на IP-пакет, 65535 байт.

Насколько я понимаю, это не совсем так. Есть ограничение на ethernet пакет, там что-то порядка 1500 байт. IP поверх него умеет фрагметировать/собирать пакеты большего размера, но врят ли это коснется вашего icmp кетчера.
Думаю, что это технически невозможно. Как раз потому что ядро крашится, если ждать даже начала выполнения команды.

Сохраните вывод команды в некий буфер и при следующем icmp echo отправьте его назад.
Конкретно это не проверял, /bin/sh никак не зависит от SSH-сервера.

Когда у меня на виртуалке заканчивается оперативная память вместе с буфером подкачки, то /bin/sh уже не открывается. Подозреваю, что где то тут же сдохнет и ssh. Ваша идея призвана бороться с подобными случаями. Она с ними справляется? Просто подключая вызов внешней утилиты вы убиваете саму идею обработки команды в ядре. Имеет ли это хоть какой нибудь смысл? С тем же успехом можно было написать свой простейший sshtelnet в user space и использовать его в крайних случаях. Отказоустойчивость, вероятно, оказалась бы на том же уровне.
Есть ограничение на ethernet пакет

Да, MTU, про него не думал. Если IP-пакет собирается ядром прежде чем попадёт в нетфильтр, то всё будет хорошо. Возможно, зависит от приоритета, надо проверять.


при следующем icmp echo отправьте его назад

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


Когда у меня на виртуалке заканчивается оперативная память вместе с буфером подкачки, то /bin/sh уже не открывается.

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

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

Все модули должны лежать в /lib/modules, не такой уж незаметный бэкдор.

Проверил файндом, ничего не нашлось. Там лежат модули из пакета и из DKMS, а загружаемое простым insmod остаётся только в памяти. Заметно будет в выводе lsmod.

Постойте, а разве более-менее сетевая flow-based железка по дороге не заменит содержимое нагрузки на random?

У меня до виртуалки ничего не подменялось. Есть сведения о железках, которые точно так делают?

Провел эксперимент:
ping ngs.ru -s 1000

Посмотрел wireshark'ом что уходит и что приходит. Полное совпадение.

Большинство мэ анализирует содержимое нагрузки в том числе и icmp. Так что есть вероятность, что в корпоративной сети не взлетит.
Так же всякие системы DDos очень нервно могут реагировать на содержимое ICMP и начать дропать трафик. Понятно, что все зависит от настроек…

Боюсь, что и провайдеры со своими DPI и прочими погремушками могут манипулировать icmp-ями в полный рост.


И вообще, тестирование сетевых штук на виртуалке, установленной на локалхосте, не покажет все богатство красок. Тот же STP на порте, например.

Я тестировал на удалённой. Повезло, но могло быть интересней.

Никакие файрволлы не должны манипулировать содержимым пакетов, разве что только если нужен NAT — но и то с ограниченным числом протоколов.


Суть ICMP echo как раз в том что отправитель получит ровно то что отправил, иначе это сломает много тулзов. Не пустить пакет — другое дело, но менять содержимое — никак.


А вообще идея не нова — уже был модуль ping-sysrq, да и похожие типа icmp shell.

Не специалист в ядерной разработке, но не будет ли тут гонки при работе с cmd_string? Чтение и запись туда ведь никак не синхронизируется, на первый взгляд.

Не понимаю проблему, я даже в C не специалист. cmd_string может перезаписываться разными ICMP-пакетами?

Да, речь в том числе и про это.
Может произойти следующая ситуация:
Пришел 1й icmp-пакет, в cmd_string записалось, скажем, echo hello world и в планировщик поставилась задача.
В момент обработки 2го пакета в cmd_string начало записываться, например killall ssh и "в это же время" планировщик начал выполнять задачу на запуск команды, где из cmd_string началось считывание. И считаться может, к примеру echoall ssh (т.е. совсем не то, что ожидалось изначально).
Похоже на то, что тут нужна некая очередь команд, взятие и добавление элемента в которую будет происходить атомарно.

Да вполне возможно что это и произойдет, особенно если послать 2-3 пакета сразу может сегфолтнуться

В случае с ядром будет сходу kernel panic.

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

Тут не столько язык, сколько проблема конкурентного доступа к памяти. И всплывает она во многих языках.

Никогда ничего не писал для ядра линукса, но предположу, что в структуре work_struct должно быть поле типа void*, в которое можно положить произвольные данные. Ещё не видел API на C, в котором бы принимался колбэк без подобного параметра. Единственное неудобство: придётся динамически выделять (а потом освобождать) память.

Интересно. Мне всегда казалось, что void говорит о том, что никаких данных не подразумевается.

Просто void — да. Но void* — это указатель без конкретного типа. Любая функция, которая принимает void*, принимает любой указатель, хоть int*, хоть char*, хоть массив из структур.
Хакеры оценят. Интересно мой код патченого su для андроида уже помечается как вирус?
Вспомнился ICMP Proxy, который в 2002(!) году победил в конкурсе на лучшую программу в журнале «Хакер». А я тогда занял второе место, хнык…
справедливо заподозрив скам

Что это?

Всяческое мошенничество. Меня заподозрили в том, что я пишу бэкдор для вредоносной деятельности.

Любой фрагментированный ICMP echo, и получаем kernel panic или перезапись памяти ядра.
Не помешает изучить зачем нужны и как работают skb_header_pointer(), skb_copy_bits() и skb_may_pull().
Déjà Vu: lwn.net/Articles/225946

Обязательно, спасибо! Про фрагментированные echo-пакеты я даже не знал.

Как понять фрагментированный ICMP echo?
IP протокол поддерживает фрагментацию пакетов. Т.е. один пакет размером до 64к будет разбит и собран автоматически на кусочки по 1500 байт (примерный максимум для ethernet). ICMP реализован поверх IP, следовательно и ICMP пакет может быть разбит на несколько ethernet пакетов (если не влезет в один).
Почему

«Любой фрагментированный ICMP echo, и получаем kernel panic или перезапись памяти ядра.»


?
Думаю, об этом лучше почитать в указанном выше Déjà Vu
Почему

«Любой фрагментированный ICMP echo, и получаем kernel panic или перезапись памяти ядра.»


?
А почему бы просто не закрыть это асинхронной криптографией? Заодно и шифрование протокола будет бесплатно.

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

Вероятно, вы все таки имели ввиду асимметричное шифрование, а не асинхронное?

Точно, как-то я и не заметил подмены.

Точно, простите. Слишком много питонячьего бэкенда было у меня в тот день…
Зарегистрируйтесь на Хабре, чтобы оставить комментарий