CVE-2019から17571のデシリアライゼーションでのLog4jコンポーネント

https://www.openwall.com/lists/oss-security/2019/12/19/2

日付:水曜日、18 12月2019年 212119 - 0600 
から:マット・病状 <mattsicker @ ... che.org> 
へ:OSS - セキュリティ@ ... ts.openwall.com 
件名:[CVE - 2019年 - 17571 ]はApacheのLog4j 1.2 信頼できないデータのデシリアライズ
  SocketServer 

CVE - 2019 - 17571:信頼できないデータのデシリアライゼーションSocketServer 

重要度:重大
CVSS:3.0 / AV:N / AC:L / PR:N / UI:N / S:U / C :H / I:H / A:H / RL:W

製品:
ApacheのLog4jのの

影響を受けるバージョン:
ApacheのLog4jのまでを含む1.227別に固定
CVE - 2017年 - 5645  のLog4j 2.82 

問題のタイプ:
CWE - 502 :信頼できないデータのデシリアライズ

説明:

含ま Log4jの1.2  である SocketServerのクラスであるに弱い
遠隔的に利用することができる、信頼できないデータのデシリアライゼーション 
デシリアライゼーションガジェットと組み合わせた場合に任意のコードを実行します
信頼できないネットワークトラフィックを聴くときのためにログデータ。

緩和:

ApacheのLog4jの1.2は、人生の最後に到達して年8月2015年までにユーザーは、必要がある
のLog4jにアップグレード2 .Xアドレスその脆弱性の両方としてだけでなく
 として、他の多くの問題以前のバージョン。

クレジット:

この問題が最初に発見された中で CVE- 2017年 - 5645 マルシオ・アルメイダによって
テルストラでレッドチームのデMacedo。

リンク:

HTTPS:// logging.apache.org/log4j/1.2/
HTTPS:// issues.apache.org/jira/browse/LOG4J2-1863
 
-  
マット・重症
長官、Apache Software Foundationの
VPロギングサービス、ASF

SocketServerクラスの脆弱性

Log4jのjarファイルパッケージをダウンロードしてください。私は1.2.14のバージョンを選択しました。

SocketServer.classにグローバル検索

 

 

クラスコード、コードを参照するには、コードの主な機能は長くはありません、それは非常によく理解されています。

  void main(String argv[]) {
    if(argv.length == 3)
      init(argv[0], argv[1], argv[2]);
    else
      usage("Wrong number of arguments.");

    try {
      cat.info("Listening on port " + port);
      ServerSocket serverSocket = new ServerSocket(port);
      while(true) {
    cat.info("Waiting to accept a new client.");
    Socket socket = serverSocket.accept();
    InetAddress inetAddress =  socket.getInetAddress();
    cat.info("Connected to client at " + inetAddress);

    LoggerRepository h = (LoggerRepository) server.hierarchyMap.get(inetAddress);
    if(h == null) {
      h = server.configureHierarchy(inetAddress);
    }

    cat.info("Starting new socket node.");
    new Thread(new SocketNode(socket, h)).start();
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

init初始化了参数,传入的参数是三个。

new一个serverSocket对象,最后new Thread(new SocketNode(socket, h)).start();

把收到的socket流内容,用SocketNode实例化这个流内容。我们看下SocketNode这个类是怎么实现的吧。全局搜索SocketNode。

public class SocketNode implements Runnable {

  Socket socket;
  LoggerRepository hierarchy;
  ObjectInputStream ois;

  static Logger logger = Logger.getLogger(SocketNode.class);

  public SocketNode(Socket socket, LoggerRepository hierarchy) {
    this.socket = socket;
    this.hierarchy = hierarchy;
    try {
      ois = new ObjectInputStream(
                         new BufferedInputStream(socket.getInputStream()));
    }
    catch(Exception e) {
      logger.error("Could not open ObjectInputStream to "+socket, e);
    }
  }

  //public
  //void finalize() {
  //System.err.println("-------------------------Finalize called");
  // System.err.flush();
  //}

  public void run() {
    LoggingEvent event;
    Logger remoteLogger;

    try {
      while(true) {
    // read an event from the wire
    event = (LoggingEvent) ois.readObject();
    // get a logger from the hierarchy. The name of the logger is taken to be the name contained in the event.
    remoteLogger = hierarchy.getLogger(event.getLoggerName());
    //event.logger = remoteLogger;
    // apply the logger-level filter
    if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) {
      // finally log the event as if was generated locally
      remoteLogger.callAppenders(event);
    }
      }
    } catch(java.io.EOFException e) {
      logger.info("Caught java.io.EOFException closing conneciton.");
    } catch(java.net.SocketException e) {
      logger.info("Caught java.net.SocketException closing conneciton.");
    } catch(IOException e) {
      logger.info("Caught java.io.IOException: "+e);
      logger.info("Closing connection.");
    } catch(Exception e) {
      logger.error("Unexpected exception. Closing conneciton.", e);
    }

    try {
      ois.close();
    } catch(Exception e) {
      logger.info("Could not close connection.", e);
    }
  }
}

代码不是很长,执行的是run的代码。可以看到

event = (LoggingEvent) ois.readObject();

直接执行了readObject操作。ois是ObjectInputStream ois;定义了ois是输入流。

因此只要传入的字节流是反序列化的内容即可。

おすすめ

転載: www.cnblogs.com/ph4nt0mer/p/12125241.html