Серйозна безпека: як НАВМИСНИЙ ТИП може покращити безпеку DNS

Серйозна безпека: як НАВМИСНИЙ ТИП може покращити безпеку DNS

За ці роки ми письмовий та говорять на Naked Security багато разів про гостру проблему DNS викрадення.

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

Якщо ви не знайомі зі словом Журналіст, це відноситься до індексу в кінці атласу, де ви шукаєте, скажімо, Монровія, Ліберія у зручному алфавітному списку, і він говорить щось на кшталт 184 - C4. Це означає, що вам потрібно перейти прямо на сторінку 184 і слідувати лініями сітки вниз від літери C у верхній частині карти та навпроти цифри 4 ліворуч. Там, де зустрічаються лінії, ви знайдете Монровію.

Для більшості користувачів більшість пошукових запитів DNS містять ім’я сервера з запитом на повернення відповіді, що містить так званий A-запис або AAAA-запис.

(A-записи використовуються для 32-розрядних інтернет-номерів IPv4, наприклад 203.0.113.42; AAAA-записи є еквівалентними відповідями для 128-бітних адрес IPv6, таких як 2001:db8:15a:d0c::42 – у цій статті ми будемо використовувати лише A-записи та номери IPv4, але в обох випадках до процесу пошуку стосуються однакові проблеми безпеки.)

Ось приклад, коли ми шукаємо уявне доменне ім’я naksec.test за допомогою DNS-сервера, спеціально створеного для відстеження та навчання DNS-трафіку.

Ми використовували інструмент старої школи Linux dig, скорочено домен інтернет-гропер, щоб створити простий запит DNS (dig за замовчуванням шукає A-записи) для потрібного нам сервера:

$ dig +noedns @127.42.42.254 naksec.test ;; РОЗДІЛ ПИТАННЯ: ;naksec.test. В ;; РОЗДІЛ ВІДПОВІДІ: NAKSEC.ТЕСТ. 5 В А 203.0.113.42 ;; Час запиту: 1 мс ;; СЕРВЕР: 127.42.42.254#53(127.42.42.254) (UDP) ;; КОЛИ: Пн, 23 січня 14:38:42 GMT 2023 р. ;; MSG РОЗМІР rcvd: 56

Ось як наш DNS-сервер впорався із запитом, показуючи шістнадцятковий дамп вхідного запиту та успішну відповідь, яка повернулася:

---> Запит від 127.0.0.1:57708 до 127.42.42.254:53 ---> 00000000 62 4e 01 20 00 01 00 00 00 00 00 00 06 6e 61 6b |bN. .........нак| 00000010 73 65 63 04 74 65 73 74 00 00 01 00 01 |сек.тест..... | DNS-пошук: A-запис для naksec.test ==> A=203.0.113.42 <--- Відповідь від 127.42.42.254:53 до 127.0.0.1:57708 <--- 00000000 62 4e 84 b0 00 01 00 01 00 00 00 00 06 6e 61 6b |bN...........нак| 00000010 73 65 63 04 74 65 73 74 00 00 01 00 01 06 4e 41 |сек.тест......NA| 00000020 4b 53 45 43 04 54 45 53 54 00 00 01 00 01 00 00 |KSEC.ТЕСТ.......| 00000030 00 05 00 04 cb 00 71 2a |......q* |

Зауважте, що з міркувань продуктивності більшість запитів DNS використовують UDP, протокол дейтаграм користувача, який працює на основі надсилання та надії: ви запускаєте UDP-пакет на сервер, з яким хочете спілкуватися, а потім чекаєте, чи прийде відповідь.

Це робить UDP набагато простішим і швидшим, ніж його великий двоюрідний брат TCP протокол керування передачею, який, як випливає з назви, автоматично піклується про багато деталей, яких UDP не робить.

Зокрема, TCP має справу з виявленням втрати даних і повторним запитом про них; забезпечення надходження будь-яких порцій даних у правильному порядку; і забезпечення єдиного мережевого підключення, яке після встановлення можна використовувати для надсилання та отримання одночасно.

UDP не має концепції «з’єднання», тому запити та відповіді по суті подорожують незалежно:

  • DNS-запит надходить на DNS-сервер у власному UDP-пакеті.
  • DNS-сервер зберігає записи який комп’ютер надіслав цей конкретний пакет.
  • Сервер шукає відповідь, щоб надіслати назад, або вирішити, що його немає.
  • Сервер надсилає відповідь початковому відправнику за допомогою другого UDP-пакета.

На рівні операційної системи чи мережі ці два UDP-пакети вище є незалежними автономними передачами – вони не пов’язані разом як частина одного цифрового з’єднання.

Сервер повинен пам'ятати, якому клієнту надсилати кожну відповідь; і клієнт повинен визначити, які відповіді стосуються запитів, які він спочатку надіслав.

Як ти можеш бути впевнений?

У цей момент, особливо дивлячись на мініатюрний розмір DNS-запиту та відповіді вище, ви, ймовірно, дивуєтеся: «Як клієнт може бути впевнений, що він відповідає правильній відповіді, а не тій, яка була спотворена під час передачі або неправильно спрямована помилково, випадково чи задумано?»

На жаль, багато, якщо не більшість запитів DNS (особливо ті, що надсилаються від сервера до сервера, коли перший сервер, який ви запитуєте, не знає відповіді, і йому потрібно знайти той, який знає, щоб сформулювати свою відповідь) не зашифровані або інакше позначені будь-яким кодом криптографічної автентифікації.

Насправді за замовчуванням запити DNS містять один «тег ідентифікації», який у документації щодо формату даних DNS називається просто як ID.

Дивовижно, але незважаючи на численні оновлення та пропозиції щодо вдосконалення протягом багатьох років, офіційний Інтернет-RFC (запит на коментарі) документ, який діє як специфікація DNS, залишається RFC 1035 (наразі ми працюємо з RFC у середині 9000-х років), починаючи з листопада 1987 року, трохи більше 35 років тому!

Тоді як пропускна здатність, так і потужність обробки були дефіцитними: типова швидкість ЦП становила близько 10 МГц; настільні комп'ютери мали приблизно 1 Мбайт оперативної пам'яті; швидкість доступу до Інтернету для організацій, які взагалі могли підключитися до Інтернету, часто становила 56 Кбіт/с або 64 Кбіт/с, розділених між усіма; і 1200 біт/с був доступним вибором для особистого підключення через комутовані модеми того часу.

Ось чому заголовки запитів і відповідей DNS були – і досі – розбиті на жалюгідні 12 байтів, з яких ідентифікаційний тег займає перші два, як мило в RFC 1035 ASCII art пояснює:

 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+ --+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QR| Код операції |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | РАХУНОК | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Ви можете побачити ідентифікатор у дії в шістнадцяткових дампах, показаних вище, де і запит, і пакети відповіді починаються з тих самих двох символів bN, які відповідають 16-бітному ідентифікатору 62 4e у шістнадцятковому.

Якщо говорити дуже вільно, ці 16 біт – це стільки, скільки надає офіційний протокол DNS за допомогою «автентифікації» або «виявлення помилок».

Втручання через здогади

Як ви можете собі уявити, враховуючи наскрізну простоту звичайного трафіку DNS, будь-хто з т.з. середня коробка or проксі-сервер сканування хто може перехоплювати, перевіряти та змінювати ваш мережевий трафік, може тривіально втручатися у ваш трафік DNS.

Це включає надсилання відповідей, які навмисно надають вам неточну інформацію, наприклад, ваша ІТ-команда перенаправляє вас із серверів, які, як їй відомо, засмічені зловмисним програмним забезпеченням.

Це також може включати дотримання провайдером Інтернет-послуг законодавства вашої країни, яке вимагає повідомляти про деякі сервери як про неіснуючі, навіть якщо вони живі та працюють нормально, оскільки вони внесені до списку блокування незаконного вмісту, наприклад матеріалів про жорстоке поводження з дітьми.

Але, на перший погляд, цей надслабкий вид тегування ідентифікатора DNS також здається тривіальним навіть для зловмисників, які взагалі не бачать ваш мережевий трафік запускати фальшиві DNS-відповіді вашим користувачам або серверам…

…з небезпечно високими шансами на успіх.

Зрештою, якщо зловмисники знають, що хтось у вашій мережі регулярно любить відвідувати naksec.test, цей сервер може здатися чудовим місцем для імплантації фейкових новин, хитрих оновлень або фальшивого коду JavaScript.

І якщо зловмисники не зможуть зламати naksec.test що, якби вони регулярно і часто запускали UDP-пакети на ваш DNS-сервер, використовуючи вигаданий ідентифікаційний тег, який нібито відповідає на запитання: «Що таке A-запис для naksec.test"?

Таким чином вони можуть перехопити DNS-запит, надати фальшиву відповідь і, таким чином, неправильно спрямувати ваш наступний візит на веб-сайт – по суті, захопити сам сайт без необхідності атакувати naksec.test сервер взагалі.

Потрібна певна удача

Звичайно, їм потрібно трохи пощастити, хоча вони можуть намагатися знову і знову, щоб підвищити свої загальні шанси, враховуючи, що їм потрібно досягти успіху лише один раз, тоді як вам потрібно щоразу отримувати правдиву відповідь DNS.

Щоб досягти успіху, їм потрібно буде надіслати свою фальшиву відповідь DNS:

  • Протягом періоду, коли ваш власний сервер ще не знав відповіді на запитання. Відповіді DNS містять 32-розрядне число, яке називається TTL, скорочення від час життя, яка вказує, як довго інша сторона може повторно використовувати відповідь. Якщо ви чи хтось інший у мережі ytour попросили naksec.test нещодавно ваш DNS-сервер міг мати відповідь у своєму кеші. Подальший пошук не буде потрібний, і зловмисники не матимуть вихідного запиту для викрадення.
  • Між часом, коли ви надіслали запит, і офіційною відповіддю ззовні не надійшла. Навіть у давні часи час пошуку DNS рідко перевищував кілька секунд. Сьогодні їх найкраще вимірювати в мілісекундах.
  • З правильним числом у перших 16 бітах. Ви можете встановити 65536 (216) розрізняють значення на 16 бітів, тому зловмисникам мало б трохи пощастити. Але за сучасної пропускної здатності мережі надсилання 65536 XNUMX різних фальшивих відповідей одночасно, таким чином охоплюючи всі можливі ідентифікаційні номери, займає крихітну частку секунди.

На щастя, гідні DNS-сервери сьогодні роблять додатковий крок, щоб ускладнити викрадення за замовчуванням.

Принаймні, це те, що вони робили приблизно з 2008 року, коли покійний Дан Камінський зазначив, що багато DNS-серверів того часу були налаштовані не лише для прослуховування вхідних запитів на фіксованому порту UDP (майже завжди порт 53, офіційно призначений DNS)…

...але також для отримання вхідних відповідей на фіксований порт, часто також порт 53, хоча б для створення приємної симетрії в трафіку.

Причиною використання фіксованого порту в обох напрямках, ймовірно, спочатку була простота програмування. Завжди прослуховуючи відповіді на тому самому номері UDP-порту, вам не потрібно відстежувати, які порти мають бути відкриті для відповідей. Це означає, що обробник запитів і компоненти генератора відповідей вашого програмного забезпечення DNS можуть працювати незалежно. Слухачу запиту не потрібно повідомляти відправнику відповіді: «Ця конкретна відповідь має повернутися на спеціальний порт, а не на звичайний».

Використовуйте номери портів як додаткові ідентифікатори

Сьогодні майже всі DNS-сервери на основі UDP прослуховують порт 53, як завжди, але вони відстежують так званий «порт джерела», який використовує запитувач DNS, який, як очікується, буде обраний випадковим чином.

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

Порти Інтернет-протоколу (TCP також використовує їх) можуть бути від 1 до 65535, хоча більшість вихідних з’єднань використовують лише вихідні порти 1024-65535, оскільки номери портів 1023 і нижче зазвичай зарезервовані для процесів із системними привілеями.

Ідея полягає в тому, що відправник будь-якого DNS-пошуку повинен не лише вставляти справді випадковий 16-бітний ідентифікатор на початку кожного запиту, але й вибрати справді випадковий номер вихідного порту UDP, на якому він буде прослуховувати відповідну відповідь.

Це додає додатковий рівень здогадок, які шахраї повинні додати до свого списку «викрадення удачі» вище, а саме те, що вони повинні надіслати фальшиву відповідь, яка відповідає всім цим прапорцям:

  • Це має бути нещодавно заданий запит, зазвичай протягом останніх кількох секунд.
  • Це має бути пошук, якого не було в кеші локального сервера, зазвичай це означає, що ніхто більше не запитував про це протягом останніх кількох хвилин.
  • Повинен мати правильний 16-бітний ідентифікаційний номер на початку пакета даних.
  • Має бути відправлено в правильний порт призначення на відповідний IP-номер сервера.

І інше

Насправді, є ще один трюк, який можуть зробити запитувачі DNS, не змінюючи базовий протокол DNS і, таким чином (здебільшого), нічого не порушуючи.

Цей трюк, на диво, був вперше запропоновано ще в 2008 році в статті під чудовою назвою Підвищена стійкість до підробки DNS через 0x20-бітове кодування: БЕЗПЕКА ЧЕРЕЗ ЗАПИТИ LEET.

Ідея на диво проста і ґрунтується на двох деталях у протоколі DNS:

  • Усі відповіді DNS мають містити вихідний розділ запиту на початку. Запити, очевидно, мають порожній розділ відповідей, але відповіді повинні відображати оригінальне запитання, що допомагає гарантувати, що запити та відповіді випадково не переплутаються.
  • Усі запитання DNS нечутливі до регістру. Якщо ви просите naksec.testабо NAKSEC.TESTабо nAksEc.tESt, ви повинні отримати ту саму відповідь.

Тепер у протоколі немає нічого, що говорить про те, що ви ПОВИННІ використовувати той самий орфограф у частині відповіді, де ви повторюєте вихідний запит, оскільки DNS не зважає на регістр.

Але хоча RFC 1035 вимагає, щоб ви проводили порівняння без урахування регістру, він наполегливо пропонує вам насправді не змінюйте регістр будь-яких текстових назв, які ви отримуєте в запитах або отримуєте з власних баз даних для використання у відповідях.

Іншими словами, якщо ви отримаєте запит на nAKsEC.tEST, а у вашій базі даних він зберігається як NAKSEC.TEST, тоді ці дві назви все одно вважаються ідентичними та збігаються.

Але коли ви формулюєте свою відповідь, RFC 1035 пропонує вам не змінюйте регістр символів у даних, які ви вводите у відповідь, навіть якщо ви можете подумати, що це виглядатиме акуратніше, і навіть якщо воно все одно збігатиметься на іншому кінці завдяки нечутливому до регістру порівнянню, яке вимагає DNS.

Отже, якщо ви навмання переплутаєте регістр літер у DNS-запиті перед тим, як його надіслати, більшість DNS-серверів точно відображатимуть цю дивну комбінацію літер, навіть якщо їхня власна база даних зберігає ім’я сервера інакше, як ви бачите тут :

