Фильтровать пакеты в сетевом стеке при обнюхивании пакетов в Linux?

У меня есть вопрос к гуру сетей низкого уровня/Linux,

Мне нужно создать два инструмента для проекта безопасности в моем университете. Первый инструмент — это атакующий ARP Poisonning, который отравляет кеш ARP с удаленного хоста, чтобы получить данные, которые он отправляет на другой хост. Я написал этот инструмент на C, используя сокеты RAW, и он отлично работает, я могу перехватывать данные, передаваемые с хоста A на хост B и с хоста B обратно на хост A.

Проблема возникает при написании второго инструмента, который является сниффером, предназначенным для чтения/редактирования/отбрасывания пакетов, приходящих с хоста A или хоста B. Я представил себе систему, в которой, когда я обнаружу пакет, пришедший с одного из этих хостов, моя программа спросите меня, хочу ли я пропустить этот пакет, хочу ли я изменить его или просто хочу отбросить его. Я активировал переадресацию IP в Linux, используя

sysctl -w net.ipv4.ip_forward=1

и я могу читать все данные, перемещающиеся между двумя хостами. Но я не знаю, как редактировать/удалять эти пакеты, так как роль сетевого стека Linux заключается в управлении вводом и выводом пакетов, поступающих с моего сетевого интерфейса. Я действую только как пассивный атакующий, если хотите.

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

Затем я попытался активировать неразборчивый режим, но в этом не было необходимости, так как этот режим работает только на физическом уровне (просматривает, совпадает ли целевой MAC-адрес в полученном пакете Ethernet с MAC-адресом на локальном интерфейсе). Таким образом, неразборчивый режим помогает нам избежать физического фильтра стека Linux, но не логического (целевой IP-адрес в пакете Я получаю IP-адрес B, а не мой, поэтому сетевой стек Linux просто отбрасывает пакет).

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

Я знаю, что есть решение с помощью iptables, мы можем попросить его пропустить некоторые пакеты с определенного IP-адреса, но я не хочу решения с использованием стороннего инструмента, я хочу инкапсулировать все в моей программе.

Для справки, среда разработки — Linux/Ubuntu Kernel 3.0.0-16, и все сделано на языке C.


person Halim Qarroum    schedule 17.03.2012    source источник
comment
Если вы хотите инкапсулировать все в своей программе, вам придется сделать то, что делает iptables - сообщить ядру, что вы хотите получать пакеты для назначенного IP-адреса.   -  person Borealid    schedule 17.03.2012
comment
Ну, я до сих пор не знаю, будет ли это более безопасным/чистым решением, в конечном итоге это вариант. Я все еще жду других комментариев, должны быть другие варианты. iptables делает это, потому что его цель - маршрутизировать пакеты, и я не знаю, действует ли он на земле ядра или на земле пользователя.   -  person Halim Qarroum    schedule 17.03.2012
comment
iptables — это пользовательский инструмент, который взаимодействует с ядром. Фактическое решение о маршрутизации пакетов принимается полностью в пространстве ядра.   -  person Borealid    schedule 17.03.2012


Ответы (3)


Я понял, почему я не получал никаких пакетов, когда отключил ip_forwarding. Я провел много тестов после того, как разместил свой вопрос здесь, и я понял, что когда ip_forwarding был отключен, удаленный хост отправлял мне очень странные TCP-пакеты примерно каждые ~ 10 секунд.

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

В этом случае поведение по умолчанию для удаленного хоста заключалось в повторной отправке этого пакета через другой интервал времени, на самом деле это нормальное поведение стека TCP. Но чего я не знал, так это того, что пока удаленный хост не получит ответ на свой первоначальный TCP-пакет, он не будет отправлять никаких других (только для того же приложения). Поэтому, когда я нажимал «F5» в браузере удаленного хоста, я думал, что он будет генерировать TCP-трафик, хотя он не получит никакого ответа, и я не знал об этом конкретном поведении TCP-стека, поэтому я просто думал, что не получаю любой ответ. Другой хост (шлюз) действовал точно так же, поэтому я могу сказать, что ошибался, думая, что стек Linux блокирует пакеты удаленного хоста.

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

person Halim Qarroum    schedule 17.03.2012

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

Для получения дополнительной информации по этой теме см. следующие ресурсы:

person Appleman1234    schedule 17.03.2012
comment
Спасибо Appleman за ваш ответ, но, как вы можете видеть ниже, я нашел, где была проблема, и исправил ее. Спасибо, в любом случае ! - person Halim Qarroum; 18.03.2012

Вы вообще используете libpcap? Судя по вашему вопросу, это не похоже на вас, что интересно, поскольку это самая известная и используемая библиотека для всего, что связано с тем, что вы делаете? Вы не используете его, потому что это часть условий задания не использовать его?

Если вы можете использовать его, я бы пошел с ним и проверил проект ettercap, в котором есть поддержка перезаписи живых пакетов.

http://ettercap.sourceforge.net/

РЕДАКТИРОВАТЬ: Проверьте модуль фильтра ettercap в

https://github.com/drizztbsd/ettercap/blob/master/src/ec_filter.c

особенно посмотри на func_inject

person Pablo Fernandez heelhook    schedule 17.03.2012
comment
Спасибо за ответ, Пабло! К сожалению, мне не разрешено использовать libcap, по словам учителя, это делает вещи менее забавными :) Мне разрешено использовать только сокеты. Я проверю вашу ссылку. - person Halim Qarroum; 17.03.2012
comment
Функция func_inject предназначена для вставки данных в пакет, но она не говорит мне, как ettercap читает интерфейс, я проверил другие части кода, но, поскольку ettercap использует libnet/libpcap для взаимодействия с интерфейсом, я не знаю. посмотрите, как это сделать, используя базовые сокеты. - person Halim Qarroum; 17.03.2012
comment
Да, если вы не можете использовать libpcap, то из этого исходного кода вы не сможете получить много информации. Может быть, добавить, что libpcap нельзя использовать на ваш вопрос? В противном случае большинство людей, вероятно, укажут вам на это;) - person Pablo Fernandez heelhook; 17.03.2012
comment
@Pablo: мне не нужно решение, включающее сторонний инструмент, я хочу инкапсулировать все в своей программе - цитата из вопроса. - person Niklas B.; 17.03.2012