«Проблемы» с нативной двоичной сериализацией в Java (да и не только) стали, наверное, одним из главных трендов 2015 года. На основе этой технологии были найдены критические уязвимости не просто в каком-то ПО, а в протоколах; зацепило и Android. Но технологии не ограничиваются только бинарной сериализацией (кроме нативной, есть еще целый пучок сторонних библиотек), есть и другие варианты. Один из них — XML-сериализация объектов.

Я уже описывал эксплуатацию такой уязвимости в одном из недавних выпусков Easy Hack. Тогда с помощью плагина для Burp мы модифицировали бинарную сериализацию в XML, меняли данные и после обратного процесса пересылали дальше на сервер. Для этого использовалась сторонняя библиотека XStream. Но есть и другие. И сегодня мы поговорим про простейший вариант (для атакующего) — XMLEncoder.

Начнем сразу с примера, так будет понятнее. Предположим, у нас имеется класс Employee. В нем есть два поля.

private int employeeId;
public String employeeName;

Создадим объект.

Employee emp1 = new Employee();
emp1.setEmployeeId(3);
emp1.employeeName="John";

Для того чтобы сериализовать объект, нам требуется всего пара строчек.

XMLEncoder e = new XMLEncoder(
    new BufferedOutputStream(
        new FileOutputStream("d:\\TestXML.xml")));
e.writeObject(emp1);

Чтобы десериализовать XML в объект, выполняется обратная операция.

XMLDecoder d = new XMLDecoder(
    new BufferedInputStream(
        new FileInputStream("d:\\TestXML.xml")));
Employee result = (Employee) d.readObject();

Согласись, очень схоже с нативной бинарной сериализацией. Похожи и основные фишки. Например, мы можем отправить любой сериализованный объект (из известных приложению классов), и он сначала будет десериализован (создан), а потом уже будет предпринята попытка его скастить (привести) к необходимому типу.

Однако все это нам не потребуется. Достаточно взглянуть на XML с объектом.



 
  
   employeeName
   
    
    John
   
  
  
   3
  
 

Поначалу структура может показаться запутанной, но главное здесь вот что: в отличие от нативной сериализации, где просто указываются все поля объекта и их значения, тут мы имеем доступ и к методам. XMLEncoder как бы описывает последовательность действий для последующего восстановления объектов с помощью XMLDecoder.

Теоретически если какое-то приложение ждет на вход объект Java, сериализованный с помощью XMLEncoder, то мы легко можем отправить специальный XML, который заставит приложение выполнить команду в ОС в процессе десериализации.

Вот пример такой XML.



    
        
             
                c:\\windows\\system32\\calc.exe            
                    
        
        
    
    

Подробнее об этой теме можешь почитать у ресерчера, который раскрыл эту тему.

Как видишь, технология реализована так, что с ее помощью можно сделать что угодно. Тем не менее она применяется в жизни. Например, не так давно (пару лет назад) ее перестал использовать фреймворк для RESTful-сервисов Restlet. Однако старые версии, которые, я уверен, еще используются во многих продуктах, дают в определенных случаях возможность получить RCE.

Кстати, я планирую в скором времени выложить на GitHub свое задание с хакквеста последнего ZeroNights. Ты сможешь поиграться с описанной выше атакой на Restlet, а также HQL-инъекцией для MySQL и типичной Execution After Redirect. Постараюсь и впредь снабжать Easy Hack тестовыми стендами, хотя вопрос, в каком виде их распространять, пока открыт.

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

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

    Подписаться

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