$ dig +noedns @127.42.42.254 nAkSEc.tEsT ;; РОЗДІЛ ПИТАННЯ: ;nAkSEc.tEsT. В ;; РОЗДІЛ ВІДПОВІДІ: NAKSEC.ТЕСТ. 5 В А 203.0.113.42 ;; Час запиту: 1 мс ;; СЕРВЕР: 127.42.42.254#53(127.42.42.254) (UDP) ;; КОЛИ: Пн, 23 січня 14:40:34 GMT 2023 р. ;; MSG РОЗМІР rcvd: 56

Наш DNS-сервер зберігає назву naksec.test все у верхньому регістрі, тому розділ відповіді містить ім’я у формі NAKSEC.TEST, а також номер IPv4 (запис A). 203.0.113.42.

Але в частині відповіді «ось дані запиту, повернуті вам для перехресної перевірки», яку надсилає наш DNS-сервер, збережено комбінацію регістру символів, яка спочатку використовувалася для пошуку DNS:

---> Запит від 127.0.0.1:55772 до 127.42.42.254:53 ---> 00000000 c0 55 01 20 00 01 00 00 00 00 00 00 06 6e 41 6b |.U. .........nAk| 00000010 53 45 63 04 74 45 73 54 00 00 01 00 01 |SEc.tEsT..... | DNS-пошук: A-запис для nAkSEc.tEsT ==> A=203.0.113.42 <--- Відповідь від 127.42.42.254:53 до 127.0.0.1:55772 <--- 00000000 c0 55 84 b0 00 01 00 01 00 00 00 00 06 6e 41 6b |.U...........nAk| 00000010 53 45 63 04 74 45 73 54 00 00 01 00 01 06 4e 41 |SEc.tEsT......NA| 00000020 4b 53 45 43 04 54 45 53 54 00 00 01 00 01 00 00 |KSEC.ТЕСТ.......| 00000030 00 05 00 04 cb 00 71 2a |......q* |
Серйозна безпека: як навмисні типи можуть покращити безпеку DNS PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
Вище. DNS-запит у Wireshark.
Розділ запитань із показаним змішаним випадком.
Серйозна безпека: як навмисні типи можуть покращити безпеку DNS PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
Вище. Відповідь DNS у Wireshark.
Зверніть увагу на те, що дані запиту точно копіюються із запиту, незважаючи на те, що база даних сервера надає ім’я ALL-UPPER.

Додаткове маркування безпеки, безкоштовно

Бінго!

Існує ще кілька «тегів ідентифікації», які може додати DNS-пошук!

Разом із 15-ти бітами довільно вибраного вихідного порту та 16 бітами довільно вибраних ідентифікаційних номерів запитувач може вибрати верхній регістр для кожного символу алфавіту в імені домену.

і naksec.test містить 10 літер, кожну з яких можна написати у верхньому або нижньому регістрі, для подальших 10 біт випадкового «тегування».

З цією додатковою деталлю, щоб вгадати, зловмисникам потрібно буде пощастити з їхнім часом, номером UDP-порту, значенням ідентифікаційного тегу та великими літерами доменного імені, щоб вставити фальшиву «відповідь на викрадення», яку запитує сервер прийняв би.

До речі, назва 0x20-кодування вище трохи жарту: 0x20 у заголовному є 00100000 у двійковій системі, і єдиний біт у цьому байті – це те, що розрізняє великі та малі літери в системі кодування ASCII.

Букви A до I, наприклад, вийти як 0x41 до 0x49, а a до i вийти як 0x61 до 0x69.

 Таблиця кодування ASCII як текст ASCII +------+------+------+------+------+------+- -----+------+ |00 ^@ |10 ^P |20 |30 0 |40 @ |50 P |60 ` |70 p | |01 ^A |11 ^Q |21 ! |31 1 |41 A |51 Q |61 a |71 q | |02 ^B |12 ^R |22 " |32 2 |42 B |52 R |62 b |72 r | |03 ^C |13 ^S |23 # |33 3 |43 C |53 S |63 c |73 с | |04 ^D |14 ^T |24 $ |34 4 |44 D |54 T |64 d |74 t | |05 ^E |15 ^U |25 % |35 5 |45 E |55 U |65 e |75 u | |06 ^F |16 ^V |26 & |36 6 |46 F |56 V |66 f |76 v | |07 ^G |17 ^W |27 ' |37 7 | 47 G |57 W |67 g |77 w | |08 ^H |18 ^X |28 ( |38 8 |48 H |58 X |68 h |78 x | |09 ^I |19 ^Y |29 ) |39 9 |49 I |59 Y |69 i |79 y | |0A ^J |1A ^Z |2A * |3A : |4A J |5A Z |6A j |7A z | |0B ^K |1B ^ [ |2B + |3B ; |4B K |5B [ |6B k |7B { | |0C ^L |1C ^ |2C , |3C < |4C L |5C |6C l |7C | | |0D ^M | 1D ^] |2D - |3D = |4D M |5D ] |6D m |7D } | |0E ^N |1E ^^ |2E . |3E > |4E N |5E ^ |6E n |7E ~ | | 0F ^O |1F ^_ |2F / |3F ? |4F O |5F _ |6F o |7F | +------+------+------+--- ---+------+------+------+------+

Іншими словами, якщо ви додаєте 0x41+0x20, щоб отримати 0x61, ви обертаєтеся A в a; якщо ви віднімете 0x69-0x20, щоб отримати 0x49, ви обертаєтеся i в I.

Чому зараз?

Можливо, зараз ви задавалися питанням, «Чому зараз, якщо ця ідея з’явилася 15 років тому, і чи принесе вона користь?»

Наш раптовий інтерес, як це сталося, походить від a останні публічні електронні листи від технарів Google, які визнали, що їхні експерименти 2022 року з цим старовинним трюком БЕЗПЕКИ були застосовані в реальному житті:

Як ми повідомляли раніше, Google Public DNS перебуває в процесі ввімкнення випадкового визначення регістру імен запитів DNS, надісланих на авторитетні сервери імен. Ми успішно розгорнули його в деяких регіонах Північної Америки, Європи та Азії, захищаючи більшість (90%) запитів DNS у тих регіонах, які не охоплені DNS через TLS.

Інтригуюче те, що Google припускає, що головні проблеми, які він мав із цим простим і, очевидно, безперечним налаштуванням, полягають у тому, що хоча більшість DNS-серверів або постійно не чутливі до регістру (тому з ними можна використовувати цей трюк), або постійно ні (тому вони внесені до списку блокувань), як ви могли очікувати...

…кілька основних серверів час від часу переходять у режим «з урахуванням регістру» на короткий проміжок часу, що звучить як різновид невідповідності, якої, як очікується, уникнуть основні постачальники послуг.

Це насправді допомагає?

Відповідь на запитання, "Чи варто це?" ще не зрозуміло.

Якщо у вас гарна довга службова назва, наприклад nakedsecurity.sophos.com (22 алфавітні символи), тоді є багато додаткової сигнальної потужності, оскільки 222 різні капіталізації означають 4 мільйони комбінацій, які шахраї можуть спробувати, помножені на 65536 32000 різних ідентифікаційних номерів, помножені на приблизно 64000 XNUMX–XNUMX XNUMX різних вихідних портів, які потрібно вгадати...

…але якщо ви заплатили невелику суму за надкоротке доменне ім’я, наприклад у Twitter t.co, ваші зловмисники мають завдання лише у 2x2x2=8 разів складніше, ніж раніше.

Тим не менш, я думаю, що ми можемо сказати «Chapeau» Google за спробу цього.

Як люблять казати спостерігачі з питань кібербезпеки, атаки стають тільки швидшими, тому все, що може взяти існуючий протокол і додати до нього додатковий час злому, майже «безкоштовно», є корисним способом боротьби.


Часова мітка:

Більше від Гола безпека