Cookies Hacking

Reading time: 14 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

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

Expires and Max-Age

Дата закінчення терміну дії cookie визначається атрибутом Expires. У свою чергу, атрибут Max-age визначає час у секундах, протягом якого cookie буде видалено. Вибирайте Max-age, оскільки це відображає більш сучасні практики.

Domain

Хости, які отримують cookie, вказуються атрибутом Domain. За замовчуванням це встановлено на хост, який видав cookie, не включаючи його піддомени. Однак, коли атрибут Domain явно встановлений, він охоплює також піддомени. Це робить специфікацію атрибута Domain менш обмежувальним варіантом, корисним для сценаріїв, де необхідно ділитися cookie між піддоменами. Наприклад, встановлення Domain=mozilla.org робить cookie доступними на його піддоменах, таких як developer.mozilla.org.

Path

Конкретний URL шлях, який повинен бути присутнім у запитуваному URL, щоб заголовок Cookie був надісланий, вказується атрибутом Path. Цей атрибут розглядає символ / як роздільник директорій, що дозволяє відповідності в підкаталогах.

Ordering Rules

Коли два cookie мають однакову назву, вибір того, який буде надіслано, базується на:

  • Cookie, що відповідає найдовшому шляху в запитуваному URL.
  • Найновішому встановленому cookie, якщо шляхи ідентичні.

SameSite

  • Атрибут SameSite визначає, чи надсилаються cookie на запити, що походять з доменів третіх сторін. Він пропонує три налаштування:
  • Strict: Обмежує надсилання cookie на запити з третіх сторін.
  • Lax: Дозволяє надсилати cookie з GET запитами, ініційованими веб-сайтами третіх сторін.
  • None: Дозволяє надсилати cookie з будь-якого домену третьої сторони.

Пам'ятайте, що під час налаштування cookie розуміння цих атрибутів може допомогти забезпечити їх очікувану поведінку в різних сценаріях.

Request TypeExample CodeCookies Sent When
Link<a href="..."></a>NotSet*, Lax, None
Prerender<link rel="prerender" href=".."/>NotSet*, Lax, None
Form GET<form method="GET" action="...">NotSet*, Lax, None
Form POST<form method="POST" action="...">NotSet*, None
iframe<iframe src="..."></iframe>NotSet*, None
AJAX$.get("...")NotSet*, None
Image<img src="...">NetSet*, None

Table from Invicti and slightly modified.
Cookie з атрибутом SameSite зменшить атаки CSRF, де потрібна активна сесія.

*Зверніть увагу, що з Chrome80 (лютий 2019) стандартна поведінка cookie без атрибута cookie samesite буде lax (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Зверніть увагу, що тимчасово, після застосування цієї зміни, cookie без політики SameSite в Chrome будуть оброблятися як None протягом перших 2 хвилин, а потім як Lax для запиту POST на верхньому рівні між сайтами.

Cookies Flags

HttpOnly

Це запобігає клієнту доступати до cookie (через Javascript, наприклад: document.cookie)

Bypasses

  • Якщо сторінка надсилає cookie у відповідь на запити (наприклад, на сторінці PHPinfo), можливо зловживати XSS, щоб надіслати запит на цю сторінку та вкрасти cookie з відповіді (перевірте приклад на https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/).
  • Це можна обійти за допомогою TRACE HTTP запитів, оскільки відповідь сервера (якщо цей HTTP метод доступний) відобразить надіслані cookie. Цю техніку називають Cross-Site Tracking.
  • Цю техніку уникають сучасні браузери, не дозволяючи надсилати запит TRACE з JS. Однак деякі обходи були знайдені в специфічному програмному забезпеченні, наприклад, надсилаючи \r\nTRACE замість TRACE до IE6.0 SP2.
  • Інший спосіб - це експлуатація вразливостей нульового дня браузерів.
  • Можливо перезаписати HttpOnly cookie, виконуючи атаку переповнення Cookie Jar:

Cookie Jar Overflow

  • Можливо використовувати атаку Cookie Smuggling для ексфільтрації цих cookie

Secure

Запит тільки надішле cookie в HTTP запиті, якщо запит передається через безпечний канал (зазвичай HTTPS).

Cookies Prefixes

Cookie, що починаються з __Secure-, повинні бути встановлені разом з прапором secure з сторінок, які захищені HTTPS.

Для cookie, що починаються з __Host-, повинні бути виконані кілька умов:

  • Вони повинні бути встановлені з прапором secure.
  • Вони повинні походити з сторінки, захищеної HTTPS.
  • Їм заборонено вказувати домен, що запобігає їх передачі на піддомени.
  • Шлях для цих cookie повинен бути встановлений на /.

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

Overwriting cookies

Отже, одне з захистів cookie з префіксом __Host- - це запобігання їх перезапису з піддоменів. Запобігання, наприклад, Cookie Tossing attacks. У доповіді Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper) представлено, що було можливо встановити cookie з префіксом __HOST- з піддомену, обманюючи парсер, наприклад, додаючи "=" на початку або на початку і в кінці...:

Або в PHP було можливо додати інші символи на початку назви cookie, які будуть замінені на символи підкреслення, що дозволяє перезаписати cookie __HOST-:

Cookies Attacks

Якщо кастомний cookie містить чутливі дані, перевірте його (особливо якщо ви берете участь у CTF), оскільки він може бути вразливим.

Decoding and Manipulating Cookies

Чутливі дані, вбудовані в cookie, завжди повинні бути перевірені. Cookie, закодовані в Base64 або подібних форматах, часто можуть бути декодовані. Ця вразливість дозволяє зловмисникам змінювати вміст cookie та видавати себе за інших користувачів, закодовуючи їх модифіковані дані назад у cookie.

Session Hijacking

Ця атака передбачає крадіжку cookie користувача для отримання несанкціонованого доступу до їх облікового запису в додатку. Використовуючи вкрадену cookie, зловмисник може видавати себе за законного користувача.

Session Fixation

У цьому сценарії зловмисник обманює жертву, щоб вона використовувала конкретну cookie для входу. Якщо додаток не призначає нову cookie під час входу, зловмисник, маючи оригінальну cookie, може видавати себе за жертву. Ця техніка залежить від того, що жертва входить з cookie, наданою зловмисником.

Якщо ви знайшли XSS у піддомені або контролюєте піддомен, прочитайте:

Cookie Tossing

Session Donation

Тут зловмисник переконує жертву використовувати cookie сесії зловмисника. Жертва, вважаючи, що вона увійшла до свого облікового запису, ненавмисно виконує дії в контексті облікового запису зловмисника.

Якщо ви знайшли XSS у піддомені або контролюєте піддомен, прочитайте:

Cookie Tossing

JWT Cookies

Натисніть на попереднє посилання, щоб отримати доступ до сторінки, що пояснює можливі недоліки в JWT.

JSON Web Tokens (JWT), що використовуються в cookie, також можуть мати вразливості. Для отримання детальної інформації про потенційні недоліки та способи їх експлуатації рекомендується звернутися до пов'язаного документа про злом JWT.

Cross-Site Request Forgery (CSRF)

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

Empty Cookies

(Перевірте додаткові деталі в оригінальному дослідженні) Браузери дозволяють створювати cookie без імені, що можна продемонструвати через JavaScript наступним чином:

js
document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"

Результат у заголовку cookie становить a=v1; test value; b=v2;. Цікаво, що це дозволяє маніпулювати cookie, якщо встановлено cookie з порожнім ім'ям, потенційно контролюючи інші cookie, встановлюючи порожній cookie на конкретне значення:

js
function setCookie(name, value) {
document.cookie = `${name}=${value}`
}

setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value

Це призводить до того, що браузер надсилає заголовок cookie, який кожен веб-сервер інтерпретує як cookie з ім'ям a та значенням b.

Chrome Bug: Проблема з кодовими точками сурогатів Unicode

У Chrome, якщо кодова точка сурогата Unicode є частиною встановленого cookie, document.cookie стає пошкодженим, повертаючи порожній рядок надалі:

js
document.cookie = "\ud800=meep"

Це призводить до того, що document.cookie виводить порожній рядок, що вказує на постійну корупцію.

Контрабанда кукі через проблеми з парсингом

(Дивіться деталі в оригінальному дослідженні) Декілька веб-серверів, включаючи ті, що з Java (Jetty, TomCat, Undertow) та Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), неправильно обробляють рядки кукі через застарілу підтримку RFC2965. Вони читають значення кукі в подвійних лапках як одне значення, навіть якщо воно містить крапки з комою, які зазвичай повинні розділяти пари ключ-значення:

RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";

Вразливості ін'єкції кукі

(Дивіться деталі в оригінальному дослідженні) Неправильний парсинг кукі серверами, зокрема Undertow, Zope та тими, що використовують Python's http.cookie.SimpleCookie і http.cookie.BaseCookie, створює можливості для атак ін'єкції кукі. Ці сервери не можуть правильно обмежити початок нових кукі, що дозволяє зловмисникам підробляти кукі:

  • Undertow очікує нову кукі відразу після цитованого значення без крапки з комою.
  • Zope шукає кому, щоб почати парсинг наступної кукі.
  • Класи кукі Python починають парсинг з символу пробілу.

Ця вразливість особливо небезпечна в веб-додатках, які покладаються на захист CSRF на основі кукі, оскільки це дозволяє зловмисникам ін'єктувати підроблені кукі CSRF-токенів, потенційно обходячи заходи безпеки. Проблема ускладнюється обробкою Python дублікатів імен кукі, де останнє входження перекриває попередні. Це також викликає занепокоєння щодо кукі __Secure- і __Host- в небезпечних контекстах і може призвести до обходу авторизації, коли кукі передаються на сервери, що піддаються підробці.

Кукі $version

Обхід WAF

Згідно з цією статтею, можливо, що можна використовувати атрибут кукі $Version=1, щоб змусити бекенд використовувати стару логіку для парсингу кукі через RFC2109. Більше того, інші значення, такі як $Domain і $Path, можуть бути використані для зміни поведінки бекенду з кукі.

Атака "Кукі-сендвіч"

Згідно з цією статтею, можливо використовувати техніку кукі-сендвіча для викрадення HttpOnly кукі. Ось вимоги та кроки:

  • Знайти місце, де очевидно безкорисна кукі відображається у відповіді
  • Створити кукі з назвою $Version зі значенням 1 (ви можете зробити це в атаці XSS з JS) з більш специфічним шляхом, щоб вона отримала початкову позицію (деякі фреймворки, такі як Python, не потребують цього кроку)
  • Створити кукі, яка відображається зі значенням, що залишає відкриті подвійні лапки і з конкретним шляхом, щоб вона була розташована в базі кукі після попередньої ($Version)
  • Тоді легітимна кукі піде наступною в порядку
  • Створити фальшиву кукі, яка закриває подвійні лапки всередині свого значення

Таким чином, кукі жертви потрапляє в пастку всередині нової кукі версії 1 і буде відображатися щоразу, коли вона відображається. e.g. з посту:

javascript
document.cookie = `$Version=1;`;
document.cookie = `param1="start`;
// any cookies inside the sandwich will be placed into param1 value server-side
document.cookie = `param2=end";`;

WAF обходи

Cookies $version

Перевірте попередній розділ.

Обхід аналізу значень з кодуванням quoted-string

Цей парсинг вказує на те, щоб розкодувати екрановані значення всередині cookie, тому "\a" стає "a". Це може бути корисно для обходу WAF, оскільки:

  • eval('test') => заборонено
  • "\e\v\a\l\(\'\t\e\s\t\'\)" => дозволено

У RFC2109 вказано, що кома може використовуватися як роздільник між значеннями cookie. Також можливо додавати пробіли та табуляції перед і після знака рівності. Тому cookie, як-от $Version=1; foo=bar, abc = qux, не генерує cookie "foo":"bar, admin = qux", а генерує cookie foo":"bar" та "admin":"qux". Зверніть увагу, як генеруються 2 cookie і як з admin видалено пробіл перед і після знака рівності.

Нарешті, різні бекдори можуть об'єднувати в рядок різні cookie, передані в різних заголовках cookie, як у:

GET / HTTP/1.1
Host: example.com
Cookie: param1=value1;
Cookie: param2=value2;

Що може дозволити обійти WAF, як у цьому прикладі:

Cookie: name=eval('test//
Cookie: comment')

Resulting cookie: name=eval('test//, comment') => allowed

Додаткові перевірки вразливих куків

Основні перевірки

  • cookie є однаковим щоразу, коли ви входите в систему.
  • Вийдіть з системи та спробуйте використати той самий cookie.
  • Спробуйте увійти з 2 пристроїв (або браузерів) до одного й того ж облікового запису, використовуючи той самий cookie.
  • Перевірте, чи містить cookie якусь інформацію, і спробуйте змінити її.
  • Спробуйте створити кілька облікових записів з майже однаковими іменами користувачів і перевірте, чи можете ви побачити подібності.
  • Перевірте опцію "запам'ятати мене", якщо вона існує, щоб дізнатися, як вона працює. Якщо вона існує і може бути вразливою, завжди використовуйте cookie з запам'ятати мене без жодного іншого cookie.
  • Перевірте, чи працює попередній cookie навіть після зміни пароля.

Складні атаки на куки

Якщо cookie залишається таким же (або майже таким) під час входу, це, ймовірно, означає, що cookie пов'язаний з якимось полем вашого облікового запису (ймовірно, з ім'ям користувача). Тоді ви можете:

  • Спробуйте створити багато облікових записів з дуже схожими іменами користувачів і спробуйте вгадати, як працює алгоритм.
  • Спробуйте брутфорсити ім'я користувача. Якщо cookie зберігається лише як метод аутентифікації для вашого імені користувача, тоді ви можете створити обліковий запис з ім'ям користувача "Bmin" і брутфорсити кожен окремий біт вашого cookie, оскільки один з cookie, які ви спробуєте, буде належати "admin".
  • Спробуйте Padding Oracle (ви можете розшифрувати вміст cookie). Використовуйте padbuster.

Padding Oracle - приклади Padbuster

bash
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
# When cookies and regular Base64
padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies auth=u7bvLewln6PJPSAbMb5pFfnCHSEd6olf

# If Base64 urlsafe or hex-lowercase or hex-uppercase --encoding parameter is needed, for example:
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2

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

Потім він почне розшифровувати кукі (це може зайняти кілька хвилин).

Якщо атака була успішно виконана, ви можете спробувати зашифрувати рядок на ваш вибір. Наприклад, якщо ви хочете зашифрувати user=administrator.

padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator

Це виконання надасть вам cookie, правильно зашифрований та закодований зі строкою user=administrator всередині.

CBC-MAC

Можливо, cookie може мати певне значення і може бути підписаний за допомогою CBC. Тоді цілісність значення є підписом, створеним за допомогою CBC з тим же значенням. Оскільки рекомендується використовувати як IV нульовий вектор, цей тип перевірки цілісності може бути вразливим.

Атака

  1. Отримати підпис імені користувача administ = t
  2. Отримати підпис імені користувача rator\x00\x00\x00 XOR t = t'
  3. Встановити в cookie значення administrator+t' (t' буде дійсним підписом (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00

ECB

Якщо cookie зашифровано за допомогою ECB, він може бути вразливим.
Коли ви входите, cookie, який ви отримуєте, завжди має бути однаковим.

Як виявити та атакувати:

Створіть 2 користувачів з майже однаковими даними (ім'я користувача, пароль, електронна пошта тощо) і спробуйте виявити певний шаблон у наданому cookie.

Створіть користувача, наприклад, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" і перевірте, чи є якийсь шаблон у cookie (оскільки ECB шифрує з одним і тим же ключем кожен блок, ті ж зашифровані байти можуть з'явитися, якщо ім'я користувача зашифровано).

Повинен бути шаблон (з розміром використаного блоку). Отже, знаючи, як зашифровано купу "a", ви можете створити ім'я користувача: "a"*(розмір блоку)+"admin". Тоді ви зможете видалити зашифрований шаблон блоку "a" з cookie. І у вас буде cookie для імені користувача "admin".

References

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks