Мы про­води­ли пен­тест одной боль­шой ком­пании с хорошим бюд­жетом на ИБ и обна­ружи­ли баг в коробоч­ном решении WebTutor. Эта уяз­вимость поз­волила нам получить дос­туп во внут­реннюю сеть, где мы стол­кну­лись с EDR и анти­виру­сом. Обой­ти их помог­ла воз­можность исполнять коман­ды из зап­росов к БД.

Pentest Award

Этот текст получил третье мес­то на пре­мии Pentest Award 2024 в катего­рии «Про­бив web». Это сорев­нование еже­год­но про­водит­ся ком­пани­ей Awilix.

Здесь я не буду обсуждать весь ход работ — ско­уп был боль­шим, и в него вхо­дило мно­го самопис­ных при­ложе­ний и нес­коль­ко коробоч­ных. Рас­ска­жу лишь об ата­ке на WebTutor — как о наибо­лее инте­рес­ном момен­те.

warning

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

 

Анализ исходных кодов (XSS и чтение файла)

Websoft HCM (ранее называ­лась WebTutor) — это сис­тема управле­ния талан­тами, пред­лага­ющая инс­тру­мен­ты под­бора, обу­чения, оцен­ки ком­петен­ций, пла­ниро­вания карь­еры, управле­ния зна­ниями. Это коробоч­ное решение, которое исполь­зует­ся мно­гими ком­пани­ями для авто­мати­зации работы по най­му и обу­чению сот­рудни­ков.

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

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

Для хра­нения дан­ных при­ложе­ние исполь­зует фай­ловую базу дан­ных или Microsoft SQL в зависи­мос­ти от нас­тро­ек.

Пос­ле уста­нов­ки находим в фай­ловой сис­теме пап­ку WebTutorAdmin с веб‑сер­вером. В ней две пап­ки: сно­ва WebTutorAdmin, где лежит админка, и WebTutorServer с про­чими фун­кци­ями сер­вера.

Я поис­кал извес­тные нам стра­ницы (логин и регис­тра­ция) и понял, что все фай­лы HTML из пап­ки WebTutorServer/wt/web дос­тупны через веб‑интерфейс. Так­же в этой пап­ке находят­ся фай­лы .xml и .bs, которые мож­но читать и выпол­нять через вызовы API.

info

WebTutor написан на язы­ке JScript. JScript — это реали­зация ECMAScript ком­пании Microsoft. При­ложе­ние так­же исполь­зует .NET Core и мно­жес­тво DLL-биб­лиотек. Для управле­ния логикой при­ложе­ния исполь­зуют­ся три типа фай­лов: .html — стра­ницы с кодом кли­ент­ской и сер­верной час­ти вмес­те, .xml и .bs. Пос­ледний исполь­зует­ся для опи­сания методов API, которые дос­тупны в при­ложе­нии. Фай­лы HTML в JScript напоми­нают шаб­лоны PHP, где сер­верный код череду­ется с кодом стра­ницы.

Дос­туп к боль­шинс­тву эндпо­интов API воз­можен без допол­нитель­ной авто­риза­ции, так как там есть про­вер­ка поль­зовате­ля. В шаб­лонах HTML за про­вер­ки сес­сии отве­чают под­гру­жаемые в начале скрип­ты:

Server.Execute( "include/user_init.html" );
Server.Execute( "include/host_init.html" );

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

Быс­тро находим прос­тую XSS вот в этом фай­ле:

WebTutorAdmin/WebTutorServer/wt/web/replace_photo.html

Пе­ремен­ная URL берет­ся из зап­роса и без вся­кой филь­тра­ции встав­ляет­ся в код стра­ницы.

<%
try
{
_url = UrlDecode( Trim( Request.Form.GetProperty( "url" ) ) );
//...
<script type="text/javascript">
location.href = "<%=_url%>";
</script>
Пример встраивания кода на JScript
При­мер встра­ива­ния кода на JScript

Пол­ный HTTP-зап­рос для XSS:

POST /replace_photo.html HTTP/1.1
Host: 10.3.89.104
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/* ;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Connection: close
Cookie: SessionID=7303593220364327493
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
foto=1&url=1";alert(1);//

Пе­реп­роверя­ем все эндпо­инты API без авто­риза­ции и находим метод /api/spxml2/get_image. Он дос­тупен и поз­воля­ет читать про­изволь­ные фай­лы в сис­теме.

Пример чтения файла win.ini
При­мер чте­ния фай­ла win.ini
 

Создание нового пользователя в системе

Рас­ширить зону поис­ка мож­но, нап­ример, получив учет­ную запись. Ищем фай­лы, где про­исхо­дит работа с поль­зовате­лями, и находим воз­можность изме­нения про­филя в сле­дующем фай­ле:

WebTutorAdmin/WebTutorServer/wt/web/user_change.html

Из зап­роса берут­ся все дан­ные и даль­ше сох­раня­ются в БД, при этом не дела­ется про­вер­ка на активную сес­сию. Хоть при­ложе­ние лома­ется при таком зап­росе и выда­ет 500, оно все рав­но успе­вает выз­вать пер­вый блок кода, где выпол­няет­ся сох­ранение поль­зовате­ля в БД.

Все парамет­ры для соз­дава­емо­го поль­зовате­ля берут­ся из зап­роса, вклю­чая логин и пароль. Для соз­дания незаб­локиро­ван­ного поль­зовате­ля необ­ходимо передать аргу­мен­ты view=new без поля web_banned.

_login = tools_web.convert_xss(Request.Form.GetOptProperty("login", ""));
_password = tools_web.convert_xss(Request.Form.GetOptProperty("password", ""));
_lastname = tools_web.convert_xss(Request.Form.GetOptProperty("lastname", ""));
_firstname = tools_web.convert_xss(
Request.Form.GetOptProperty("firstname", "")
);
_middlename = tools_web.convert_xss(
Request.Form.GetOptProperty("middlename", "")
);
_position_name = tools_web.convert_xss(
Request.Form.GetOptProperty("position_name", "")
);
_view = tools_web.convert_xss(Request.Form.GetOptProperty("view", "self"));
_email = tools_web.convert_xss(Request.Form.GetOptProperty("email", ""));
_phone = tools_web.convert_xss(Request.Form.GetOptProperty("phone", ""));
_sex = tools_web.convert_xss(Request.Form.GetOptProperty("sex", "")); //...
if (_view == "new") _web_banned = Request.Form.HasProperty("web_banned");

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

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

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

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

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

    Подписаться

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