Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
shiro-cve-2020-17523 — shiro-cve-2020-17523: анализ двух методов обхода уязвимости и соответствующая среда для эксплуатации | Kitploit
Инструменты/GitHubGitHub/jweny/shiro-cve-2020-17523
Аутентификация и авторизацияАнализ уязвимостейЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubjweny/shiro-cve-2020-17523

shiro-cve-2020-17523

shiro-cve-2020-17523: анализ двух методов обхода уязвимости и соответствующая среда для эксплуатации

Репозиторий
118115 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Apache Shiro два способа обхода аутентификации (CVE-2020-17523)

0x01 Описание уязвимости

Apache Shiro — это мощная и простая в использовании платформа безопасности Java, выполняющая аутентификацию, авторизацию, управление паролями и сессиями. Благодаря понятному API Shiro вы можете быстро и легко создавать любые приложения — от самых маленьких мобильных до крупнейших корпоративных.

При совместном использовании с Spring и определённых правилах сопоставления прав доступа злоумышленник может обойти аутентификацию, создав специальный HTTP-запрос.

Затронутые версии: Apache Shiro < 1.7.1

0x02 Настройка среды для уязвимости

shiro 1.7.0

https://github.com/jweny/shiro-cve-2020-17523 Среда для обоих методов уже обновлена.

0x03 Тестирование PoC

Метод 1:

http://127.0.0.1:8080/admin/%20 или http://127.0.0.1:8080/admin/%20/

Использование пробелов и других пустых символов позволяет обойти аутентификацию Shiro.

image-20210205120522547

Метод 2:

После общения с коллегой p0desta был обнаружен ещё один метод использования в особых сценариях.

http://127.0.0.1:8080/admin/%2e или http://127.0.0.1:8080/admin/%2e/

Однако . (а также /) в правилах сопоставления путей Spring являются разделителями путей и не сопоставляются как обычные символы. Поэтому по умолчанию доступ к /admin/. возвращает 404.

Но если включён полный путь (setAlwaysUseFullPath(true)), сопоставление работает корректно.

image-20210205102100797

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

В Shiro получение и сопоставление URL происходит в org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain.

Кратко рассмотрим метод getChain:

carbon (2)

image-20210205103341569

Этот метод сначала проверяет, заканчивается ли requestURI на /, и если да, удаляет последний /.

Затем в цикле сопоставления путей сначала проверяется, заканчивается ли правило пути pathPattern на /, и если да, он также удаляется. После этого вызывается метод pathMatches() для сопоставления пути.

Поэтому для обоих методов не имеет значения, заканчивается ли путь на /, так как после прохождения getChain он будет удалён.

4.1 Анализ обхода с пробелом

Обратим внимание на метод pathMatches():

Вызовем Evaluate и вычислим pathMatches("/admin/*","/admin/1") и pathMatches("/admin/*","/admin/ "). Первый соответствует нормально, второй — нет.

image-20210203134044268

image-20210203134119174

Начинаем отладку. После долгого F7 доходим до doMatch("/admin/*","/admin/ "). Видно, что tokenizeToStringArray вернул pathDirs уже без второго уровня пути. Это приводит к несоответствию /admin/* и /admin.

image-20210203150854085

Следуем за методом tokenizeToStringArray. Обнаруживаем, что при вызове tokenizeToStringArray параметр trimTokens равен true.

image-20210203150959413

В методе tokenizeToStringArray при значении trimTokens true выполняется обработка trim(), что удаляет пробелы. После возврата в getChain последний / удаляется. Поэтому pathDirs, возвращённые tokenizeToStringArray, не содержат второго уровня пути.

image-20210203151053344

Резюме: в уязвимой версии Shiro при вызове tokenizeToStringArray по умолчанию trimTokens равен true, и пробелы удаляются через trim(). После возврата в getChain последний / удаляется, поэтому /admin не соответствует /admin/*, что приводит к обходу аутентификации. В то же время Spring получает путь доступа /admin/%20 и обрабатывает его как обычно, что позволяет обойти авторизацию.

4.2 Анализ обхода с /./

Глядя на второй метод с /. и /./, вспоминаете ли вы знакомый метод? Да, это normalize().

carbon (3)

Кратко переведём:

УсловиеПример
Обработка обратной косой черты в прямую\ -> /
Двойной слеш обрабатывается как один

Таким образом, /admin/. сначала обрабатывается в /admin/./, затем становится /admin/.

image-20210205113301788

После обработки в org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain последний / удаляется, и получается /admin. /admin не соответствует /admin/*, поэтому аутентификация Shiro обходится.

image-20210205113518970

В то же время Spring получает запрос /admin/.. Если полный путь не включён, в Spring . и / являются разделителями путей и не участвуют в сопоставлении. Поэтому маппинг не находится и возвращается 404.

image-20210205114350972

Если включён полный путь, Spring сопоставляет весь URL и возвращает 200.

Здесь приведён код для включения полного пути:

root@kitploit:~
@SpringBootApplication
public class SpringbootShiroApplication extends SpringBootServletInitializer implements BeanPostProcessor {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootShiroApplication.class);
    }

    public static void main(String[] args) {

        SpringApplication.run(SpringbootShiroApplication.class, args);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping) bean).setAlwaysUseFullPath(true);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }
}

0x05 Официальное исправление

На основе анализа можно выделить две причины обхода авторизации в Shiro:

  1. Функция tokenizeToStringArray некорректно обрабатывает пробелы.
  2. Логика удаления последнего / не должна выполняться до цикла сопоставления путей.

Официальное исправление:

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

  1. Установить параметр trimTokens в значение false в tokenizeToStringArray. image-20210203154342100
  2. Изменить порядок удаления последнего /. Сначала сопоставлять исходный путь, и только если сопоставление не удалось, удалять последний /. image-20210205115522098

0x06 О trim

Теоретически trim() удаляет все пробельные символы в начале и конце строки; пробел — лишь один из них. Однако в тестах другие пробельные символы, такие как %08, %09, %0a, при обработке Spring+Tomcat возвращают 400.

Таким образом, для первого метода, кроме пробела, других полезных payload пока не обнаружено.

0x07 Ссылки

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

https://www.anquanke.com/post/id/216096

https://www.cnblogs.com/syp172654682/p/9257282.html

Скачать инструмент
// -> /
Если заканчивается на /. или /.., добавляем / в конце/. -> /./ /.. -> /../
Нормализация /.//./ -> /
Прыжок по пути/aaa/../bbb -> /bbb