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

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


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

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



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

Существует в BSD системах очень удобный интерфейс bpf, что расшифровывается как "Пакетный Фильтр Беркли". Его использует каждый сниффер, вспомните хотя бы tcpdump или ipgrab. Для прямой работы с этим фильтром написана очень удобная библиотека libpcap, которую можно скачать с сайта производителя: www.tcpdump.org. Чем же замечательна эта библиотека?

 typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
 			     const u_char *);
 char	*pcap_lookupdev(char *);
 int	pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
 pcap_t	*pcap_open_live(char *, int, int, int, char *);
 pcap_t	*pcap_open_dead(int, int);
 pcap_t	*pcap_open_offline(const char *, char *);
 void	pcap_close(pcap_t *);
 int	pcap_loop(pcap_t *, int, pcap_handler, u_char *);
 int	pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
 const u_char*
 	pcap_next(pcap_t *, struct pcap_pkthdr *);
 int	pcap_stats(pcap_t *, struct pcap_stat *);
 int	pcap_setfilter(pcap_t *, struct bpf_program *);
 int	pcap_getnonblock(pcap_t *, char *);
 int	pcap_setnonblock(pcap_t *, int, char *);
 void	pcap_perror(pcap_t *, char *);
 char	*pcap_strerror(int);
 char	*pcap_geterr(pcap_t *);
 int	pcap_compile(pcap_t *, struct bpf_program *, char *, int,
 	    bpf_u_int32);
 int	pcap_compile_nopcap(int, int, struct bpf_program *,
 	    char *, int, bpf_u_int32);
 void	pcap_freecode(struct bpf_program *);
 int	pcap_datalink(pcap_t *);
 int	pcap_snapshot(pcap_t *);
 int	pcap_is_swapped(pcap_t *);
 int	pcap_major_version(pcap_t *);
 int	pcap_minor_version(pcap_t *);
 FILE	*pcap_file(pcap_t *);
 int	pcap_fileno(pcap_t *);
 pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
 void	pcap_dump_close(pcap_dumper_t *);
 void	pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
 int	pcap_findalldevs(pcap_if_t **, char *);
 void	pcap_freealldevs(pcap_if_t *);
 u_int	bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
 int	bpf_validate(struct bpf_insn *f, int len);
 char	*bpf_image(struct bpf_insn *, int);
 void	bpf_dump(struct bpf_program *, int);
 
это неполный список функций взятых из заголовочного файла pcap.h. Полную информацию о назначении каждой из функций вы можете подчерпнуть из третьей man страницы pcap, моя же цель - предоставить вам достаточную информацию по написанию простого сниффера.

Как вы знаете, для того чтобы сниффер заработал, его нужно запускать из под рута, так как к bpf устройству доступ есть только у него, не забывайте это при тестировании своего творения.

Поиск устройства
Есть две возможности перехвата трафика: это перехват в промиск-моде и вне него. В первом случае вы перехватываете весь трафик в сети (при условии, что нет свитчей, или их память переполнена арп таблицей - они все работают как простые хабы, и отсутствии роутеров), во втором случае, вы сможете перехватывать только исходящий или приходящий трафик (непосредственно через вашу сетевую карту).
Из этого следует, что при установке сниффера следует выбирать тот интерфейс, на котором вероятность перехвата трафика выше. Выполнить поиск интерфейса можно при помощи функции pcap_lookupdev(); Она вернет указатель на массив символьного типа с названием интерфейса. Стоит также отметить, что вернет она первый интерфейс, находящийся в НЕ_ПРОМИСК_МОДЕ, так что не удивляйтесь, если у вас на машине, на которой стоит arpwatch вернется какой-нить "не тот" интерфейс.

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

 pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
первый параметр - указатель на название устройства (помните предыдущий вызов?), второй и третий - маска сети и ее адрес. Стоит подробно остановится на обсуждении четвертого параметра: дело в том, что это буфер для возврата всех ошибок, полученных при вызовах функция pcap’a. Его описывают следующим образом:
char ebuf[PCAP_ERRBUFF_SIZE];
Замете, что данный буфер используется в большинстве функция pcap’a.

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

pcap_open_live(char *, int, int, int, char *);
Несколько слов о параметрах: первый - это устройство, второй - количество байт, необходимых для перехвата, третий - бит промиск мода, если он утановлен, то он включается, помните я говорил о вариациях сниффинга? Четвертый – это таймаут (в миллисекундах) и последний - буфер для ошибок. Возвращает эта функция указатель на сессию. Пример:
 #include <stdio.h>
 #include <pcap.h>
 
 int
 main(int argc, char *argv[])
 {
 	char *dev,ebuf[PCAP_ERRBUFF_SIZE];
 	pcap_t *ptr;
 	bpf_u_int32 mask,net;
 
 	if (argc <2)
 		dev=pcap_lookupdev(ebuf);
 	else
 		dev=argv[1];
 
 printf(“We’v choisen the %s – device\n”,dev);
 pcap_lookupnet(dev, &net, &mask,  ebuf);
 ptr=pcap_open_live(dev, BUFSIZ, 1, 0, ebuf);
 }
 
Собственно наш пример пока ничего не делает, кроме того, что принимает в качестве параметра командной строки название устройства (в случае отсутствия параметра ищет устройство сам), выводит полученную информацию и открывает сессию, переводя сетевую карту в режим прослушивания.

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

 …….
 struct bpf_program  bpf_filter;
 char filter_buf[]=”foo”;
 ……..
 pcap_compile(ptr, &bpf_filter, filter_buf, 0, net);
 pcap_setfilter(ptr, &bpf_filter);
 ……...
 
Основной цикл
Процесс перехвата обычно происходит в определенном цикле. За организацию данного цикла отвечают некоторые функции, о которых вы можете подчерпнуть из man страниц. Вот одна из них:
const u_char* 	pcap_next(pcap_t *, struct pcap_pkthdr *);
Первый параметр - это указатель на нашу сессию, второй - указатель на следующую структуру:
 struct pcap_pkthdr {
 	struct timeval ts;	/* time stamp */
 	bpf_u_int32 caplen;	/* length of portion present */
 	bpf_u_int32 len;	/* length this packet (off wire) */
 };
 
Данная структура (заголовок пакета) взята из pcap.h. На самом деле, данная функция не создает цикла, она просто берет следующий пакет из очереди и возвращает на него указатель.
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
Первый параметр – сессия, второй - количество пакетов, которые следует перехватить прежде чем обработать, третий - указатель на функцию-обработчик, который будет обрабатывать что-то (например этот самый пакет), и последний параметр, который может вообще не использоваться, просто указывается NULL (хотя стоит признать тот факт, что некоторые программные продукты его используют: для подробной информации обращайтесь к man). Небольшой пример:
 //вырезано
 void
 analiz(u_char *stuff,const struct pcap_pkthdr *hdr,const u_char *packet)
 {
 	printf(“New packet has arrived!\n”);
 }
 
 //часть инициализации вырезана
 //сама функция цикла:
 
 pcap_loop(handle, -1, analiz, NULL);
 
Теперь, если запустить данную программу без фильтрации, то мы сможем увидеть появление данной надписи столько раз, сколько пакетов прийдет к нам на карту:
 Aucronix# ./test-snif rl1
 New packet has arrived!
 New packet has arrived!
 New packet has arrived!
 New packet has arrived!
 New packet has arrived!
 ………………………..
Для написания большого проекта желательно знать как можно лучше устройство сети, в их познании вам помогут различные rfc. А я на этом заканчиваю, продолжение следует...

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

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




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



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


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