Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
dsa — Analyse von CVE-2016-3959 und ein Proof-of-Concept-Angriff gegen einen Go-SSH-Server. | Kitploit
Tools/GitHubGitHub/alexmullins/dsa
SchwachstellenanalyseExploitationKryptographiePenetrationstestsLernen & Bildung
GitHubalexmullins/dsa

dsa

Analyse von CVE-2016-3959 und ein Proof-of-Concept-Angriff gegen einen Go-SSH-Server.

Repository anzeigen
117vor 10 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Eine Zusammenfassung der Go-crypto/dsa-Sicherheitslücke (CVE-2016-3959)

Alex Mullins

  1. April 2016

Einleitung

Vor kurzem wurde ein Fehler in der Digital Signature Algorithm (DSA)-Kryptografiebibliothek der Programmiersprache Go entdeckt. In diesem Artikel werden wir die Einzelheiten des Fehlers besprechen und wie ein Angreifer ihn ausnutzen könnte, um einen Denial-of-Service-Angriff gegen einen standardmäßigen Go-SSH-Server zu starten, der die zugrunde liegende DSA-Bibliothek zur Authentifizierung von Clients verwendet.

Die erste Erwähnung dieser Sicherheitslücke erschien in einem Beitrag auf der Open Source Security (oss-sec)-Mailingliste unter http://seclists.org/oss-sec/2016/q2/11.

Go hat eine Endlosschleife in mehreren Big-Integer-Routinen, die Go-Programme anfällig für Remote-Denial-of-Service-Angriffe macht. Programme, die HTTPS-Client-Authentifizierung oder die Go-SSH-Serverbibliotheken verwenden, sind beide dieser Sicherheitslücke ausgesetzt. Dies wird im folgenden CL behoben: https://golang.org/cl/21533

-- Jason Buberel

Zusammenfassend gesagt, wenn diese Sicherheitslücke ausgenutzt würde, könnte sie zu einer Endlosschleife im zugrunde liegenden BigNum-Bibliothekscode führen. Dies würde Systemressourcen in Bezug auf CPU und Arbeitsspeicher verbrauchen und könnte schließlich dazu führen, dass das Programm oder das System selbst nicht mehr reagiert.

Die obige Aussage besagt, dass SSH zusammen mit HTTPS-Client-Authentifizierung betroffen ist, aber nach einem Blick auf die crypto/tls- und net/http-Pakete von Go scheint dies falsch zu sein. Die HTTPS-Client-Authentifizierung kann entweder RSA- oder ECDSA-Signaturverfahren verwenden, aber nicht DSA. Siehe unten. Wenn ich damit falsch liege, lassen Sie es mich bitte wissen.

https://golang.org/pkg/crypto/tls/#Certificate

type Certificate struct {
        Certificate [][]byte
        // PrivateKey contains the private key corresponding to the public key
        // in Leaf. For a server, this must implement crypto.Signer and/or
        // crypto.Decrypter, with an RSA or ECDSA PublicKey. For a client
        // (performing client authentication), this must be a crypto.Signer
        // with an RSA or ECDSA PublicKey.
        PrivateKey crypto.PrivateKey

        ... other fields
}

Nicht lange nachdem dieser Beitrag auf der oss-sec-Mailingliste erschien, wurde eine CVE-Nummer vergeben: CVE-2016-3959. Die Go-Entwickler haben einen Fix dafür bereit, der in den Versionen 1.5.4 und 1.6.1 erscheinen wird, die am Mittwoch, den 13. April 2016 veröffentlicht werden sollen; https://groups.google.com/forum/#!topic/golang-nuts/MmSbFHLPo8g.

Um den Codebeispielen in diesem Artikel folgen zu können, benötigen Sie Go Version 1.6 installiert. Folgen Sie der Anleitung unter https://golang.org/doc/install. Wenn Sie dieses Dokument und die Codebeispiele herunterladen möchten, benötigen Sie auch Git installiert. Folgen Sie den Anweisungen unter https://git-scm.com/book/en/v2/Getting-Started-Installing-Git. Um das Repository zu klonen, geben Sie den folgenden Befehl in einem Terminal ein:

$ go get github.com/alexmullins/dsa

Dadurch wird das Repository in Ihren Go-Workspace geklont.

Der nächste Abschnitt behandelt die Einzelheiten der Sicherheitslücke.

Der Fehler

Also, was genau ist falsch? Um das zu beantworten, muss man zur ursprünglichen Ankündigung auf der oss-sec-Mailingliste zurückgehen. Dort gibt es nicht viele Informationen, außer einer allgemeinen Erklärung des Problems und einem Link zum Code-Fix unter https://golang.org/cl/21533. Die Commit-Nachricht für diese Änderung enthält Folgendes:

crypto/dsa: ungültigen PublicKey frühzeitig eliminieren

Für PublicKey.P == 0 wird Verify fehlschlagen. Versuchen Sie es gar nicht erst.

--- Robert Griesemer

und der korrigierte Code:

https://github.com/golang/go/blob/master/src/crypto/dsa/dsa.go#L247

// Verify verifies the signature in r, s of hash using the public key, pub. It
// reports whether the signature is valid.
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
    // FIPS 186-3, section 4.7

    // Code fix added to check if the key parameters are sensible.
    if pub.P.Sign() == 0 {
        return false
    }

    if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
        return false
    }
    if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
        return false
    }

    w := new(big.Int).ModInverse(s, pub.Q)

    n := pub.Q.BitLen()
    if n&7 != 0 {
        return false
    }
    z := new(big.Int).SetBytes(hash)

    u1 := new(big.Int).Mul(z, w)
    u1.Mod(u1, pub.Q)
    u2 := w.Mul(r, w)
    u2.Mod(u2, pub.Q)
    v := u1.Exp(pub.G, u1, pub.P)
    u2.Exp(pub.Y, u2, pub.P)
    v.Mul(v, u2)
    v.Mod(v, pub.P)
    v.Mod(v, pub.Q)

    return v.Cmp(r) == 0
}

Um die Commit-Nachricht und den obigen Code-Fix zusammenzufassen: In Go 1.6 und früheren Versionen gibt es einen Fehler in der Verify-Funktion des crypto/dsa-Pakets. Wenn jemand Verify mit dem öffentlichen Schlüsselparameter P = 0 aufruft, führt dies zu einer Endlosschleife in einer der weiter unten in der Verify-Funktion stehenden Anweisungen.

Ein kurzer Exkurs zur Erklärung von DSA. DSA ist ein digitaler Signaturalgorithmus, der asymmetrische Kryptografie verwendet, um eine Nachricht zu signieren, die später verwendet werden kann, um zu garantieren, dass die Nachricht tatsächlich vom Sender/Inhaber des privaten Schlüssels gesendet wurde. Ein einfaches Beispiel: Alice sendet Bob eine Nachricht, in der sie ihm mitteilt, wo und wann sie sich zum Mittagessen treffen sollen. Bob möchte jedoch sicher sein, dass Alice wirklich diejenige ist, die ihm die Nachricht gesendet hat, und nicht jemand anderes. Dazu signiert Alice die Nachricht mit ihrem privaten Schlüssel, und Bob kann Alices Signatur mit ihrem öffentlichen Schlüssel überprüfen, den Bob kennt. Niemand außer dem Inhaber des privaten Schlüssels kann eine Nachricht signieren, die dann mit dem entsprechenden öffentlichen Schlüssel verifiziert werden kann (das ist zumindest die Idee).

Damit DSA funktioniert, werden 5 große Zahlen benötigt. Die ersten 3 Zahlen werden als die DSA-Parameter P, Q und G bezeichnet. Diese definieren die zugrunde liegende Gruppe und den Gruppengenerator. Diese Zahlen können ordnungsgemäß mit einem Aufruf von dsa.GenerateParameters() erstellt werden.

type Parameters struct {
        P, Q, G *big.Int
}

Die letzten beiden Zahlen, die für DSA benötigt werden, sind der private Schlüssel X und der entsprechende öffentliche Schlüssel Y. Diese Zahlen können auch mit einem Aufruf von dsa.GenerateKey() erstellt werden.

type PrivateKey struct {
        PublicKey
        X *big.Int
}

type PublicKey struct {
        Parameters
        Y *big.Int
}

Das ist alles, was Sie über DSA wissen müssen, um folgen zu können. Weitere Informationen finden Sie im NIST-Standard: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf oder auf der Wikipedia-Seite: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm.

Zurück zum Thema; wo befindet sich die Endlosschleife in der Verify-Funktion? Mit ein wenig tieferem Graben werden Sie feststellen, dass der Code bei Folgendem hängt:

v := u1.Exp(pub.G, u1, pub.P)

Dies ist der Kommentar für die Exp()-Methode:

// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
// If y <= 0, the result is 1 mod |m|; if m == nil or m == 0, z = x**y.
// See Knuth, volume 2, section 4.6.3.
func (z *Int) Exp(x, y, m *Int) *Int {
Tool herunterladen