[Scala] [Java] Ich habe versucht, die Sicherheitsanfälligkeit beim Durchqueren von Zip4j durch Bytecode-Operation zu beheben.

Kennen Sie Zip-Slip, eine Sicherheitsanfälligkeit beim Durchsuchen von Zip?

Ich werde die Details anderen Artikeln wie ↓ überlassen, aber dieses Mal werde ich versuchen, die Bibliothek mit dem Namen zip4j durch Manipulieren des Bytecodes zu reparieren. Auswirkungen der Sicherheitsanfälligkeit beim Durchlaufen des Zip Slip-Verzeichnisses auf viele Java-Projekte

Übrigens ist hier die Version der Sicherheitsanfälligkeits-Gegenmaßnahme für jede Bibliothek aufgeführt, die Zip verarbeitet. snyk/zip-slip-vulnerability: Zip Slip Vulnerability (Arbitrary file write through archive extraction) Es scheint, dass zip4j keine JAR-Distribution hat ... Wenn Sie den Quellcode verteilen und selbst zu einem Glas machen, ist es meiner Meinung nach wahrscheinlicher, dass Sie nicht die neueste Version verwenden ...

↓ Zip-Slip-Testdaten zip-slip-vulnerability/archives at master · snyk/zip-slip-vulnerability

Code, den ich zu reparieren versucht habe

import javassist._
import javassist.expr.ExprEditor
import javassist.expr.MethodCall
import net.lingala.zip4j.core.ZipFile

/**
  *Dynamisches Zip4j-Sicherheitspatch durch Umschreiben des Bytecodes
  */
object Zip4jSecurity {
  def main(args: Array[String]): Unit = {
    patch()

    //Testen Sie, ob die Validierung funktioniert. Postleitzahl-Eine Ausnahme tritt aufgrund der Belegvalidierung auf.
    val zipFile = new ZipFile("/home/momose/Documents/zip-slip.zip")
    zipFile.extractAll("/home/momose/Documents/tmp/")
  }

  /**
    *Wenden Sie den Patch an
    */
  def patch(): Unit = {
    val cp = ClassPool.getDefault
    val classLoader = Thread.currentThread().getContextClassLoader()
    cp.appendClassPath(new LoaderClassPath(classLoader))
    val cc = cp.get("net.lingala.zip4j.unzip.Unzip")
    val zipSlipValidationEditor = new Zip4jSecurity.ZipSlipValidationEditor
    cc.instrument(zipSlipValidationEditor)
    //Registrieren Sie sich beim Klassenlader
    cc.toClass(null, clazz.getProtectionDomain)
  }

  private class ZipSlipValidationEditor extends ExprEditor {
    //Flags, die nur für den ersten Methodenaufruf gelten
    private var unedited = true

    override def edit(m: MethodCall): Unit = {
      if (unedited &&
        m.getClassName.equals("net.lingala.zip4j.model.CentralDirectory") &&
        m.getMethodName.equals("getFileHeaders")) {
        //Validierungscode
        val statement ="""
java.io.File outputDir = new java.io.File(outPath);
java.util.List fileHeaders = $0.getFileHeaders($$);
for( int i=0; i<fileHeaders.size(); i++ ){
    net.lingala.zip4j.model.FileHeader e = (net.lingala.zip4j.model.FileHeader)fileHeaders.get(i);
    if (!new java.io.File(outputDir, e.getFileName()).getCanonicalPath().startsWith(outputDir.getCanonicalPath())) {
            throw new RuntimeException("Illegale Postleitzahl");
    }
}
$_ = fileHeaders;"""
        m.replace(statement)
        unedited = false
      }
    }
  }

}

Ausführungsergebnis

Exception in thread "main" java.lang.RuntimeException:Illegale Postleitzahl
	at net.lingala.zip4j.unzip.Unzip.extractAll(Unzip.java:50)
	at net.lingala.zip4j.core.ZipFile.extractAll(ZipFile.java:488)
	at net.lingala.zip4j.core.ZipFile.extractAll(ZipFile.java:451)
	at com.github.momosetkn.zip.Zip4jSecurity$.main(Zip4jSecurity.scala:18)
	at com.github.momosetkn.zip.Zip4jSecurity.main(Zip4jSecurity.scala)

Es validiert das Ergebnis der Java-Methode "getCanonicalPath", z. B. "realpath" in C- und Linux-Befehlen. ↓ Referenzmaterialien IDS02 \ -J . Pfadnamen vor der Validierung normalisieren

Nur bei Verwendung in der Methode net.lingala.zip4j.core.ZipFile # extractAll Wir haben nicht bestätigt, dass dies eine Gegenmaßnahme ist, sodass in anderen Fällen Sicherheitslücken entstehen können. Ich möchte, dass Sie es selbst testen.

↓ Dieser Teil wird im Methodenaufruf net.lingala.zip4j.model.CentralDirectory # getFileHeaders () vorbereitet. zip4j/Unzip.java at master · supasate/zip4j

Impressionen

Mit Scala sollten String-Literale einfach zu handhaben sein. Es wäre auch schön, wenn alle Ausnahmen wie ungeprüfte Ausnahmen behandelt würden. Beim Umschreiben mit javassist ist es umständlich, Java-Code zu schreiben, der der neu zu schreibenden Java-Version entspricht.

Recommended Posts

[Scala] [Java] Ich habe versucht, die Sicherheitsanfälligkeit beim Durchqueren von Zip4j durch Bytecode-Operation zu beheben.
Ich habe versucht, die Fehlermeldung beim Ausführen von Eclipse (Java) zu übersetzen.
[Java] Ich habe versucht, mit der Grabmethode ein Labyrinth zu erstellen ♪
Ich habe versucht, die Methode der gegenseitigen Teilung von Eugrid in Java zu implementieren
Ich habe versucht, die ähnliche Funktion durch asynchrone Kommunikation zu implementieren
[JDBC] Ich habe versucht, von Java aus auf die SQLite3-Datenbank zuzugreifen.
Ich habe versucht, die Grundlagen von Kotlin und Java zusammenzufassen
Ich habe versucht, die Umgebung nach und nach mit Docker aufzubauen
Ich möchte die Notwendigkeit des Testens beurteilen, indem ich die Unterschiede der Klassendateien beim Refactoring von Java vergleiche.
Ich habe versucht, den Betrieb des gRPC-Servers mit grpcurl zu überprüfen
Ich habe versucht, die Methoden von Java String und StringBuilder zusammenzufassen
Ich habe versucht, das Java-kompatible FaaS-Formular "Fn Project" auszuführen.
Ich habe versucht, den Kalender mit Java auf der Eclipse-Konsole anzuzeigen.
Durch die Überprüfung der Funktionsweise von Java unter Linux konnte ich die Kompilierung und Hierarchie verstehen.
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, die Methode zu erklären
Ich habe das Java-Framework "Quarkus" ausprobiert.
Ich habe versucht, das Java-Lernen zusammenzufassen (1)
Ich habe jetzt versucht, Java 8 zusammenzufassen
Ich habe versucht, den Punktzähler durch serielle Kommunikation mit der MZ-Plattform zu verbinden
[Einführung in Java] Ich habe versucht, das Wissen zusammenzufassen, das ich für wesentlich halte
Ich möchte die IP-Adresse erhalten, wenn ich mit Java eine Verbindung zu Wi-Fi herstelle
Ich habe versucht, die verwendeten Methoden zusammenzufassen
Ich habe versucht, Java-Lambda-Ausdrücke zusammenzufassen
Ich habe das neue Yuan-Problem in Java ausprobiert
Ich habe versucht, das Iterator-Muster zu implementieren
Ich habe versucht, die Stream-API zusammenzufassen
Ich ging zum Java Women's Club # 1
Eine Geschichte, als ich versuchte, ein Video zu erstellen, indem ich Processing und Resolume verknüpfte
Was ich versucht habe, als ich alle Felder einer Bohne bekommen wollte
Ich möchte, dass Sie Scala vorerst als besseres Java verwenden
[JavaScript] Der stärkste Fall, als ich versuchte, die Teile zusammenzufassen, die ich nicht verstehe
[Kleine Geschichte] Ich habe versucht, die Java-ArrayList etwas komfortabler zu gestalten