Се­год­ня мы порабо­таем с токена­ми JWT, про­экс­плу­ати­руем LFI в обход филь­тра и раз­ревер­сим ELF-файл, написан­ный на Python 3.9. Все это поможет нам прой­ти сред­нюю по слож­ности машину Unicode с пло­щад­ки Hack The Box.

warning

Под­клю­чать­ся к машинам с HTB рекомен­дует­ся толь­ко через VPN. Не делай это­го с компь­юте­ров, где есть важ­ные для тебя дан­ные, так как ты ока­жешь­ся в общей сети с дру­гими учас­тни­ками.

 

Разведка

Сканирование портов

До­бав­ляем IP-адрес машины в /etc/hosts:

10.10.11.126 unicode.htb

И запус­каем ска­ниро­вание пор­тов.

Справка: сканирование портов

Ска­ниро­вание пор­тов — стан­дар­тный пер­вый шаг при любой ата­ке. Он поз­воля­ет ата­кующе­му узнать, какие служ­бы на хос­те при­нима­ют соеди­нение. На осно­ве этой информа­ции выбира­ется сле­дующий шаг к получе­нию точ­ки вхо­да.

На­ибо­лее извес­тный инс­тру­мент для ска­ниро­вания — это Nmap. Улуч­шить резуль­таты его работы ты можешь при помощи сле­дующе­го скрип­та.

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Он дей­ству­ет в два эта­па. На пер­вом про­изво­дит­ся обыч­ное быс­трое ска­ниро­вание, на вто­ром — более тща­тель­ное ска­ниро­вание, с исполь­зовани­ем име­ющих­ся скрип­тов (опция -A).

Результат работы скрипта
Ре­зуль­тат работы скрип­та

Мы наш­ли два откры­тых пор­та:

  • 22 — служ­ба OpenSSH 8.2p1;
  • 80 — веб‑сер­вер Nginx 1.18.0.

Нач­нем с иссле­дова­ния сай­та.

Главная страница сайта
Глав­ная стра­ница сай­та

На пер­вой же стра­нице видим откры­тый редирект. Это сто­ит отме­тить, так как редирек­ты мож­но исполь­зовать для обхо­да ряда филь­тров и про­верок. Так­же на сай­те есть воз­можность зарегис­три­ровать­ся и авто­ризо­вать­ся. Сде­лаем и то и дру­гое. Работу желатель­но вес­ти в Burp Proxy, что­бы у нас оста­вались все записи.

Burp Proxy
Burp Proxy

Пос­ле логина видим редирект с прис­воен­ным иден­тифика­тором сес­сии auth. И сра­зу под­меча­ем нес­коль­ко новых воз­можнос­тей пос­ле авто­риза­ции.

Главная страница сайта после авторизации
Глав­ная стра­ница сай­та пос­ле авто­риза­ции

Уда­лось най­ти фор­му заг­рузки фай­лов, но ее тес­тирова­ние ни к чему не при­вело. Вер­немся к иден­тифика­тору сес­сии — это JWT. JSON Web Token сос­тоит из трех час­тей: заголов­ка (header), полез­ной наг­рузки (payload) и под­писи. Заголо­вок и полез­ная наг­рузка пред­став­ляют собой объ­екты JSON, при этом наг­рузка может быть любой, это имен­но те кри­тичес­ки важ­ные дан­ные, которые переда­ются при­ложе­нию. Заголо­вок содер­жит опре­делен­ные поля:

  • alg — алго­ритм, исполь­зуемый для под­писи/шиф­рования. Это обя­затель­ный ключ;
  • typ — тип токена. Это поле дол­жно иметь зна­чение JWT.

Тре­тий эле­мент вычис­ляет­ся на осно­вании пер­вых и зависит от выб­ранно­го алго­рит­ма. Токены могут быть переко­диро­ваны в ком­пак­тное пред­став­ление: к заголов­ку и полез­ной наг­рузке при­меня­ется алго­ритм Base64-URL, пос­ле чего добав­ляет­ся под­пись и все три эле­мен­та раз­деля­ются точ­ками. К при­меру, мож­но с помощью Burp Inspector декоди­ровать заголо­вок.

Декодированный заголовок
Де­коди­рован­ный заголо­вок

Поп­робу­ем разоб­рать эти дан­ные. Для это­го нам понадо­бит­ся либо при­ложе­ние jwt_tool, либо онлай­новый ресурс jwt.io. Я буду исполь­зовать вто­рой вари­ант. В заголов­ке у нас при­сутс­тву­ет параметр jku. Он опре­деля­ет URI, который ука­зыва­ет на ресурс, где находит­ся ключ про­вер­ки под­писи в пред­став­лении JWKS (JSON Web Key Set). В качес­тве под­писан­ных дан­ных исполь­зует­ся имя поль­зовате­ля.

Декодирование JWT
Де­коди­рова­ние JWT

Вер­немся к парамет­ру jku, там мы находим еще один домен, который допишем в файл /etc/hosts.

10.10.11.126 hackmedia.htb unicode.htb

JSON Web Key Set (JWKS) — это набор откры­тых клю­чей, которые исполь­зуют­ся для про­вер­ки веб‑токена, выпущен­ного сер­вером авто­риза­ции и под­писан­ного с исполь­зовани­ем алго­рит­ма под­писи RS256. RS256 генери­рует асим­метрич­ную под­пись. Что­бы под­писать JWT, дол­жен исполь­зовать­ся зак­рытый ключ, а для про­вер­ки под­писи нужен дру­гой откры­тый ключ. Прос­мотреть струк­туру JWKS мы можем, обра­тив­шись к URL, ука­зан­ному в jku, — http://hackmedia.htb/static/jwks.json.

Используемый JWKS
Ис­поль­зуемый JWKS

Даль­нейший век­тор оче­виден: необ­ходимо изме­нить имя поль­зовате­ля на admin, что даст нам при­виле­гиро­ван­ный кон­текст, под­писать новые дан­ные, сге­нери­ровать новый JWT и заменить ста­рый на веб‑сер­висе.

 

Точка входа

Те­перь раз­берем­ся с под­писью. В заголов­ке ука­зан адрес JWKS, что дает нам сле­дующую идею: сге­нери­ровать свою пару клю­чей для под­писи токена и соот­ветс­тву­ющий им JWKS. Мы помес­тим JWKS на сво­ем веб‑сер­вере и затем в заголов­ке про­пишем адрес, ука­зыва­ющий на этот сер­вер. Для генери­рова­ния клю­чей вос­поль­зуем­ся сай­том mkjwk.org. Выс­тавим исполь­зуемые парамет­ры и получим клю­чи.

Генерирование ключей
Ге­нери­рова­ние клю­чей

Те­перь вер­немся к токену на jwt.io. Изме­ним имя поль­зовате­ля на admin, в парамет­ре jku ука­жем файл на сво­ем сер­вере (веб‑сер­вер запус­каем коман­дой python3 -m http.server 80). Файл дол­жен содер­жать дан­ные из фор­мы Public Key. Для под­писи исполь­зуем пару клю­чей из форм Private Key (X.509 PEM Format) и Public Key (X.509 PEM Format).

Создание JWT-токена
Соз­дание JWT-токена

Встав­ляем дан­ный токен в Burp и пос­ле зап­роса получа­ем ответ об ошиб­ке про­вер­ки jku.

Ответ от сервера
От­вет от сер­вера

При этом на наш веб‑сер­вер зап­рос не при­шел. Зна­чит, есть про­вер­ка того, какой сер­вер ука­зан в jku. Тог­да исполь­зуем откры­тый редирект! Он будет перенап­равлять на наш сер­вер зап­росы, совер­шаемые для про­вер­ки jku:

http://hackmedia.htb/static/../redirect/?url=10.10.14.73/jwks.json
Новые параметры JWT
Но­вые парамет­ры JWT

При исполь­зовании нового JWT видим, что на наш сер­вер при­шел зап­рос.

Логи веб-сервера
Ло­ги веб‑сер­вера

Но дос­туп мы не получа­ем. Ско­рее все­го, это свя­зано с дан­ными в фай­ле JWKS. Прос­мотрим тог­да файл с сер­вера и изме­ним в нем толь­ко параметр n (e и так сов­пада­ет). Вновь посылая зап­рос через Burp, получа­ем новый ответ. Перехо­дим в бра­узер и, исполь­зуя рас­ширения вро­де Cookie Editor, встав­ляем новый JWT и обновля­ем стра­ницу.

Панель администратора
Па­нель адми­нис­тра­тора

В ито­ге получа­ем адми­нис­тра­тив­ную панель.

 

Точка опоры

Изу­чая сайт, сра­зу натыка­емся на стра­ницу, которая переда­ет кон­тент в парамет­ре.

Страница /display
Стра­ница /display

Поп­робу­ем ука­зать там какой‑нибудь файл, нап­ример /etc/passwd. Но получа­ем ошиб­ку и сооб­щение о том, что исполь­зует­ся филь­тр.

Сообщение, что обнаружена атака
Со­обще­ние, что обна­руже­на ата­ка

Тог­да я при­менил сло­варь, в котором содер­жатся раз­ные спо­собы обхо­да филь­тров для LFI, и получил отличную от осталь­ных реак­цию сер­вера.

Содержимое файла /etc/hosts
Со­дер­жимое фай­ла /etc/hosts

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии