MASSCAN
Masscan - Це сканер портів в Інтернеті. Він може сканувати весь Інтернет менше ніж за 5 хвилин, передаючи 10 мільйонів пакетів в секунду, з однієї машини.
Його використання ( параметрів, вихід ) схоже на nmap
, найвідоміший сканер портів. Якщо ви сумніваєтесь, спробуйте одну з таких особливостей - функції, які широко підтримують підтримується сканування багатьох машин при поглибленому скануванні однієї машини ні.
Внутрішньо він використовує асинхронну передачу, подібну до портових сканерів як scanrand
, unicornscan
, і ZMap
. Це гнучкіше, що дозволяє довільні діапазони портів та адрес.
ПРИМІТКА: masscan використовує своє спеціальний стек TCP / IP. Що-небудь, крім просте сканування портів може спричинити конфлікт із локальним стеком TCP / IP. Це означає для вас потрібно використовувати будь-яке --src-ip
можливість запуску з іншої IP-адреси або використовувати --src-port
налаштувати, які порти джерела використовує masscan, а потім також налаштувати внутрішній брандмауер ( pf
або iptables
) для брандмауера цих портів з решти операційної системи.
Будівля
На Debian / Ubuntu це щось подібне. Це не так дійсно мають будь-які залежності, крім компілятора C (, наприклад gcc
або clang
).
sudo apt-get --assume-yes install git make gcc git clone https://github.com/robertdavidgraham/masscan cd masscan make
Це ставить програму в masscan/bin
підкаталог. Щоб встановити його ( на Linux ) запустіть:
make install
Джерело складається з безлічі невеликих файлів, тому будівництво йде набагато швидше за допомогою багатопотокової збірки. Для цього потрібно більше 2 гігів Малиновий Пі ( і розриває ), тому ви можете використовувати меншу кількість, як -j4
а не всі можливі нитки.
make -j
Хоча Linux є основною цільовою платформою, код працює добре на багатьох інших системи ( Windows, macOS тощо ). Ось додаткова інформація про збірку:
- Windows w / Visual Studio: використовуйте проект VS10
- Windows w / MinGW: просто введіть
make
- Windows w / cygwin: не працюватиме
- Mac OS X / w XCode: використовуйте проект XCode4
- Mac OS X / w cmdline: просто введіть
make
- FreeBSD: тип
gmake
- інше: спробуйте просто скласти всі файли разом,
cc src/*.c -o bin/masscan
На macOS, здається, бінарні файли x86 працюють так само швидко під емуляцією ARM.
Використання
Використання схоже на nmap
. Щоб сканувати мережевий сегмент для деяких портів:
# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112
- сканувати
10.x.x.x
підмережа та2603:3001:2d00:da00::x
підмережі - сканує порт 80 і діапазон від 8000 до 8100 або 102 портів загалом на обох підмережах
- вихід друку до
<stdout>
який можна перенаправити у файл
Щоб переглянути повний перелік варіантів, скористайтеся цим --echo
особливість. Це скидає поточну конфігурацію та виходить з ладу. Цей вихід може бути використаний як вхід назад в програму:
# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112 --echo > xxx.conf # masscan -c xxx.conf --rate 1000
Перевірка банера
Masscan може зробити більше, ніж просто виявити, чи відкриті порти. Це також може завершити з'єднання TCP та взаємодію з додатком при цьому порт, щоб захопити просту інформацію про "банер.
Masscan підтримує перевірку банерів на наступних протоколах:
Проблема в цьому полягає в тому, що masscan містить власний стек TCP / IP окремо від системи, в якій ви її запускаєте. Коли локальна система отримує SYN-ACK з досліджуваної цілі, він відповідає пакетом RST, який вбиває з'єднання перед масканом може захопити банер.
Найпростіший спосіб запобігти цьому - призначити масовий окремий IP адреса. Це виглядало б як один із наступних прикладів:
# masscan 10.0.0.0/8 -p80 --banners --source-ip 192.168.1.200 # masscan 2a00:1450:4007:810::/112 -p80 --banners --source-ip 2603:3001:2d00:da00:91d7:b54:b498:859d
Вибрана вами адреса повинна бути в локальній підмережі, а не в іншому випадку використовуватись іншою системою. Маскан попередить вас, що ви зробили помилка, але ви, можливо, зіпсували зв’язок іншої машини кілька хвилин, тому будьте обережні.
У деяких випадках, таких як WiFi, це неможливо. У тих випадках можна брандмауер порту, який використовує маскан. Це запобігає локальному стеку TCP / IP побачивши пакет, але Маскан все ще бачить його, оскільки він обходить місцевий стек. Для Linux це виглядатиме так:
# iptables -A INPUT -p tcp --dport 61000 -j DROP # masscan 10.0.0.0/8 -p80 --banners --source-port 61000
Ви, ймовірно, хочете вибрати порти, які не суперечать портам Linux, інакше вибрати для джерел-портів. Ви можете побачити діапазон використання Linux та перенастроїти цей діапазон, переглянувши файл:
/proc/sys/net/ipv4/ip_local_port_range
В останній версії Kali Linux ( 2018-серпень ) цей діапазон становить від 32768 до 60999, так вам слід вибрати порти нижче 32768 або 61000 і вище.
Встановлення iptables
правило триває лише до наступного перезавантаження. Потрібно шукати, як це зробити збережіть конфігурацію залежно від вашого дистрибутива, наприклад, використання iptables-save
та / або iptables-persistent
.
На Mac OS X та BSD є подібні кроки. Щоб дізнатися про діапазони, яких слід уникати, використовувати команду типу:
# sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
На FreeBSD та старих MacOS використовуйте його ipfw
команда:
# sudo ipfw add 1 deny tcp from any to any 40000 in # masscan 10.0.0.0/8 -p80 --banners --source-port 40000
На новіших MacOS та OpenBSD використовуйте pf
утиліта пакетного фільтра. Редагування файлу /etc/pf.conf
додати такий рядок:
block in proto tcp from any to any port 40000
Потім, щоб увімкнути брандмауер, запустіть команду:
# pfctrl -E
Якщо брандмауер вже працює, то перезавантажте або перезавантажте правила з наступною командою:
# pfctl -f /etc/pf.conf
Windows не відповідає пакетами RST, тому жодна з цих методик необхідні. Однак masscan все ще розроблений для того, щоб найкраще працювати, використовуючи його власна IP-адреса, тому ви повинні запускати цей шлях, коли це можливо, навіть коли він є не суворо необхідно.
Те саме потрібно для інших перевірок, таких як --heartbleed
перевірити, що є лише формою перевірки банерів.
Як сканувати весь Інтернет
Хоча корисна для менших внутрішніх мереж, програма справді розроблена з урахуванням всього Інтернету. Це може виглядати приблизно так:
# masscan 0.0.0.0/0 -p0-65535
Сканування всього Інтернету погано. З одного боку, частини Інтернету реагують погано сканується. З іншого боку, деякі сайти відстежують сканування та додають вас до списку заборон, який дозволить вам заграти з корисних частин Інтернету. Тому ви хочете виключити багато діапазонів. До чорного списку або виключати діапазони, ви хочете використовувати наступний синтаксис:
# masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt
Це просто друкує результати на командному рядку. Ви, мабуть, хочете їх збережено у файлі. Тому ви хочете щось на кшталт:
# masscan 0.0.0.0/0 -p0-65535 -oX scan.xml
Це зберігає результати у файлі XML, що дозволяє легко скинути призводить до отримання бази даних чи чогось іншого.
Але це йде лише за замовчуванням 100 пакетів / секунду, що буде вічно сканувати Інтернет. Вам потрібно пришвидшити його так:
# masscan 0.0.0.0/0 -p0-65535 --max-rate 100000
Це збільшує швидкість до 100 000 пакетів / секунду, що сканує весь Інтернет ( мінус виключає ) приблизно за 10 годин на порт ( або 655 360 годин якщо сканувати всі порти ).
Що слід помітити в цьому командному рядку, це те, що це все nmap
сумісні варіанти. Крім того, "невидимі" варіанти, сумісні з nmap
також встановлені для вас: -sS -Pn -n --randomize-hosts --send-eth
. Так само, формат файлу XML натхненний nmap
. Звичайно, є багато відмінностей, тому що асинхронний характер програми призводить до принципово іншого підходу до проблеми.
Вищевказаний командний рядок трохи громіздкий. Замість того, щоб все ставити на командному рядку він може бути збережений у файлі. Наведені вище налаштування виглядав би так:
# My Scan rate = 100000.00 output-format = xml output-status = all output-filename = scan.xml ports = 0-65535 range = 0.0.0.0-255.255.255.255 excludefile = exclude.txt
Щоб використовувати цей файл конфігурації, використовуйте його -c
:
# masscan -c myscan.conf
Це також полегшує ситуацію, коли ви повторюєте сканування.
За замовчуванням masscan спочатку завантажує файл конфігурації /etc/masscan/masscan.conf
. Будь-які пізніші параметри конфігурації перекривають те, що є у цьому файлі конфігурації за замовчуванням. Ось де я поставив своє "виключне" параметр, щоб я його ніколи не забував. Це просто працює автоматично.
Вихід
За замовчуванням masscan виробляє досить великі текстові файли, але це легко перетворити їх у будь-який інший формат. Існує п'ять підтримуваних форматів виводу:
- xml: Просто використовуйте параметр
-oX <filename>
. Або використовуйте параметри--output-format xml
і--output-filename <filename>
. - двійковий: Це формат вбудованого масового сканування. Він створює набагато менші файли так, щоб коли я сканую Інтернет, мій диск не заповнюється. Їх потрібно розібрати, хоч. Параметр командного рядка
--readscan
буде читати файли двійкового сканування. Використання--readscan
з-oX
опція створить XML-версію файл результатів. - grepable: Це реалізація Nmap -oG вихід, який можна легко проаналізувати за допомогою інструментів командного рядка. Просто використовуйте параметр
-oG <filename>
. Або використовуйте параметри--output-format grepable
і--output-filename <filename>
. - json: Це зберігає результати у форматі JSON. Просто використовуйте параметр
-oJ <filename>
. Або використовуйте параметри--output-format json
і--output-filename <filename>
. - список: Це простий список з одним хостом і парою портів за рядок. Просто використовуйте параметр
-oL <filename>
. Або використовуйте параметри--output-format list
і--output-filename <filename>
. Формат:<port state> <protocol> <port number> <IP address> <POSIX timestamp> open tcp 80 XXX.XXX.XXX.XXX 1390380064
Порівняння з Nmap
Там, де це розумно, докладено всіх зусиль, щоб програма була ознайомлена до nmap
користувачі, хоча це принципово інакше. Маскан налаштований для широкого діапазону сканування багатьох машин, тоді як nmap призначений для інтенсивне сканування однієї машини або невеликого діапазону.
- не потрібно сканувати порти за замовчуванням, потрібно вказати
-p <ports>
- цільові хости - це IP-адреси або прості діапазони, а не імена DNS, ні фанкі підмережі
nmap
може використовувати ( як10.0.0-255.0-255
).
Ви можете придумати masscan
як такі налаштування постійно ввімкнено:
-sS
: це лише сканування SYN ( в даний час зміниться в майбутньому )-Pn
: не пінг господарів спочатку, що є основоположним для операції асинхронізації-n
: не відбувається роздільної здатності DNS--randomize-hosts
: скануйте повністю рандомізовано, завжди ви не можете цього змінити--send-eth
: відправляє за допомогою сировиниlibpcap
Якщо ви хочете список додаткових nmap
сумісні налаштування, використовуйте наступне команда:
# masscan --nmap
Швидкість передачі ( ВАЖЛИВО !! )
Ця програма дуже швидко виводить пакети. У Windows або від VM, він може робити 300 000 пакетів / секунду. У Linux ( немає віртуалізації ) це буде робити 1,6 мільйона пакетів на секунду. Це досить швидко, щоб розплавити більшість мереж.
Зауважте, що він розтане лише вашу власну мережу. Це рандомізує ціль IP-адреси, щоб вони не переповнювали будь-яку віддалену мережу.
За замовчуванням ставка встановлюється на 100 пакетів / секунду. Збільшити ставку до мільйон використовують щось на кшталт --rate 1000000
.
Скануючи IPv4 Інтернет, ви будете сканувати безліч підмереж, так що, хоча велика кількість пакетів виходить, кожен цільовий підмереж отримає невелику ставку вхідних пакетів.
Однак при скануванні IPv6 ви, як правило, зосередитесь на одному цільовий підмереж з мільярдами адрес. Таким чином, ваш дефолт поведінка переповнить цільову мережу. Мережі часто збій під навантаженням, яке може генерувати маскан.
Дизайн
У цьому розділі описані основні проблеми дизайну програми.
Макет коду
Файл main.c
містить main()
функціонувати, як можна було очікувати. Це також містить transmit_thread()
і receive_thread()
функції. Ці функції були навмисно сплющені та сильно прокоментовані, щоб ви можна прочитати дизайн програми просто шляхом кроку по лінії кожен із них.
Асинхронний
Це асинхронний дизайн. Іншими словами, це nmap
що то nginx
веб-сервер повинен Apache
. Він має окрему передачу та отримання нитки, які значною мірою незалежні одна від одної. Це такий самий вид дизайн знайдено в scanrand
, unicornscan
, і ZMap
.
Оскільки він асинхронний, він працює так само швидко, як і базовий пакет дозволяє.
Рандомізація
Ключова відмінність Masscan від інших сканерів полягає в тому, як він рандомізується цілі.
Принциповим принципом є наявність єдиної змінної індексу, яка починається з нуль і збільшується на кожен зонд. У коді С це виражається як:
for (i = 0; i < range; i++) { scan(i); }
Ми повинні перевести індекс на IP-адресу. Скажімо, що ви хочете сканувати всі "приватні" IP-адреси. Це була б таблиця діапазонів на кшталт:
192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
У цьому прикладі перші індекси 64k додаються до 192.168.x.x для формування цільова адреса. Потім наступні 16 мільйонів додаються до 10.x.x.x. Решта індексів у діапазоні застосовуються до 172.16.x.x.
У цьому прикладі у нас є лише три діапазони. Під час сканування всього Інтернету, у нас на практиці більше 100 діапазонів. Це тому, що ви повинні перейти до чорного списку або виключити багато піддіапазонів. Це розбиває потрібний діапазон на сотні менших діапазонів.
Це призводить до однієї з найповільніших частин коду. Ми передаємо 10 мільйонів пакети в секунду і повинні конвертувати змінну індексу в IP-адресу для кожного зонда. Ми вирішуємо це, роблячи «двійковий пошук» у невеликому кількість пам'яті. При цій швидкості пакету ефективність кешу починає домінувати над ефективністю алгоритму. Є багато більш ефективних методик теорія, але всі вони потребують стільки пам’яті, щоб бути повільнішими на практиці.
Ми називаємо функцію, яка перекладається з індексу на IP-адресу то pick()
функція. У використанні це виглядає так:
for (i = 0; i < range; i++) { ip = pick(addresses, i); scan(ip); }
Masscan підтримує не тільки діапазони IP-адрес, але і діапазони портів. Це означає нам потрібно вибрати зі змінної індексу як IP-адресу, так і порт. Це досить просто:
range = ip_count * port_count; for (i = 0; i < range; i++) { ip = pick(addresses, i / port_count); port = pick(ports, i % port_count); scan(ip, port); }
Це призводить до іншої дорогої частини коду. Ділення / модуль інструкції - близько 90 тактових циклів або 30 наносекунд на процесорах x86. Коли передаючи зі швидкістю 10 мільйонів пакетів / секунду, у нас є лише 100 наносекунд на пакет. Я не бачу способу оптимізувати це краще. На щастя, хоча дві такі операції можна виконати одночасно, тому дві з них, як показано вище, не дорожче, ніж робити.
Насправді є кілька простих оптимізацій для вищезазначених проблем із продуктивністю, але всі вони покладаються i++
, той факт, що змінна індексу збільшує одну одним через сканування. Власне, нам потрібно рандомізувати цю змінну. Ми потрібно рандомізувати порядок IP-адрес, які ми скануємо, або ми підірвемо чорт із цільових мереж, які не побудовані для цього рівня швидкості. Ми потрібно рівномірно розподілити наш трафік по цілі.
Те, як ми рандомізуємо, - це просто зашифрування змінної індексу. За визначенням, шифрування є випадковим і створює відображення 1 на 1 між оригінальним індексом змінна і вихід. Це означає, що, поки ми лінійно проходимо через діапазон, вихідні IP-адреси абсолютно випадкові. У коді це виглядає так:
range = ip_count * port_count; for (i = 0; i < range; i++) { x = encrypt(i); ip = pick(addresses, x / port_count); port = pick(ports, x % port_count); scan(ip, port); }
Це також має великі витрати. Оскільки діапазон замість цього непередбачуваний розмір приємної рівномірної потужності 2, ми не можемо використовувати дешеві бінарні методи, як І ( & ) і XOR ( ^ ). Натомість нам доводиться використовувати дорогі операції, як МОДУЛЮС (% ). У моїх нинішніх орієнтирах потрібно 40 наносекунд зашифруйте змінну.
Ця архітектура дозволяє отримати багато цікавих функцій. Наприклад, він підтримує "шматки". Ви можете налаштувати по 5 машин, кожен з яких виконує п'яту частину сканування або range / shard_count
. Shards можуть бути декількома машинами або просто декількома мережеві адаптери на одній машині або навіть (, якщо ви хочете ) кілька IP адреси джерел на одному мережевому адаптері.
Або ви можете використовувати "насіння" або "ключ" для функції шифрування, щоб отримати інший порядок кожного разу, коли ви скануєте, як x = encrypt(seed, i)
.
Ми також можемо призупинити сканування, вийшовши з програми, і просто запам'ятовування поточного значення i
, і перезавантажте його пізніше. Я роблю це багато під час розвитку. Я бачу, що щось не так у моєму скануванні в Інтернеті, так Я натискаю, щоб зупинити сканування, а потім перезавантажую його після виправлення помилки.
Ще одна особливість - це повторні перекази / ретри. Пакети іноді потрапляють на Інтернет, тож ви можете відправити два пакети назад. Однак щось таке краплі одного пакета можуть скинути відразу після пакета. Тому ти хочу надіслати копію близько 1 секунди один від одного. Це просто. У нас уже є змінна "швидкість", яка є кількістю пакетів на секунду передача в, тому функція повторного введення просто використовувати i + rate
як індекс. Одного дня я збираюся зробити дослідження Інтернету, і диференціювати "назад до спини", "1 секунду", "10 секунд" і "1 хвилину" повторно передає таким чином, щоб побачити, чи є якась різниця в чому падає.
C10 Масштабованість
Асинхронна техніка відома як рішення "проблеми c10k". Masscan призначений для наступного рівня масштабованості, "проблеми C10M".
Рішення C10M - це обхід ядра. Є три первинні ядра обходить в Маскані:
Masscan може використовувати драйвер ДНК PF_RING. Цей драйвер DMA пакує безпосередньо від пам'яті в режимі користувача до мережевого драйвера з нульовим залученням ядра. Це дозволяє програмному забезпеченню навіть при повільному процесорі передавати пакети максимум швидкість апаратного забезпечення дозволяє. Якщо ви помістите в комп'ютер 8 мережевих карт 10 Гбіт / с, це означає, що він може передавати зі швидкістю 100 мільйонів пакетів на секунду.
Masscan має власний вбудований стек TCP для захоплення банерів від TCP з'єднання. Це означає, що він може легко підтримати 10 мільйонів одночасних TCP з'єднання, якщо, звичайно, у комп'ютера достатньо пам'яті.
У Маскана немає "мутексу". Сучасні мютекси ( ака. футекси ) - це переважно режим користувача, але у них дві проблеми. Перша проблема полягає в тому, що вони викликають кеш-лінії швидко відскакувати між процесорами. Друге - це коли там це суперечка, вони зроблять системний дзвінок у ядро, яке вбиває продуктивність. Мутекс на швидкому шляху програми сильно обмежує масштабованість. Натомість Маскан використовує "кільця" для синхронізації речей, наприклад, коли стек TCP в режимі користувача в приймальній нитці повинен передавати пакет без заважаючи потоку передачі.
Переносність
Код добре працює в Linux, Windows та Mac OS X. Усі важливі біти є у стандарті C ( C90 ). Тому він компілює на Visual Studio з Microsoft компілятор, компілятор Clang / LLVM на Mac OS X та GCC на Linux.
Windows і Mac не налаштовані на передачу пакетів і отримують лише близько 300 000 пакети за секунду, тоді як Linux може робити 1500 000 пакетів / секунду. Це напевно, швидше, ніж ти хочеш.
Безпечний код
Для вразливих ситуацій пропонується щедрість, див. Файл VULNINFO.md для отримання додаткової інформації інформація.
Цей проект використовує безпечні функції, як strcpy_s()
замість небезпечних функцій як strcpy()
.
Цей проект має автоматизовані випробування на регресію блоку (make regress
).
Сумісність
Багато зусиль доклали до того, щоб зробити вхід / вихід схожим nmap
, який кожен, хто робить сканування портів, ( або повинен бути ) знайомий.
Співіснування IPv6 та IPv4
Masscan підтримує IPv6, але спеціального режиму немає, обидва підтримуються водночас. ( Немає -6
варіант - він завжди доступний ).
У будь-якому прикладі ви бачите використання масових, просто введіть IPv6-адресу, де ви бачите IPv4-адресу. Ви можете включити IPv4 та IPv6 адреси одночасно в одному скануванні. Вихід включає відповідна адреса в тому ж місці, без спеціального маркування.
Пам'ятайте лише, що адресний простір IPv6 дійсно великий. Ви, мабуть, не хочете сканувати для великих діапазонів, за винятком, можливо, перших 64 к адрес підмережі, які були призначені через DHCPv6.
Натомість ви, ймовірно, захочете сканувати великі списки збережених адрес у файлі (--include-file filename.txt
), що ви отримали з інших джерел. Як і скрізь, цей файл може містити списки як IPv4, так і IPv6 адрес. Тестовий файл, який я використовую, містить 8 мільйонів адрес. Файли такого розміру потребують пари додаткові секунди, які потрібно прочитати при запуску ( masscan сортує адреси та видаляє дублює перед скануванням ).
Пам'ятайте, що masscan містить власний мережевий стек. Таким чином, локальна машина Ви запускаєте masscan з не потрібно включати IPv6 - хоча локальний мережа повинна мати можливість маршрутизувати пакети IPv6.
PF_RING
Щоб отримати понад 2 мільйони пакетів / секунду, вам потрібен Intel 10-фунт / с Ethernet адаптер та спеціальний драйвер, відомий як "PF_RING ZC" з ntop. Masscan не потрібно перебудовувати для використання PF_RING. Для використання PF_RING, потрібно створити такі компоненти:
libpfring.so
( встановлено в /usr/lib/libpfring.so )pf_ring.ko
( їх драйвер ядра )ixgbe.ko
( їх версія драйвера Intel 10-gbps Ethernet )
Вам не потрібно створювати їх версію libpcap.so
.
Коли Маскан виявить, що адаптер названий чимось подібним zc:enp1s0
замість цього чогось подібного enp1s0
, він автоматично перейде в режим PF_RING ZC.
Більш детальну дискусію можна знайти в PoC | | GTFO 0x15.
Регресійне тестування
Проект містить вбудований тест на одиницю:
$ make test bin/masscan --selftest selftest: success!
Це тестує багато складних бітів коду. Ви повинні зробити це після будівництва.
Тестування працездатності
Щоб перевірити продуктивність, запустіть щось на зразок наступного на адресу, що викидається, щоб не перевантажувати локальний маршрутизатор:
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --router-mac 66-55-44-33-22-11
Блудний --router-mac
зберігає пакети на локальних сегментах мережі так, щоб вони не вийдуть в Інтернет.
Ви також можете протестувати в режимі "офлайн", який швидко працює програма без передачі накладних витрат:
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --offline
Цей другий орієнтир приблизно показує, наскільки швидко програма запуститься, якби вона була використання PF_RING, який має майже нульові накладні витрати.
До речі, алгоритм рандомізації використовує "цілеспрямовану арифметику", хронічно повільна робота на процесорах. Сучасні процесори подвоїли швидкість при якому вони виконують цей розрахунок, роблячи masscan
набагато швидше.