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
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
}
}
}
}
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
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