Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 8 мая!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Программисты долго мучаются с кодом прогаммы, изучают С++, WinAPI функции, MSDN. Потом пишут банальную систему защиты или навешивают банальный протектор, а крэкеры и реверсеры справляются с такой защитой за 5 минут. В итоге, продажи программы почти нулевые. Чтобы такого не допустить, тут самому надо немного поднабрать опыта отладки, реверсинга, тот же отладчик Ollydbg изучить или дизассемблер IDA Pro. Но где искать по крохам эти знания? Нет, конечно можно годами "методом тыка" разбираться, но куда быстрее видеокурс специальный посмотреть. Вот тут он есть: ссылка. Автор курса с большим опытом и объясняет понятно, я из этого курса много узнал про то как работает компьютер, процессор, про инструменты специальные и как с ними работать. Мои коллеги программисты на работе ничего такого и не знают, теперь я им нос утру.
.. Netfilter Kernel Programming  //devol

В этой статье я постараюсь дать начальные сведения о netfilter'e и о том, как предотвратить Land-подобную атаку с помощью написания модуля для ядра.

И так, netfilter - это подсистема фильтрации пакетов в ядрах ветки 2.4/6.x, он же - первый встроенный в ядро контекстный брэндмауер (Stateful Firewall). Контекстный брэндмауер отличается от обычного тем, что он может определять, является ли настоящий пакет частью какого-либо соединения. В частности, в TCP протокол встроена система трехэтапного квинтирования. Для этого клиент шлет серверу запрос на соединение, указав в хедере флаг syn, на что сервак отвечает ему таким же пакетом, но плюс к syn флагу он еще добавляет флаг ack, указывая тем самым, что он хочет с ним установить соединение, после согласия на это клиента. Ну, так вот, обычный брэндмауер не способен отличить пакет, который будет идти в этой сессии соединения или же это какой-либо другой пакет, владелец которого уже секунд 20 назад установил соединение. Зато контекстный брэндмауер определяет, относится ли этот пакет к нашему с ним соединению или же к другому, посмотрев для этого таблицу коннектов. Примерно таким же образом он обрабатывает и другие протоколы: UDP, ICMP, etc (смотри /etc/protocols). В частности, такой тип брэндмауеров используется в Cisco. Ну да ладно, много интересного об архитектуре и особенностях netfilter'a вы можете узнать, поботав доки с www.netfilter.org.

А теперь поговорим о том, как же нам запрогать netfilter. Он способен перехватывать пакеты следующих сетевых стеков: IPv4, IPv6, DECnet. Мы рассмотрим только IPv4. Для данного стека в хереде /usr/include/linux/netfilter_ipv4.h определены следующие возможные значения захвата IP-пакетов (так называемые хуки):

 
 0.NF_IP_PRE_ROUTING: решаем, что делать с пакетом на входе.
 
 1.NF_IP_LOCAL_IN: входящий, для нашего компа.
 
 2.NF_IP_FORWARD: если пакет предназначен для другого интерфейса.
 
 3.NF_IP_LOCAL_OUT: если этот пакет создан локально.
 
 4.NF_IP_POST_ROUTING: решаем что делать с пакетом на выходе.
 
 
Перед тем, как к нам прилетит пакет, вызывается NF_IP_PRE_ROUTING хук. Далее вызывается функция, которая и решит, что мы сделаем с пакетом. Эти функции определены в /usr/include/linux/netfilter.h:
 
 0.NF_DROP: отбросить пакет.
 
 1.NF_ACCEPT: пропустить на дальнейшую обработку.
 
 2.NF_STOLEN: запомнить этот пакет в понятии котекстного брандмауера.
 
 3.NF_QUEUE: поставить пакет в очередь.
 
 4.NF_REPEAT: вызвать эту функцию повторно.
 
 
Структура объявления хуков определена в /usr/include/linux/netfilter.h:
 
 struct nf_hook_ops
 
 {
 
 /* член списка этой структуры используется для поддержки списка хуков
 
 netfilter'a и он не несет никакой смысловой нагрузки на регистрацию хука */
 
 	struct list_head list;
 
 /* укаказатель на хук-функию, см.выше */
 
 	nf_hookfn *hook;
 
 /* какое семейство протоколов будем использовать. Так как мы обусловились
 
 работать со стеком IPv4, то посмотрев хедер /usr/include/linux/socket.h,
 
 узнаем что это PF_INET */
 
 	int pf;
 
 /* какой из хуков мы будем использовать, см.выше */
 
 	int hooknum;
 
 /* каждому хуку можно назначить свой приоритет, для нашего стека см. файл
 
 /usr/include/linux/netfilter_ipv4.h */
 
 	int priority;
 
 };
 
 
Теперь же, чтобы зарегистрировать хук, нам понадобиться функция nf_register_hook, прототип которой определен в файле /usr/include/linux/netfilter.h.
 
 int nf_register_hook(struct nf_hook_ops *reg);
 
 
В качестве аргумента эта функция принимает выше обозначенную структуру. Для определения данных, которые передаются в хук-функцию, используется прототип nf_hookfn, который определен в том же хедере:
 
 typedef unsigned int nf_hookfn(unsigned int hooknum,
 
 			       struct sk_buff **skb,
 
 			       const struct net_device *in,
 
 			       const struct net_device *out,
 
 			       int (*okfn)(struct sk_buff *));
 
 
Здесь первый аргумент - это номер хука, а второй - указатель на указатель на sk_buff структуру, которая определена в /usr/include/linux/skbuff.h хедере. Это нужно для того, чтобы ядро знало, с какими пакетами мы работаем. Следующие два аргумента - это указатели на net_device структуру, определенную в /usr/include/linux/netdevice.h. Они используются для того, чтобы ядро знало, что за интерфейс мы используем (eth0, tap0, lo, etc). In и Out, соответственно, входящий и исходящий интерфейсы. В частности, in будет осуществлен для NF_IP_PRE_ROUTING и NF_IP_LOCAL_IN, а out - для NF_IP_POST_ROUTING и NF_IP_LOCAL_OUT хуков. Последний аргумент - функция, которая в качестве аргумента опять же принимает структуру sk_buff. Эта функция нужна, чтобы зря не расходовать процессор ожиданием пакета, который поставлен в очередь с помощью функции NF_QUEUE.

Так как все основные определения я уже дал, остается зашарить в ядерном написании модулей. Для этой цели поботайте статейки dev0id'a о "Linux Kernel Modules". Все, теперь я предоставлю исходник нашего фильтра пакетов, который будет обнаруживать пакеты, которые шлются при Land-атаке, т.е. где порт и IP атакуемого сервера совпадают с портом и IP этого же сервера (т.е. source=destination ip/port).

 
 /* хедеры */
 
 #define __KERNEL__
 
 #define MODULE
 
 #include <linux/module.h>
 
 #include <linux/kernel.h>
 
 #include <linux/netdevice.h>
 
 #include <linux/netfilter.h>
 
 #include <linux/netfilter_ipv4.h>
 
 /* структура, которую мы будем использовать для регистрации нашей функции */
 
 static struct nf_hook_ops nfho;
 
 
 
 /* интерфейс, который мы используем */
 
 static char *drop_if = "eth0";
 
 /* тут указываем наш ip-адрес, в данном случае 192.168.168.1 */
 
 static unsigned char *drop_ip = "\xc0\xa8\xa8\x01";
 
 /* порт. Укзываем пока что один открытый 80-ый порт, но реально дописать программу,
 
 которая будет отслеживать все открытые TCP/UDP-порты */
 
 unsigned char *deny_port = "\x00\x50";
 
 
 
 
 
 /* это наша хук-функция */
 
 unsigned int hook_func(unsigned int hooknum,
 
 				struct sk_buff **skb,
 
 				const struct net_device *in,
 
 				const struct net_device *out,
 
 				int (*okfn)(struct sk_buff *))
 
 {
 
 	struct sk_buff *sb = *skb;
 
 	struct tcphdr *port;
 
 	port = (struct tcphdr *)(skb->data + (skb->nh.iph->ihl * 4));
 
 	if ((strcmp(in->name, drop_if) == 0) &&
 
 		(sb->nh.iph->saddr == drop_ip) &&
 
 		((skb->nh.iph->protocol != IPPROTO_TCP) ||
 
 		 (skb->nh.iph->protocol != IPPROTO_UDP)) &&
 
 		((port->dest) == *(unsigned short *)deny_port))
 
 	{
 
 		printk("Packet dropped...");
 
 		return NF_DROP;
 
 	}else{
 
 		return NF_ACCEPT;
 
 	}
 
 }
 
 
 
 /* сандартная функция инициализации */
 
 int init_module()
 
 {
 
     nfho.hook     = hook_func;
 
     nfho.hooknum  = NF_IP_PRE_ROUTING;
 
     nfho.pf       = PF_INET;
 
     nfho.priority = NF_IP_PRI_FIRST;
 
 
 
     nf_register_hook(&nfho);
 
 
 
     return 0;
 
 }
 
 
 
 /* стандартная функция удаления модуля */
 
 void cleanup_module()
 
 {
 
     nf_unregister_hook(&nfho);
 
 }
 
 
Ну вот собственно и все, что я хотел рассказать в этой вводной статье. Ботайте физику и, физтех - рулез!

Основные источники:
[0] http://netfilter.org
[1] http://lists.netfilter.org/pipermail/netfilter-devel/
[2] http://www.geocities.com/victorhugo83/
[3] http://www.linuxsecurity.com/feature_stories/kernel-netfilter.html

[c] devol aka cl1mp3x, (XFree86@mail.ru).

<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS