...

суббота, 1 февраля 2014 г.

Дайджест интересных материалов из мира веб-разработки и IT за последнюю неделю №93 (26 января — 1 февраля 2014)


сегодня в 23:25


Предлагаем вашему вниманию подборку с ссылками на полезные ресурсы, интересные материалы и IT-новости




Веб Разработка




CSS




JavaScripts




Веб-инструменты




Новости







Браузеры




Сайты с интересным дизайном и функциональностью




Дизайн




Подборка бесплатных дизайнерских печенек




Демо




Занимательное






Просим прощения за возможные опечатки или неработающие/дублирующиеся ссылки. Если вы заметили проблему — напишите пожалуйста в личку, мы стараемся оперативно их исправлять.

Дайджест за прошлую неделю.

Материал подготовили dersmoll и alekskorovin.




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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


20-граммовый орнитоптер с системой стереоскопического зрения самостоятельно огибает препятствия


сегодня в 21:41


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





Кроме двух микрокамер, обеспечивающих стереокартинку, DelFly Explorer использует для ориентации в пространстве гироскопы и барометр. Сейчас орнитоптер умеет только летать по комнате на заданной высоте, не натыкаясь на препятствия. В будущем сотрудники лаборатории хотят научить его пролетать сквозь дверные и оконные проёмы, чтобы его полёт не ограничивался одной комнатой. Хотя говорить о коммерческом применении пока рано, учёные считают, что в будущем подобные роботы могут использоваться для обследования промышленных объектов и установок, залетая в самые труднодоступные места.


image


Летом прошлого года лаборатория миниатюрных летательных аппаратов представила ещё одну разработку — самый маленький в мире автопилот для квадрокоптеров. Плата автопилота на базе микроконтроллера ARM Cortex M3 MCU, снабжённая акселерометрами, гироскопами, барометром, магнетометром и GPS, имеет размеры всего два на два сантиметра и весит 2,8 грамма. Этот автопилот — часть большого проекта по созданию свободных и открытых беспилотников Paparazzi.




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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[Перевод] Джо Армстронг об инструментах разработчика

Недавно на Erlang-mail листе проскочил следующий вопрос:


Тулы, которые у нас есть для разработки на Erlang — просто мусор! Я прошу прощения, но сейчас 2014-ый, а мы все еще используем Vim и Makefile'ы. Да, есть Rebar. Но по сравнению с Maven, Gradle (или даже SBT) это студенческая поделка, которую кто-то выложил на GitHub. Про плагины для Eclipse и Intellij я вообще молчу. Они просто не работают. Поэтому я всегда возвращаюсь к Vim. Я просто хочу писать код, который решает мою задачу а не думать о том как написать Makefile со всеми зависимостями.







Ответ Джо Армстронга, автора языка Erlang:

Тулы никогда не смогут заменить вам головы. Ничто, из того, что вы перечислили не помогает мне думать. В реальной жизни, бОльшая часть времени уходит именно на обдумывание задачи. Поэтому, как только у вас есть решение — вы сможете запрограммировать его в течении пары часов.


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


Есть два тип программистов. Одни пишут 10 строк в день и уверенно двигаются к конечному продукту. Другие — пишут 100 или даже 1000 строк в день но топчутся на месте. Они никода не получат продукт, потому-что не понимают какую задачу решают. Они пишут тонны кода, чтобы это понять. Это создает иллюзию занятости и неплохо оплачивается.


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


Я предпочитаю думать о том, как на самом деле работает мое приложение, а не о том, как работает Eclipse. Редактирование кода — это не проблема. Меня вполне устраивает Emacs или даже ручка с бумагой, которые, в отличее от Eclipse, всегда можно взять с собой.


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


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


Я помню времена, когда программисты отлично понимали друг друга. Каждый, кто умел программировать — знал как написать Makefile и bash скрипт. Сейчас же, человек который ничего не видел кроме Java и Maven входит в ступор, когда ему присылают Rake-файл.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Как сотрудники газеты Guardian уничтожали компьютеры с файлами Эдварда Сноудена


сегодня в 20:40


20 июня 2013 года под присмотром агентов Центра правительственной связи Великобритании трое сотрудников лондонского офиса газеты Guardian с помощью болгарок, дрелей и электрогравёров буквально стёрли в порошок несколько компьютеров, на которых хранились файлы, добытые Эдвардом Сноуденом. Вчера, 31 января, впервые опубликовано видео, на котором запечатлёно это абсрудное действо. Несмотря на то, что файлы Сноудена хранятся ещё в нескольких местах, и с ними продолжают работать журналисты иностранных отделений Guardian, а так же других СМИ, с которыми Сноуден поделился информацией, власти Великобритании вынудили Guardian физически уничтожить несколько редакционных компьютеров.





По словам заместителя редактора Guardian Пола Джонсона, который с двумя коллегами принимал участие в процессе, на то, чтобы полностью разрушить жёсткие диски и все электронные компоненты компьютеров в строгом соответствии с указаниями сотрудников спецслужб, ушло три часа. «Это был чисто символический акт. Мы знали это. Сотрудники Центра правительственной связи знали это. И само правительство тоже знало. Это было самое сюрреалистичное событие в британской журналистике, какое мне довелось видеть» — говорит он.


Этому «уничтожению» информации предшествовал длительный конфликт журналистов со спецслужбами, в ходе которого последние требовали не просто уничтожить файлы на своих компьютерах, но и предварительно передать их властям для анализа. Редактор Guardian Алан Расбриджер категорически отказался это делать, ссылаясь на своё право не раскрывать конфиденциальные источники информации. Газете даже угрожали закрытием. В качестве компромисса стороны сошлись на демонстративном уничтожении техники. Возможно, спецслужбы таким образом пытались сохранить лицо и продемонстрировать свою власть, даже несмотря на то, что это абсолютно бессмысленно в практическом плане и никак не может помешать прессе и дальше публиковать материалы Сноудена.





Свежий взгляд

на бег


протестируй кроссовки

нового поколения




Стань

первоиспытателем!


Скачай Windows Server 2012 R2

и выиграй почетную футболку!


Скачать



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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[recovery mode] Сравнительный тест зарядных устройств на 5В и кабелей microUSB

Перебор нескольких зарядных устройств (ЗУ) для телефона в автомобиль показал, что недорогие ЗУ noname, какой бы ток ни заявлялся производителем, телефон не заряжают. Проблема решена приобретением автомобильного ЗУ Nokia DC-17 (заявлено до 1000мА). Однако затем HTC Wildfire S с батареей 1300 мАч для заряда которой с лихвой достаточно 0,5А, заменен на Lenovo P780 с батареей 4000 мАч, требующей уже 2А.


И это привело к новой проблеме – Nokia DC-17, тихо и быстро заряжавшая старый телефон, при заряде нового громко пищала. Что мешало слушать музыку и вызывало беспокойство за ЗУ и за телефон.

Подбор ЗУ в автомобиль занял некоторое время и привел к неожиданному выводу.



Nokia DC-17 отдана в дар, куплено ЗУ для планшетов Samsung ECA-P10CBE (2000мА). А так как кабель в комплекте имел оригинальный коннектор для планшетов Samsung, пришлось использовать ЗУ с первым попавшимся кабелем microUSB. Телефон заряжался с током 0,11А, что недостаточно – в режиме навигатора телефон медленно, но разряжался. А стоило заменить шнурок на оригинальный, и ток заряда увеличился до 0,145А. Ток не зависел от того – стоит ли ЗУ в прикуривателе или подключено через «тройник».



Этот неожиданный результат послужил основанием проверить все имеющиеся под рукой ЗУ и кабели с помощью купленного в китайском интернет магазине устройства USB Charger Doctor. Не внесенного в российский реестр средств измерений и неповеренного, но уж как есть. Перед каждым новым измерением телефон стоял на зарядке около 1мин. Батарея телефона перед серией испытаний была заряжена на 8%, в процессе дозарядилась до 15%.


Первым этапом испытывались ЗУ с оригинальным кабелем от Lenovo P780:

1) оригинальная Lenovo (заявлено до 2A) – 1,85А

2) Samsung (заявлено до 2А) – 1,85А

3) HTC (заявлено до 1A) – 1,24A

4) Sony Ericsson (заявлено до 0,85A) – 0,90A

5) Sony (заявлено до 0,5A) – 0,81A

6) Samsung (заявлено до 1A) – 0,68A



Noname ЗУ не исследованы по причине того, что опытным путем давно определены как негодные и выкинуты. Возможности же фирменных ЗУ, как следует из теста, примерно соответствуют заявленным.


Вторым этапом сравнивались кабели microUSB с родным кабелем от Lenovo (на фотографиях выше), который позволял заряжать тот же самый телефон от того же ЗУ на ток 1,85А:

1) Sony Ericsson – 1,86A

2) Короткий кабель Nokia – 1,87А

3) Длинный кабель Nokia – 1,30A

4) Добротный на ощупь длинный и тонкий noname кабель №1 – 0,90А

5) Noname кабель №2 – 0,61А

6) Тонкий кабель Samsung – 0,42A

7) Nomame кабель №3 – 0,15А

8) Noname кабель №4 – 0,10А



Только два кабеля позволяли также быстро заряжать телефон от родного ЗУ, как и родной из комплекта. Еще один-два в принципе пригодны, остальные для заряда телефона использованы быть не могут.


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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Программируем nRF24LE1 через Raspberry PI и USBasp

image

Некоторое время назад на хабре упоминались недорогие (от $6 ) радио модули nRF24LE1 со встроенным микроконтроллером.На этих радио модулях ребята из COOLRF планировали осуществлять свой проект, но в итоге «переехали» на более дорогой чип Atmega128RFA1, а nRF24LE1 как я понял отодвинули на второй план.

В статье мы рассмотрим возможность прошивки радио модуля через Raspberry PI и USBasp а так же пару примеров кода на Си.



Описание nRF24LE1




Существует 3 варианта корпуса чипа: QFN24 (4×4 mm), QFN32 (5×5 mm), QFN48 (7×7 mm).И периферия I2C, UART, SPI находятся на разных выводах (см с 131 страницы даташита). Здесь я рассмотрю вариант QFN32 и технические характеристики будут относится к нему.

Радио передающая часть полностью аналогична «безмозглому» варианту nRF24L01:

2.4 Ггц,125 каналов. Поддерживаемые скорости 250kbps, 1Mbps и 2Mbps и т.д.


Встроенный же 8051-совместимый микроконтроллер имеет следующие параметры:



  • Тактовая частота 16мгц.Частотой можно управлять (понижать до 125кгц) в реальном времени.

  • Доступная flash память для программы 16кб.

  • ОЗУ (RAM) память 1 кб.

  • 1 кб. NVRAM (EEPROM память)

  • 7 выводов поддерживают 6..12 битных АЦП .

  • Два восьмибитных PWM (ШИМ) вывода.

  • А так же имеются интерфейсы: I2C, UART, SPI.

  • Напряжение питания 1,9В...3,6В.

  • Программирование через slave SPI.




Программирование nRF24LE1 через Raspberry PI




Прошить nRF24LE1 возможно через «родной» программатор, который относительно дорог — около $30 на Ebay. Цена мне конечно не понравилась и на просторах интернета был найден вариант программатора на основе Raspberry PI http://ift.tt/MJoR9f. Исходный код программатора был немного модифицирован и русифицирован — пришлось переводить с португальского. Модифицированную версию можно скачать по ссылке в конце статьи.

Для программирования радио модуля необходимо подключить выводы SPI согласно таблице:

image

Вывод PROG nRF24LE1 необходимо подключить к 24 выводу GPIO на Raspberry PI. FCSN подключаем аналогично на СЕ0 (вывод 8) .Reset подтягиваем на плюс.Не забываем подключить GND и VDD к 3.3в.

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


Для заливки прошивки воспользуемся скомпилированной программой nrf24le1 используя следующие команды:



  • ./nrf24le1 test — выводит тестовую информацию nRF24LE1 (InfoPage).

  • ./nrf24le1 write — прошьет файл main.bin, лежащий в этой же папке в nRF24LE1.

  • ./nrf24le1 read -создаст дамп прошивки из nRF24LE1 под имененем main-dump.bin .




Программирование nRF24LE1 через USBasp




После изучения варианта прошивки через Raspberry PI, был разработан свой вариант более простой, который может реализовать любой пользователь, программирующий микроконтроллеры AVR и имеющий на вооружении программатор USBasp. Про данный программатор ранее я упоминал, реализовав на нём несколько разнообразных устройств в том числе nRF24L01-USB.

Для данной идеи был использован тот же исходный код программатора под Raspberry PI. А USBasp перепрограммирован в USB-SPI переходник используя библиотеку V-USB.

Программатор на базе USBasp относительно медленный -вся прошивка в 16кб. «заливается» за 12 секунд, но это компенсируется ценой — все же цена этого программатора $3, а не $30.

Подключение nRF24LE1 к USBasp в следущем порядке, по нумерации десяти контактного разъема:

image

Кстати, неясно толерантны ли выводы nRF24LE1 к 5 Вольтам и нужны ли делители на резисторах для согласования уровней между nRF24LE1 и USBasp. В итоге я не использовал делители и никаких негативных последствий не получил — Вы можете так же не устанавливать делители, но на свой страх и риск. Например у nRF24L01+ выводы толеранты и допускают подключение 5 Вольтовым микроконтроллерам.

Все действия по программированию аналогичны программированию через Raspberry PI.

Пишем первые программы на nRF24LE1




Для написания программы я воспользовался бесплатным кросс платформенным компилятором SDCC sdcc.sourceforge.net/.

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


#include <stdint.h>
#include <stdio.h>

//подключение необходимых функций SDK:

#include "src/gpio/src/gpio_pin_configure.c"
#include "src/gpio/src/gpio_pin_val_clear.c"
#include "src/gpio/src/gpio_pin_val_set.c"

#include "delay.h"
#include "src/delay/src/delay_us.c"
#include "src/delay/src/delay_s.c"
#include "src/delay/src/delay_ms.c"

void main()
{
// мигаем портом P0_0
gpio_pin_configure(GPIO_PIN_ID_P0_0, // укажем необходимые параметры
GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT |
GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR |
GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH);

while(1)
{
gpio_pin_val_set(GPIO_PIN_ID_P0_0); // установка в 1
delay_ms(500);
gpio_pin_val_clear(GPIO_PIN_ID_P0_0); //установка в 0
delay_ms(500);
}
}







Пример плавного зажигания светодиода используя PWM вывод


#include <stdio.h>

//подключение необходимых функций SDK:
#include "delay.h"
#include "src/delay/src/delay_us.c"
#include "src/delay/src/delay_s.c"
#include "src/delay/src/delay_ms.c"

#include "src/pwm/src/pwm_configure.c"
#include "src/pwm/src/pwm_start.c"

void main()
{
int i=0;
// делитель на 10 , битность 8
pwm_configure(PWM_CONFIG_OPTION_PRESCALER_VAL_10 || PWM_CONFIG_OPTION_WIDTH_8_BITS);

//main program loop
while(1)
{

pwm_start(PWM_CHANNEL_0,i);

i++;

delay_ms(200);

if (i>255) i=0;

}
}





В данный момент доделываю пример для работы с nRF24L01-USB. Уже реализовано чтение датчика DHT22 и управление нагрузками по радиоканалу. В будущем планирую сделать примерный аналог библиотеки Arduino RF24 -осталось доделать пару функций.

В целом, после программирования на микроконтроллерах AVR программирование nRF24LE1 мне показался не чуть не сложным.


Какие подручные железки можно ещё переделать под программирование nRF24LE1 ?




Подойдет любой аналогичный мини компьютеру Raspberry PI, например Cubieboard.

Можно реализовать программатор на Arduino.Возможно займусь таким вариантом.

Любой микроконтроллер с аппаратной поддержкой USB, например STM-ки.

Исходные коды и пример:

Программатор на Raspberry PI

Программатор на USBasp

SDK

led_delay

Даташит


Может что-то упустил и остались вопросы — пишите в комментариях.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Кровлинг с поддержкой JavaScript/Ajax/DomMutation или SlimerJS + CasperJS + Magic = Profit

Сегодня вновь очень активно развивается тема автоматизации тестирования безопасности веб-приложений с использованием PhantomJS в связке с BurpSuite, ModSecurity, Garmr и т.д. Я не стал исключением, о своём опыте разработки относительно рабочего прототипа кровлера с поддержкой Javascript, Ajax и DomMutation я бы и хотел с вами поделится. Может это поможет кому-то разработать собственное решение, которое будет гораздо лучше. Всех заинтересованных прошу под кат:-)



Надеюсь, никто не станет спорить, что существующие веб-приложения это адское варево из различных технологий и чем дальше тем больше логики перемещается с серверной части на клиентскую. Разумеется, это не могло не сказаться на отделах ИБ, которые и без того зачастую не столь велики, а тут еще и привычные методики автоматизированного тестирования просто обламываются на корню. В один момент стало ясно, что для первичного анализа решений уже не хватает статического анализа и привычной схемы html-парсер+фаззер. Так было принято решение исследовать этот вопрос и попробовать что-то с этим сделать.

Почему поддержка Javascript, Ajax и мутаций столь важна?




Потому как иначе никак:-) История знает массу примеров, когда отсутствие даже простейшей поддержки Javascript в сканерах безопасности сводила их эффективность на нет. К примеру, CSRF в Яндекс.Почта — если в GET параметрах передать изменение настроек пользователя, бекенд честно ответит ошибкой о невалидном CSRF-токене и тогда JavaScript движок переотправлял(!) этот же запрос, но уже дополнив запрос валидным токеном:) Получается, с позиции бекенда все более чем правильно, но с позиции клиента… Или XSS при переводе письма на любой из языков — история аналогичная, примитивная уязвимость которую не смог бы обнаружить w3af и иже с ним. Отсутствие поддержки JavaScript на текущий момент времени, кажется просто недопустимым и необходимо всеми силами стараться это исправить.

Как быть?




Я решил воспользоваться существующими идеями и взять за основу любимые SlimerJS и CasperJS и попробовать получить на выходе кровлер с возможностью рекурсивного обхода событий элементов DOM + мониторинг мутаций для выявления «патологий», XSS уязвимостей и прочего. Почему не PhantomJS? Потому как в нем пока нет поддержки MutationObserver, который был мне нужен для анализа мутаций. И так, я представил себе целостную систему состоящую из четырёх больших блоков:

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

* Прокси, который смог бы собрать данные для дальнейшего фаззинга и запуска остальной части проверок зависящих от контекста

* Фикстуры в веб-приложении, с заранее подготовленными метками, на которые ориентируется кровлер.

* Отчет на основе diff'а с предыдущими результатами сканирования

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

image

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



Доступно тут (пока не убьёт Хабраеффект): http://ift.tt/1ks2TTo.

Исходный ход: http://ift.tt/MJoQCo

К примеру, если запустить w3af, с плагином webSpider, то никаких Ajax запросов обнаружено не будет, а между тем они не редко уязвимы по ряду очевидных причин.У Skipfish будет примерно такой же результат.

Я подготовил небольшой прототип для подтверждения работоспособности алгоритма, доступен на github. В корне проекта есть тестовый скрипт «test.js»:

var Spider = require('lib/spider').Spider;
var utils = require('utils');

(function start() {
"use strict";

var startTime = new Date().getTime();
var spider = new Spider();
var url = 'http://ift.tt/MJoQSE';
if (spider.cli.has(0))
url = spider.cli.get(0);

spider.initialize({
targetUri: url
});

spider.start(url);
spider.then(spider.process);
spider.run(function() {
this.echo('\n<---------- COMPLETED ---------->\n');

var deltaTime = new Date().getTime() - startTime;
deltaTime = (deltaTime / 1000).toFixed(2);
this.echo('time: ' + deltaTime + 'sec');
this.echo('Processed pages:' + this.pagesQueue.length);
utils.dump(this.pages);
spider.exit();
});
})();




Суть которого запустить процесс кровлинга и вывести «сырой» результат, опробуем на моём примере:

$ ./test.sh http://ift.tt/1ks2TTo

<---------- COMPLETED ---------->

time: 3.61sec
Processed pages:1
[
{
"url": "http://ift.tt/1ks2TTo",
"opened": true,
"processed": true,
"reloadCount": 0,
"status_code": 200,
"jsErrors": [],
"xss": [],
"xssHashMap": [],
"pages": [],
"events": [
{
"eventType": "click",
"path": "id(\"user-Lisa\")/DIV[3]/BUTTON[1]",
"parentEvent": null,
"depth": 0,
"status": "completed",
"completed": true,
"deleted": false,
"xss": [],
"xssHashMap": [],
"events": [
{
"eventType": "click",
"path": "//DIV[4]",
"parentEvent": null,
"depth": 1,
"status": "completed",
"completed": true,
"deleted": false,
"xss": [],
"xssHashMap": [],
"events": [],
"resourses": []
}
],
"resourses": [
"http://ift.tt/MJoQSG"
]
},
{
"eventType": "click",
"path": "id(\"user-Jimmy\")/DIV[3]/BUTTON[1]",
"parentEvent": null,
"depth": 0,
"status": "completed",
"completed": true,
"deleted": false,
"xss": [
{
"innerHtml": "Another XSS...",
"path": "id(\"userInfoDescription\")/XSSMARK[1]",
"initiator": null,
"dbRecord": null
}
],
"xssHashMap": [
0
],
"events": [],
"resourses": [
"http://ift.tt/1ks2RuY"
]
},
{
"eventType": "click",
"path": "id(\"user-Mark\")/DIV[3]/BUTTON[1]",
"parentEvent": null,
"depth": 0,
"status": "completed",
"completed": true,
"deleted": false,
"xss": [],
"xssHashMap": [],
"events": [],
"resourses": [
"http://ift.tt/MJoQSI"
]
},
{
"eventType": "click",
"path": "id(\"user-Tommy\")/DIV[3]/BUTTON[1]",
"parentEvent": null,
"depth": 0,
"status": "completed",
"completed": true,
"deleted": false,
"xss": [],
"xssHashMap": [],
"events": [],
"resourses": [
"http://ift.tt/1ks2RLg"
]
}
],
"deferredEvents": [],
"startTime": 1391266464847,
"endTime": 1391266466787,
"resourses": [
"http://ift.tt/1ks2TTo"
]
}
]





Видите у событий Ajax запросы за данными о пользователе? Это как раз то, что нам нужно! Согласен, текущий отладочный вывод немного избыточен, зато информативен. Из него видно, что он успешно обнаружил дополнительные запросы при обработке событий кнопок «More info», которые можно пофаззить в будущем. В довесок благодаря фикстурам в веб-приложении он смог сразу же обнаружить и XSS в мутациях, о чем любезно сообщил. Пока работает не очень быстро, но я активно работаю над этим в свободное время. Другой отличный пример это linkedin, вот результат работы для 5ти его страниц (начиная с главной):



Зеленные узлы — обработанные события элементов

Синие — ресурсы которые были запрошены при их обработке

Как видите, в подобных веб-приложениях с множеством «цепочных» событий этот подход может быть эффективен!

Итог




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

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

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Как бесплатно получить профессиональный аккаунт в Wunderlist


сегодня в 19:22


Многие используют в работе таск-менеджер Wunderlist. Он подкупает кроссплатформенностью и бесплатностью, но за деньги предлагаются такие интересные функции, как добавление файлов, делегирование задач, неограниченные подзадачи и общение. Отдавать 5 долларов в месяц (или 50 долларов в год) за продукт, повышающий продуктивность, не должно быть жалко, но есть бесплатный способ получения профессионального аккаунта.

Как мне показалось, он не является очевидным, потому что я, как и большинство, использую настольный и мобильный клиенты, и там такой функции нет. Но если посетить веб-версию Wunderlist, то можно обнаружить интересный функционал.

Идем на www.wunderlist.com и авторизуемся. Кликаем по своему аватару в верхнем левом углу страницы и в меню выбираем «Получите Wunderlist Pro бесплатно».



Добавляйте адреса своих друзей и получайте 1 месяц за каждого (лимит — 12 месяцев).



Да, приглашенный друг тоже получит 1 месяц PRO-аккаунта.



Свежий взгляд

на бег


протестируй кроссовки

нового поколения




Стань

первоиспытателем!


Скачай Windows Server 2012 R2

и выиграй почетную футболку!


Скачать



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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Chef за 21 день. Часть третья. Chef и AWS


{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Template for stack",

"Parameters" : {

"KeyName" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
"Type" : "String",
"MinLength" : "1",
"MaxLength" : "255",
"AllowedPattern" : "[\\x20-\\x7E]*",
"ConstraintDescription" : "can contain only ASCII characters."
},

"HostKeys" : {
"Description" : "Public Key",
"Type" : "String"
},

"SecretAccessKey" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
"Type" : "String"
},

"InstanceType" : {
"Description" : "Chef Server EC2 instance type",
"Type" : "String",
"Default" : "m1.small",
"AllowedValues" : [ "t1.micro","m1.small"],
"ConstraintDescription" : "must be a valid EC2 instance type."
},

"SSHLocation" : {
"Description" : " The IP address range that can be used to SSH to the EC2 instances",
"Type": "String",
"MinLength": "9",
"MaxLength": "18",
"Default": "0.0.0.0/0",
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
}

},

"Mappings" : {
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "64" },
"m1.small" : { "Arch" : "64" }
},

"AWSRegionArch2AMI" : {
"us-east-1" : { "32" : "ami-d7a18dbe", "64" : "ami-bba18dd2", "64HVM" : "ami-0da96764" },
"us-west-2" : { "32" : "ami-def297ee", "64" : "ami-ccf297fc", "64HVM" : "NOT_YET_SUPPORTED" },
"us-west-1" : { "32" : "ami-923909d7", "64" : "ami-a43909e1", "64HVM" : "NOT_YET_SUPPORTED" }
}
},

"Resources" : {

ChefClient" : {
"Type" : "AWS::EC2::Instance",
"Metadata" : {
"Description" : "Chef Client",

"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"yum" : {
"git" : []
}
}
}
}
},

"Properties": {
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
"InstanceType" : { "Ref" : "InstanceType" },
"SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],
"KeyName" : { "Ref" : "KeyName" },

"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",

"yum update -y aws-cfn-bootstrap\n",

"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n",
" exit 1\n",
"}\n",

"yum update -y\n",
"yum install git -y\n",
"/sbin/service iptables stop\n",
"/sbin/service ip6tables stop\n",
"/sbin/chkconfig iptables off\n",
"/sbin/chkconfig iptables off\n",
"yum install git -y\n",


"/usr/bin/curl -L http://ift.tt/1hlhsH9 | bash\n",
"cd /root/\n",
"/usr/bin/git http://ift.tt/1ijoRr1",
"/bin/mkdir -p /root/chef-repo/.chef\n",
"/bin/mkdir -p /etc/chef\n",

"/bin/mkdir /root/.aws\n",
"/bin/touch /root/.aws/config\n",
"/bin/echo '[default]' >> /root/.aws/config\n",
"/bin/echo 'region = ", {"Ref" : "AWS::Region" }, "' >> /root/.aws/config\n",
"/bin/echo 'aws_access_key_id = ", { "Ref" : "HostKeys" }, "' >> /root/.aws/config\n",
"/bin/echo 'aws_secret_access_key = ", { "Ref" : "SecretAccessKey" }, "' >> /root/.aws/config\n",


"/usr/bin/aws s3 cp s3://storage/admin.pem /root/chef-repo/.chef\n",
"/usr/bin/aws s3 cp s3://storage/chef-validator.pem /root/chef-repo/.chef\n",
"/usr/bin/aws s3 cp s3://storage/knife.rb /root/chef-repo/.chef\n",
"/usr/bin/aws s3 cp s3://storage/client.rb /etc/chef\n",
"/usr/bin/aws s3 cp s3://storage/json_attribs.json /etc/chef\n",
"/bin/cp -p /root/chef-repo/.chef/chef-validator.pem /etc/chef/validation.pem\n",
"/usr/sbin/ntpdate -q 0.europe.pool.ntp.org\n",


"/bin/echo '\nchef_server_url \"", { "Ref" : "ChefServerURL" }, "\"' >> /etc/chef/client.rb\n",
"/bin/echo '\nchef_server_url \"", { "Ref" : "ChefServerURL" }, "\"' >> /root/chef-repo/.chef/knife.rb\n",

"/usr/bin/chef-client\n",

"/opt/aws/bin/cfn-signal -e 0 -r \"ChefClient setup complete\" '", { "Ref" : "WaitHandle" }, "'\n"

]]}}
}
},

"WaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},

"WaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "ChefClient",
"Properties" : {
"Handle" : {"Ref" : "WaitHandle"},
"Timeout" : "1200"
}
},



"ChefServer" : {
"Type" : "AWS::EC2::Instance",
"Metadata" : {
"Description" : "Bootstrap ChefServer",

"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"yum" : {
"wget" : []
}
}
}
}
},

"Properties": {
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
"InstanceType" : { "Ref" : "InstanceType" },
"SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],
"KeyName" : { "Ref" : "KeyName" },

"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash\n",

"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackId" }, " -r ChefServer ", " -c orderby ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Ref" : "SecretAccessKey"}, " || error_exit 'Failed to run cfn-init'\n",

"yum update -y aws-cfn-bootstrap\n",

"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n",
" exit 1\n",
"}\n",

"yum update -y\n",
"/sbin/service iptables stop\n",
"/sbin/service ip6tables stop\n",
"/sbin/chkconfig iptables off\n",
"/sbin/chkconfig ip6tables off\n",

"#Install ChefServer package\n",
"cd /root/\n",
"/usr/bin/wget http://ift.tt/1iYmVHk",
"/bin/rpm -ivh /root/chef-server-11.0.10-1.el6.x86_64.rpm\n",
"/usr/bin/wget http://ift.tt/1ijoU6m",
"/bin/cp -f default.rb /opt/chef-server/embedded/cookbooks/runit/recipes/default.rb\n",


"#Configure ChefServer\n",
"su - -c '/usr/bin/chef-server-ctl reconfigure'\n",
"su - -c '/usr/bin/chef-server-ctl restart'\n",


"#AWS creds installation\n",
"/bin/mkdir /root/.aws\n",
"/bin/touch /root/.aws/config\n",
"/bin/echo '[default]' >> /root/.aws/config\n",
"/bin/echo 'region = ", {"Ref" : "AWS::Region" }, "' >> /root/.aws/config\n",
"/bin/echo 'aws_access_key_id = ", { "Ref" : "HostKeys" }, "' >> /root/.aws/config\n",
"/bin/echo 'aws_secret_access_key = ", { "Ref" : "SecretAccessKey" }, "' >> /root/.aws/config\n",


"#Upload files for client\n",
"/usr/bin/aws s3 cp /etc/chef-server/admin.pem s3://storage/\n",
"/usr/bin/aws s3 cp /etc/chef-server/chef-validator.pem s3://storage/\n",

"#Chef client and dirs for it\n",
"/usr/bin/curl -L http://ift.tt/1hlhsH9 | /bin/bash\n",
"/bin/mkdir /root/.chef\n",
"/bin/mkdir /etc/chef\n",
"/bin/mkdir /etc/chef/cookbooks\n",
"/bin/mkdir /etc/chef/roles\n",

"#Knife client config files from S3\n",
"/bin/cp /etc/chef-server/admin.pem /etc/chef/client.pem\n",
"/usr/bin/aws s3 cp s3://storage/knife_admin.rb /root/.chef/knife.rb\n",

"#Roles and cookbooks from S3\n",
"/usr/bin/aws s3 cp s3://storage/roles/ /etc/chef/roles/ --recursive\n",
"/usr/bin/aws s3 cp s3://storage/cookbooks/ /etc/chef/cookbooks/ --recursive\n",


"#Cookbooks from community\n",
"/usr/bin/knife cookbook site download cron\n",
"/usr/bin/knife cookbook site download jenkins\n",
"/usr/bin/knife cookbook site download ntp\n",
"/usr/sbin/ntpdate -q 0.europe.pool.ntp.org\n",
"yum remove ruby -y\n",
"yum install ruby19 -y\n",

"#Unpack and move cookbooks\n",
"/bin/mv /root/*.tar.gz /etc/chef/cookbooks\n",
"for i in `/bin/ls /etc/chef/cookbooks/*.tar.gz`; do /bin/tar zxf $i -C /etc/chef/cookbooks/; /bin/rm -f $i; done\n",
"for i in `/bin/ls /etc/chef/cookbooks`; do /usr/bin/knife cookbook upload $i; done\n",

"#Upload cookbooks and roles\n",
"/usr/bin/knife cookbook upload * -c '/root/.chef/knife.rb'\n",
"/usr/bin/knife role from file /etc/chef/roles/*.rb\n",

"/bin/echo -e \"*/5 * * * * root /usr/bin/knife exec -E 'nodes.find(\\\"!roles:BaseRole\\\") { |n| puts n.run_list.add(\\\"role[BaseRole]\\\"); n.save}' -c '/root/.chef/knife.rb'\" >> /etc/crontab\n",
"/bin/echo -e \"*/5 * * * * root /usr/bin/knife exec -E 'nodes.find(\\\"env_role:master AND !roles:master\\\") { |n| puts n.run_list.add(\\\"role[master]\\\"); n.save}' -c '/root/.chef/knife.rb'\" >> /etc/crontab\n",
"/bin/echo -e \"*/5 * * * * root /usr/bin/knife exec -E 'nodes.find(\\\"env_role:slave AND !roles:slave\\\") { |n| puts n.run_list.add(\\\"role[slave]\\\"); n.save}' -c '/root/.chef/knife.rb'\" >> /etc/crontab\n",

"/opt/aws/bin/cfn-signal -e 0 -r \"ChefServer setup complete\" '", { "Ref" : "WaitHandle" }, "'\n"

]]}}
}
},

"WaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},

"WaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "ChefServer",
"Properties" : {
"Handle" : {"Ref" : "WaitHandle"},
"Timeout" : "1200"
}
},

"WebServerSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Enable HTTP access via port 80 and SSH access",
"SecurityGroupIngress" : [
{"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"},
{"IpProtocol" : "tcp", "FromPort" : "8080", "ToPort" : "8080", "CidrIp" : "0.0.0.0/0"},
{"IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0"},
{"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}}
]
}
},

}




This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Фильтры захвата для сетевых анализаторов (tcpdump, Wireshark, Paketyzer)

1. Фильтры захвата




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

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

Для решения этой проблемы в анализаторах трафика реализованы фильтры, которые разделены на два типа: фильтры захвата и фильтры отображения. Сегодня пойдет речь о первом типе фильтров – о фильтрах захвата.

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



2. Синтаксис фильтров захвата




Выражение фильтра захвата состоит из набора специальных примитивов, которые строятся из так называемых классификаторов и идентификаторов объекта (адреса, имена объектов сети, номера портов).


Внимание: все классификаторы регистрозависимы и должны писаться только маленькими буквами.





Давайте разберемся с ними подробней.

Классификаторы могут быть следующих разновидностей:


  • type – тип объекта


    • host – узел (тип по умолчанию, если тип не задан, предполагается что это host)

    • net – сеть

    • port – порт








Например:

host 192.168.0.1 – захват трафика в котором в качестве адреса (отправителя или получателя) стоит IP 192.168.0.1

net 172.16.0.0/16 – захват трафика в котором в качестве адреса (отправителя или получателя) стоит IP из сети 172.16.0.0/16 (точнее находится в диапазоне от 172.16.0.0 до 172.16.255.255), при этом, так как это всего лишь фильтр поиска совпадающих адресов, совершенно не важно какая настроена маска на интерфейсе, и вас не должно смущать что 172.16.0.0 по маске /16 это номер сети, мы совершенно не знаем какая маска настроена на интерфейсе, и формально, такой адрес узла допустим.

port 80 – захват трафика в котором есть данные принадлежащие порту 80 (udp или tcp)

10.0.0.1 – захват трафика в котором в качестве адреса (отправителя или получателя) стоит IP 10.0.0.1, классификатор host не указан, но он предполагается по умолчанию.






  • dir – направление по отношению к объекту (direction)


    • src – объект является отправителем

    • dst – объект является получателем








Например:

src host 192.168.0.1 – захват трафика в котором в качестве адреса отправителя (не получателя) стоит IP 192.168.0.1

dst net 172.16.0.0/16 – захват трафика в котором в качестве адреса получателя (не отправителя) стоит IP из сети 172.16.0.0/16 (точнее находится в диапазоне от 172.16.0.0 до 172.16.255.255).






  • proto – протокол взаимодействия


    • ether – базовая сетевая технология Ethernet, как правило указывает на то что в фильтре используется аппаратный MAC адрес

    • ip – протокол IPv4

    • ip6 – протокол IPv6

    • arp – протокол ARP

    • tcp – протокол TCP

    • udp – протокол UDP

    • если протокол не указан, то считается что должен захватываться весь трафик, совместимый с типом объекта








Например:

src ether host 00:11:22:33:44:55 – захват трафика в котором в качестве MAC адреса отправителя используется 00:11:22:33:44:55.

ip icmp – захват ICMP пакетов.

tcp port 80 – захват трафика в котором есть данные принадлежащие TCP порту 80





Кроме идентификаторов и классификаторов объекта фильтры могут содержать ключевые слова gateway, broadcast, multicast, less, greater а так же арифметические выражения.


Например:

ip multicast – захват ip пакетов, содержащих адреса из класса D.

less 1000 – захват кадров, у которых размер менее 1000 байт.





Связка нескольких условий может происходить с помощью логических операций:


  • «И» – and (&&)

  • «ИЛИ» – or (||)

  • «НЕ» – not (!) – инверсия значения




При этом приоритет этих операций следующий:


  • наивысшим приоритетом обладает операция инверсии

  • потом логическое «И»

  • наименьшим приоритетом обладает операция «ИЛИ».




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


Например:

net 192.168.0.0/24 and tcp port 21 – захват трафика принадлежащего сети (диапазону) 192.168.0.0/24 (или отправитель или получатель) и передающего данные по протоколу TCP и использующего порт 21.

host 192.168.0.1 or host 192.168.0.221 – захват трафика принадлежащего или хосту 192.168.0.1 или хосту 192.168.0.221 (при чем не важно кто отправитель, кто получатель и так же достаточно выполнения одно из двух условий, что бы хотя бы один из этих адресов присутствовал в кадре)

host 192.168.0.1 or host 192.168.0.2 and tcp port 22 – захват или любого трафика принадлежащего хосту 192.168.0.1 или трафика протокола TCP и использующего порт 22 принадлежащего хосту 192.168.0.2.

(host 192.168.0.1 or host 192.168.0.2) and tcp port 22 – захват трафика протокола TCP и использующего порт 22 принадлежащего хосту 192.168.0.1 или хосту 192.168.0.2 (любому из них, или обоим сразу).

(host 192.168.0.1 || host 192.168.0.1) && not tcp port 22 – захват любого трафика кроме трафика протокола TCP и использующего порт 22 принадлежащего хосту 192.168.0.1 или хосту 192.168.0.2 (любому из них, или обоим сразу).





Если в фильтре есть несколько одинаковых повторяющихся классификаторов, то для сокращения записи их можно не писать.


Например:

net 192.168.0.0/24 and (tcp port 21 or tcp port 20 or tcp port 25 or tcp port 80 or tcp port 110)

можно сократить до

net 192.168.0.0/24 and (tcp port 21 or 20 or 25 or 80 or 110)






Внимание:

Выражение исключающее пакеты, в которых есть адреса 1.1.1.1 и 1.1.1.2:

not (host 1.1.1.1 and host 1.1.1.2)

Можно сократить как:

not (host 1.1.1.1 and 1.1.1.2)

Но не как:

not host 1.1.1.1 and 1.1.1.2 – в этом случае будут показаны пакеты в которых нет первого адреса и есть второй.

И не так

not ( host 1.1.1.1 or 1.1.1.2) – в этом случае будут исключены пакеты в которых есть хотя бы один из указанных двух адресов.





Список основных примитивов, которые могут быть использованы для написания фильтров захвата, показан в таблице 2-1.

Таблица 2-1. Список основных примитивов, которые могут быть использованы для написания фильтров захвата.















































































































ПримитивОписание
dst host ip_addressЗахватывать кадры, в которых в поле адреса получателя заголовка IPv4/IPv6 содержит заданный адрес узла
src host ip_addressЗахватывать кадры, в которых в поле адреса отправителя заголовка IPv4/IPv6 содержит заданный адрес узла
host ip_addressЗахватывать кадры, в которых в поле адреса отправителя или получателя заголовка IPv4/IPv6 содержит заданный адрес узла.

Эквивалентен фильтру:

ether proto ip and host ip_address
ether dst mac_addressЗахватывать кадры, в которых в поле адреса получателя заголовка канального уровня содержит заданный MAC адрес узла
ether src mac_addressЗахватывать кадры, в которых в поле адреса отправителя заголовка канального уровня содержит заданный MAC адрес узла
ether host mac_addressЗахватывать кадры, в которых в поле адреса отправителя или получателя заголовка канального уровня содержит заданный MAC адрес узла
dst net networkЗахватывать кадры, в которых в поле адреса получателя заголовка IPv4/IPv6 содержит заданный адрес, принадлежащий диапазону указанной классовой сети
src net networkЗахватывать кадры, в которых в поле адреса отправителя заголовка IPv4/IPv6 содержит заданный адрес, принадлежащий диапазону указанной классовой сети
net networkВыбирает все пакеты IPv4/IPv6, содержащие адреса из указанной сети в поле отправителя или получателя
net network mask maskЗахватывать кадры, в которых в поле адреса отправителя или получателя заголовка IPv4/IPv6 содержит заданный адрес, принадлежащий диапазону указанной сети
net network/mask_lengthЗахватывать кадры, в которых в поле адреса отправителя или получателя заголовка IPv4/IPv6 содержит заданный адрес, принадлежащий диапазону указанной сети
dst port portЗахватывать кадры, в которых в поле порт получателя заголовка UDP или TCP содержит заданный номер порта
src port portЗахватывать кадры, в которых в поле порт отправителя заголовка UDP или TCP содержит заданный номер порта
port portЗахватывать кадры, в которых в поле порт отправителя заголовка UDP или TCP содержит заданный номер порта
less lengthЗахватывать кадры, размер которых не больше указанного значения
greater lengthЗахватывать кадры, размер которых не меньше указанного значения
ip proto protocolЗахватывать кадры, в которых в поле «Protocol» заголовка IPv4, содержится идентификатор указанного протокола. При этом можно указывать не только численные значения протоколов, но и их стандартные имена (icmp, igmp, igrp, pim, ah, esp, vrrp, udp, tcp и другие). Однако следует учитывать, что tcp, udp и icmp используются также в качестве ключевых слов, поэтому перед этими символьными идентификаторами следует помешать символ обратного слэша («\»)
ip6 proto protocolЗахватывать кадры, в которых в поле «Protocol» заголовка IPv4, содержится идентификатор указанного протокола. При этом можно указывать не только численные значения протоколов, но и их стандартные имена (icmp6, igmp, igrp, pim, ah, esp, vrrp, udp, tcp и другие). Однако следует учитывать, что tcp, udp и icmp6 используются также в качестве ключевых слов, поэтому перед этими символьными идентификаторами следует помешать символ обратного слэша («\»)
ether broadcastЗахватывать все широковещательные кадры Ethernet. Ключевое слово ether может быть опущено
ip broadcastЗахватывать кадры, содержащие широковещательные адреса в заголовке пакета IPv4. При этом для определения, является ли адрес широковещательным, используется маски подсети для интерфейса, который используется для захвата пакетов. Так же захватывает пакеты, отправленные на ограниченный широковещательный адрес
ether multicastЗахватывать все групповые кадры Ethernet. Ключевое слово ether может быть опущено
ip multicastЗахватывать кадры, содержащие групповые адреса в заголовке пакета IPv4
ip6 multicastЗахватывать кадры, содержащие групповые адреса в заголовке пакета IPv6
ether proto protocol_typeЗахватывать кадры Ethernet с заданным типом протокола. Протокол может быть указан по номеру или имени (ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, netbeui)
ip, ip6, arp, rarp, atalk, aarp, decnet, iso, stp, ipx, netbeui, tcp, udp, icmpЗахватывать кадры передающие данные указанного протокола. Используются в качестве сокращения для:

ether proto protocol
vlan [vlan_id]Захватывать кадры соответствующе стандарту IEEE 802.1Q. Если при этом указан номер vlan_id, то захватываются только кадры принадлежащие указанному VLAN

3. Расширенные примеры фильтров захвата




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

Для этого используются выражения возвращающее логическое значение следующего формата:


expression операция expression





В котором в качестве expression могут быть константы, результаты арифметических (+, -, *, /) или двоичных побитовых операций (& — «И», | — «ИЛИ», > — сдвиг вправо), оператор длинны offset, данные или поля заголовков кадра. В качестве операции могут быть применены символы «>» (больше), «=» (больше равно), «

Простейшим примером использования расширенного фильтра будет «5 = 3+1», где «5» и «3+1» — expression, а «=» — операция. В результате вычисления этой строки будет возвращено логическое значение, в данном случае false.

Для получения данных или заголовков кадра используется примитив proto[offset:size].



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





Параметр proto содержит название протокола, из заголовка которого необходимо выбрать определенные данные (ether, fddi, tr, wlan, ppp, slip, link, ip, arp, rarp, tcp, udp, icmp, ip6 и другие).

Параметр offset указывает на смещение в байтах относительно начала заголовка указанного протокола, нумерация байт начинается с нуля: ip[0] – первый байт от начала IP пакета, tcp[1] – второй байт от начала TCP сегмента, ether[3] – четвертый байт от начала Ethernet кадра.

Параметр size указывает на количество байт, которое необходимо взять, начиная с байта, указанного в смещении (offset), поле size является не обязательным, и если оно отсутствует, то считается что необходимо взять 1 байт: ip[2:2] – третий и четвертый байты от начала IP пакета, tcp[4] – пятый байт от начала TCP сегмента, ether[6-6] – байты с седьмого по двенадцатый, от начала Ethernet кадра.

Если в поле offset установить отрицательное значение, то будут выбраны байты предыдущего заголовка, идущие до заголовка протокола, указанного в параметре proto. Но при этом будет обязательно требоваться наличие в кадре заголовка протокола, указанного в примитиве proto. Таким образом, фильтры ether[11]=0x37 (12-й байт кадра Ethernet и его со значением 0x37) и ip[-3] = 0x37 (взять 3-й байт с конца заголовка, идущего перед заголовком IP, и сравнить его со значением 0x37) не являются идентичными. В первом будут пропускаться все кадры, в которых MAC адрес отправителя которых заканчивается на 37, а во втором так же будет требоваться наличие протокола IP, а кадры не содержащие IP протокол, например, ARP кадры, захватываться ну будут.


Например:

Выражения ip[1:1] и ip[1] приведут к оному и тому же результату – будет выбрано значение второго байта заголовка IPv4

Выражение tcp[8:2] выберет девятый и десятый байты (поле Source Port) заголовка TCP.

Выражение ip[-3] = 0x37 выберет все IPv4 пакеты, MAC адрес отправителя которых заканчивается на «0x37».





Следует учитывать, что при выборе данных с помощью конструкции proto [offset:size] для протоколов TCP и UDP, учитывается фрагментация IP пакетов. В результате tcp[0] всегда будет означать первый байт заголовка TCP, и никогда не приведет к выбору первого байта данных пакетов, передающих не первый фрагмент из цепочки фрагментов.

Для некоторых протоколов определенные поля и значения смещений могут задаваться не только числами, но и именами. Например, для протокола ICMP поддерживается параметр icmptype, который может принимать значения icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstam-preply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply. Для анализа флагов TCP можно использовать параметр tcpflags идентификаторы tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack и tcp-urg.


Например:

Выражение tcp[tcpflags]&(tcp-syn|tcp-fin) != 0 выберет все кадры, содержащие TCP сегменты в которых открывается или завершается сессия.

Выражение icmp[icmptype]!=icmp-echo and icmp[icmptype]!=icmp-echoreply выберет все кадры, содержащие ICMP протокол, кроме эхо запросов и эхо ответов.





Могут быть ситуации, в которых необходимо анализировать только часть бит, определенного байта. Для решения этих задач используется битовая операция «И» (&). С ее помощью можно сохранить только определенные биты байта, а остальные обнулить.

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



























Тип адресаЗначение старшего байта в 16-й системеЗначение старшего байта в 2-й системе
Направленные\Unicast0000000000
Групповые\Multicast0100000001
Административно назначенные\Admin ID0100000010
Широковещательные\BroadcastFF11111111



Исходя из этой информации, можно сделать вывод о том, то в широковещательных или групповых адресах младший бит старшего байта адреса равен единице, а в остальных – нулю. Если мы возьмем старшего байта адреса, обнулим все его биты кроме самого младшего, и при этом значение байта станет равным единице, то этот адрес был или широковещательным, или групповым, если значение байта станет равным нулю, то этот адрес были или направленным, или административно заданным. В результате для выполнения данной проверки необходимо использоваться следующее выражение: ether[0]&1 = 1, где ether[0] – получает значение первого байта Ethernet заголовка, а &1 — битовая операция логическое «И», обнуляющая все биты этого байта, кроме младшего, «= 1» — проверка результата на совпадение с единицей.

Разберем еще один пример более подробно.

Нам нужно получить содержимое поля Type Of Service (ToS) заголовка IPv4. Для этого обратившись к RFC-791 мы увидим, что это поле является однобайтовым полем, и вторым байтом заголовка:



3.1. Internet Header Format
A summary of the contents of the internet header follows:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+



Для того что бы получить его значение нам необходимо воспользоваться следующим примитивом:

ip[1:1] – получить один байт заголовка IP начиная с байта номер 1 (нумерация байт начинается с нуля).

Теперь мы можем строить фильтры, основываясь на содержимом этого поля.

Если мы хотим, чтобы отображались все кадры, содержащие заголовок IPv4, в котором поле ToS равно нулю необходимо написать следующее: ip[1:1] = 0.

Если мы хотим что бы отображались все кадры, содержащие заголовок IPv4, в котором поле ToS не равно нулю необходимо написать следующее: ip[1:1] != 0.

Но можно пойти дальше, согласно RFC-791 поле ToS является составным полем и имеет следующую структуру:



0 1 2 3 4 5 6 7
+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | |
| PRECEDENCE | D | T | R | 0 | 0 |
| | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+
Bits 0-2: Precedence.
Bit 3: 0 = Normal Delay, 1 = Low Delay.
Bits 4: 0 = Normal Throughput, 1 = High Throughput.
Bits 5: 0 = Normal Relibility, 1 = High Relibility.
Bit 6-7: Reserved for Future Use.



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

Если обратиться к более новым стандартам (RFC1349), значение седьмого бита уже определено – требования по цене – «Cost» (денежный эквивалент).

И вот, допустим, мы хотим определить есть ли в сети кадры, в которых в IPv4 заголовке установлен седьмой бит поля ToS. Как это сделать? Для решения этой задачи нам понадобиться вспомнить (или выучить:D) двоичную систему исчисления. В байте каждый бит имеет свой вес, который начинается с единицы, и увеличивается, справа налево каждый раз умножаясь на два.



0 1 2 3 4 5 6 7
+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | |
| PRECEDENCE | D | T | R | С | 0 |
| 0 0 0 | 0 | 0 | 0 | 1 | 0 |
| | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+
128 64 32 16 8 4 2 1



Получается, что вес интересующего нас бита равен 2.

Что если мы сравним значение поля ToS c двойкой?

ip[1:1] = 2

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

Например, если у нас в поле ToS есть кроме бита «Cost» еще и другие биты, установленные в единицу? Допустим это будет бит отвечающий за требования к пропускной способности – «Throughput».



0 1 2 3 4 5 6 7
+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | |
| PRECEDENCE | D | T | R | С | 0 |
| 0 0 0 | 0 | 1 | 0 | 1 | 0 |
| | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+
128 64 32 16 8 4 2 1



В результате значение этого байта будет уже не 2, а 10, и простым сравнением нельзя получить ответ на вопрос, установлен ли определенный бит в интересующем нас поле.

Что же нам мешает получить интересующий нас ответ? Нам мешает значение других, возможно также установленных в единицу битов. Соответственно надо от них избавиться. Для решения этой задачи воспользуемся операцией побитового логического «И» (иногда называется логическое умножение), обозначается символом «&». Как известно, в логической операции «И» на выходе будет только тогда единица, когда и первый операнд и второй равны единице. Соответственно если мы произведем побитовое умножение значения поля ToS на специальную маску, в которой будет установлен в единицу только тот бит, который находится на позиции интересующего нас бита в поле ToS, то мы исключим из результата все остальные биты:



Поле ToS :00001010=10
Маска :00000010=2
Результат:00000010=2

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




Поле ToS :11111111=255
Маска :00000010=2
Результат:00000010=2



И только лишь, если интересующий нас бит, равен нулю, в результате наложения маски будет так же ноль.



Поле ToS :11111101=253
Маска :00000010=1
Результат:00000000=0



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

Исходя из этого, для решения этой задачи нам необходимо применить следующий фильтр:

ip[1:1] & 2 = 2

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


Можно привести еще один пример на основании анализа поля Type Of Service заголовка IP: нам нужно увидеть все кадры, в которых в заголовке IPv4 в поле ToS значение битов Precedence (предпочтительность) не равна нулю. Для этого применим маску, в который единичками выделим те биты, которые отвечают за Precedence:




Поле ToS :10111101=189
Маска :11100000=224
Результат:10100000=160



Результат не равен нулю, и это говорит о том, что поле Precedence так же не равно нулю.


Поле ToS :00011111=31
Маска :11100000=224
Результат:00000000=0



Результат равен нулю, и это говорит о том, что поле Precedence так же равно нулю.

В результате, проверка на ненулевое значение поля ToS в заголовке IPv4 будет выглядеть следующим образом:

ip[1:1] & 224 != 0

или же тоже самое, но используя шестнадцатеричный вариант:

ip[1:1] & 0xe0 != 0


Рассмотрим пример с другим протоколом. Возьмем протокол TCP.

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




TCP Header Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+



Для определения есть ли в сегменте опции, используется поле «Data Offset», оно показывается длину заголовка в четырехбайтовых словах. Минимальная длина заголовка TCP сегмента – 20 байт, а это 5 четырехбайтовых слов. Соответственно, если в заголовке TCP сегмента есть опции, то значение этого поля будет больше 5.

Для того, чтобы получить значение этого поля необходимо воспользоваться примитивом tcp[12:1]. Правда, учитывая то что минимальный кусок, который мы можем взять это один байт, а нам нужно всего 4 бита, придется немного подумать.

Применив примитив tcp[12:1] мы получили следующий кусок заголовка:



+-+-+-+-+-+-+-+-
| Data |
| Offset| Reserved
| |
+-+-+-+-+-+-+-+-



Если бы поле «Data Offset» было в младшей части байта, то число «5» в двоичном представлении выглядело бы следующим образом:



128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 1 = 5



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



128 64 32 16 8 4 2 1
0 1 0 1 0 0 0 0 = 80 (0x50 в шестнадцатеричном виде)



Для выделения старших бит необходимо наложить маску:



Поле Data Offset :01010000=80
Маска :11110000=240
Результат :01010000=80



Если в заголовке все же есть опции, то значение «Data Offset» будет больше 5. Например, если в заголовке будет одна восьмибайтовая опция, то значение этого поля будет 7 (5 четырехбайтовых слов фиксированной части заголовка, и 2 четырехбайтовых слова опции):



128 64 32 16 8 4 2 1
0 0 0 0 0 1 1 1 = 7



Перенеся соответствующие биты в старшую часть получаем:



128 64 32 16 8 4 2 1
0 1 1 1 0 0 0 0 = 112 (0x70 в шестнадцатеричном виде)



Выделяем старшие биты накладывая маску:



Поле Data Offset :01110000=112
Маска :11110000=240
Результат :01110000=112



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

Результирующий фильтр, который покажет те TCP сегменты, в которых длина TCP заголовка больше 5 четырехбайтовых слов, получился следующий:

tcp[12:1] & 240 != 80

или

tcp[12:1] & 240 > 80

или

tcp[12:1] & 0xf0 > 80

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

Например, для того что бы захватить кадры содержащие сегменты с флагами SYN или FIN, необходимо написать следующий фильтр:

tcp[tcpflags] & (tcp-syn|tcp-fin) != 0

Я думаю он вполне читаем и не требует особых пояснений.

Реализация подобной задачи через биты и маски привела бы к такому формату фильтра:

tcp[13:1] & 2 != 0 or tcp[13:1] & 1 != 0

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


Например:

Выражение ether[0]&1 != 0 выберет все широковещательные кадры.

Выражение ether[0] & 1 = 0 and ip [16]>= 244 выберет все широковещательные или групповые IP пакеты, в которых на канальном уровне не используется широковещательный или групповой MAC адрес.

Выражение ip[0]&0xf = 5 выберет все IP пакеты, в которых нет опций.

Выражение ip[6:2]&0x1fff = 0 выберет все не фрагментированные IP пакеты, и первые фрагменты фрагментированных пакетов.

Выражение ip[-3]&0xff = 0x37 выберет все IP пакеты, MAC адрес отправителя которых заканчивается на «0x37».





Еще одним интересным набором битовых операций является операции битового сдвига. Эти операции обозначаются символами «пара стрелочек»: «>»- сдвиг вправо.

Как они работают?

Возьмем произвольный байт, для простоты возьмем единицу, и запишем ее значение в двоичной системе исчисления:



128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 1 = 1



Теперь произведем операцию битового сдвига влево, смещая значения всех бит на одну позицию, и поставляя ноль в младший освободившийся разряд:



128 64 32 16 8 4 2 1
0 0 0 0 0 0 1 <<





128 64 32 16 8 4 2 1
0 0 0 0 0 0 1 0 = 2



В результате значение байта стала равно двойке, то есть увеличилось в два раза. И еще раз применим эту операцию:



128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 <<





128 64 32 16 8 4 2 1
0 0 0 0 0 1 0 0 = 4



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

Давайте проверим действительность этого правила на более сложном числе, например, 100. Запишем его в двоичном виде:



128 64 32 16 8 4 2 1
0 1 1 0 0 1 0 0 = 100



А теперь произведем операцию сдвига влево:



128 64 32 16 8 4 2 1
1 1 0 0 1 0 0 <<





128 64 32 16 8 4 2 1
1 1 0 0 1 0 0 0 = 200



В результате значение байта стала равно 200 – увеличилось в два раза.

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

Например, число 240:



128 64 32 16 8 4 2 1
1 1 1 1 0 0 0 0 = 240



Произведем операцию сдвига вправо:



128 64 32 16 8 4 2 1
>> 1 1 1 1 0 0 0





128 64 32 16 8 4 2 1
0 1 1 1 1 0 0 0 = 120



Значение байта стала равно 120 – уменьшилось в два раза.

Как эту операцию мы можем использовать? Давайте вспомним, что поле IHL (Internet Header Length) заголовка IP указывает длину заголовка не в байтах, а в четырехбайтовых словах, и для того что бы проверить, содержит ли пакет опции мы применяли следующую операцию:

ip[0]&0xf = 5

То есть сравнивали не с реальным значением, а со значением, разделенным на четыре (20 байт это 5 четырехбайтовых слов). Если по каким-то причинам удобней работать с длиной заголовка в байтах (например, если это значение надо впоследствии вычесть из общей длины пакета), то его необходимо умножить на 4. Для того что бы умножить число на 4, его нужно дважды умножить на два, то есть провести операцию битового сдвига влево дважды, после чего сравнить с необходимой длинной IP заголовка в байтах:

ip[0]<<2 = 20

Ну и конечно же все это можно объединять в составные наборы правил:

(icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply) or (udp and udp port not 67 and ip[16] < 224) or (tcp[0:2]<1024 and tcp[2:2]<1024)

С этим фильтром программа будет захватывать только те кадры, которые подходят под одно из трех описаний:



  • Содержат ICMP сообщения, кроме echo и echoreply (использующиеся утилитой ping)

  • Передают UDP дейтаграммы, кроме тех, что используют в качестве порта отправителя или порта получателя порт 67 и кроме тех, которые передаются на групповые адреса и на ограниченный широковещательный адрес

  • Передают TCP сегменты, в которых и порт отправителя, и порт получателя находятся в диапазоне «Хорошо известных портов»


4. Задание для самопроверки :D




Для закрепления работы со сложными фильтрами захвата попробуйте понять, что описывает и как работает этот фильтр:

tcp port 80 and (ip[2:2] — ip[0]&0xf<<2 — tcp[12]&0xf0>>2 != 0)


Примечание:

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





Удачного снифинга)

image© IDE Academy

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Вероятность в алгоритмах. Лекция от Яндекса

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

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


Хэш-функции




Предположим, что мы хотим придумать структуру данных, которая в computer science называется ассоциативной таблицей. В этой таблице в два столбца записаны пары компонентов. Первый столбец называется «ключ», а второй – «значение». Ключом, например, может быть имя человека, а значением – его адрес. Наша задача – быстро выполнять поиск по этой таблице: находить строчку в таблице, где присутствует определенный ключ, и отдавать соответствующее ему значение. Вариант просмотреть всю таблицу сверху донизу нас не устраивает, так как мы хотим искать быстро. Если количество строк в таблице принять за n, то время поиска должно быть существенно меньше n. Мы считаем, что в нашей таблице все ключи уникальны. Если бы ключи были целыми числами, то все было бы достаточно просто. Нужно было бы создать массив, в котором элементы будут индексироваться возможными значениями ключа в диапазоне от нуля до m – 1, где m не слишком велико. Это подход хорош тем, что при таком способе хранения данных, для того чтобы по ключу k обратиться к соответствующей строке и найти соответствующее значение, нужно затратить константное время O(1). Недостаток этого способа заключается в том, что если вместо чисел в качестве ключей будут использоваться, например, строки, то придется кодировать эти строки числами. А при таком кодировании численный диапазон будет слишком велик.

И тут нам на помощь приходит хэширование. Допустим, у нас по-прежнему есть таблица размером m, но на этот раз m никак не будет связано с тем, какие у нас есть ключи. Ключи у нас – это некие целые числа. Как нам при таких условиях найти в таблице положение ключа k? Предположим, что мы знаем некоторую функцию – h(k), называемую хэш-функцией. Она для заданного k нам говорит, в какой ячейке из m возможных содержится этот ключ. Если не рассматривать, как именно работает хэш-функция, то все выглядит очень просто. Но тут есть подвох. Во-первых, у нас бесконечно много возможных значений ключей, а хэш-функция отображает на конечное множество. Поэтому, конечно же, когда два разных ключа после применения хэш-функции попадают в одну и ту же клетку: непонятно, как мы можем хранить их одновременно. Подобные ситуации называются коллизиями, и с ними нужно уметь бороться. Способов борьбы существует достаточно много. Один из простейших, но при этом довольно эффективный способ заключается в том, чтобы считать, что в ячейках содержатся не значения, и даже на пары ключ – значение, а целый список пар. Это все те пары, в которых ключи под действием хэш-функции приняли некоторое конкретное значение. Называется это разрешением коллизий методом цепочек.


Ключевой момент здесь – это выбор хэш-функции. Именно это влияет на эффективность. Если мы выберем h(k) = 0, то все хэши у нас будут равны нулю, и в итоге мы получим одну цепочку, в которой мы будем все время искать. Это очень медленно и невыгодно. Но если значения хэш-функции будут в какой-то мере случайны, то такого происходить не будет.


Случайность




Рассмотрим понятие случайности с точки зрения математики, а точнее, дискретный вариант этого понятия. Предположим, у нас есть обычный шестигранный кубик. Бросая его, мы генерируем некоторую случайность. Т.е. у нас есть множество элементарных событий – Ω. В нашем случае элементарным событием будет та грань, которая окажется сверху после полной остановки кубика. Обозначим грани (a, b, c, d, e, f). Далее нам нужно задать распределение вероятностей: создать функцию, которая для каждого элементарного события будет говорить, какова его вероятность от нуля до единицы. Т.к. кубик у нас ровный и шестигранный, то вероятность выпадения каждой стороны должна равняться 1/6.

Случайная величина в нашем случае – это любая функция, определенная на элементарных событиях. Если мы пронумеруем грани кубика числами от 1 до 6, то число, соответствующее выпавшей грани и будет случайной величиной.

Теперь рассмотрим понятие среднего случайной величины. Если элементарными событиями у нас являются сущности (a1, …, an), а вероятности им приписанные – (p1, …, pn), и наша функция отображает элементарные события на значения (x1, …, xn), то средним мы называем взвешенную сумму вида x1p1 + x2p2 + … xnpn. Т.е. нужно посмотреть, какие значения, и с какими вероятностями принимаются, после чего усреднить с коэффициентом, который равен вероятности наступления того или иного элементарного события.


Неравенство Маркова




Неформальный смысл этой леммы таков: если у случайной величины не очень большое среднее, то она не может часто принимать большие значения. Рассмотрим формальную постановку задачи и доказательство. Пусть будет задано дискретное вероятностное пространство (Ω, p) и случайная величина на нем – f * Ω → R1. Мы интересуемся вероятностью такого происшествия, что случайная величина приняла значение большее или равное ε, где ε – это некоторое положительное число.

image


Перейдем к доказательству. Доказываемое неравенство можно переписать иначе:


image


Вспомним, что E[f]=x1p1 + x22 + ⋯ + xnpn. Из этого мы можем сделать следующий вывод:


image


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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.