Squid: Denial-of-Service-Attacke legt Proxy lahm

Eine Sicherheitslücke in dem Proxy-Server Squid hat zur Folge, dass ein entfernter Angreifer Denial-of-Service-Attacken gegen den Dienst durchführen kann.  Die Attacke ist mit Hilfe spezieller HTTP-Anfragen möglich. Sendet der Angreifer einen HTTP-Header mit speziell präpariertem Accept-Language-Eintrag, so wird die Squid-Applikation in eine Endlosschleife versetzt und reagiert auf weitere Anfragen nicht mehr. Auch wird die CPU Load durch die Attacke hochgetrieben.  Der Fehler tritt auf, wenn Squid versucht eine entsprechende Fehler-Seite als Reaktion auf die Anfrage zu generieren.

Die Attacke lässt sich einfach via curl realisieren:

curl -H "Accept-Language: ," http://localhost:3129/

Diese einfache curl-Anweisung sendet einen entsprechenden Header an Squid und führt damit die Attacken gegen den lokalen Squid-Proxy auf localhost aus.

Der Programmierfehler befindet sich in der errorpage.cc-Datei. Hier kann der Angreifer durch spezielle Eingaben die strHdrAcptLangGetItem()-Funktion in eine Endlosschleife versetzen.

bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos)
{
  while (pos < hdr.size()) {
    char *dt = lang;
 
  if (!pos) {
    /* skip any initial whitespace. */
    while (pos < hdr.size() && xisspace(hdr[pos]))
      ++pos;
  } else {
    // IFF we terminated the tag on whitespace or ';' we need to skip to the next ',' or end of header.
    while (pos < hdr.size() && hdr[pos] != ',')
      ++pos;
      if (hdr[pos] == ',')
        ++pos;
   }
 
  /*
   * Header value format:
   *  - sequence of whitespace delimited tags
   *  - each tag may suffix with ';'.* which we can ignore.
   *  - IFF a tag contains only two characters we can wildcard ANY translations matching: <it> '-'? .*
   *    with preference given to an exact match.
   */
  bool invalid_byte = false;
  while (pos < hdr.size() && hdr[pos] != ';' && hdr[pos] != ',' && !xisspace(hdr[pos]) && dt < (lang + (langLen -1)) ) {
    if (!invalid_byte) {
    #if USE_HTTP_VIOLATIONS
    // if accepting violations we may as well accept some broken browsers
    //  which may send us the right code, wrong ISO formatting.
    if (hdr[pos] == '_')
      *dt = '-';
    else
    #endif
    *dt = xtolower(hdr[pos]);
    // valid codes only contain A-Z, hyphen (-) and *
    if (*dt != '-' && *dt != '*' && (*dt < 'a' || *dt > 'z') )
      invalid_byte = true;
    else
      ++dt; // move to next destination byte.
    }
    ++pos;
  }
  *dt = '\0'; // nul-terminated the filename content string before system use.
  ++dt;
 
  debugs(4, 9, HERE << "STATE: dt='" << dt << "', lang='" << lang << "', pos=" << pos << ", buf='" << ((pos < hdr.size()) ? hdr.substr(pos,hdr.size()) : "") << "'");
 
  /* if we found anything we might use, try it. */
  if (*lang != '\0' && !invalid_byte)
    return true;
  }
 return false;
}

Durch die Attacke wird diese Funktion mit pos=0 aufgerufen. Hangelt man sich durch den abgedrucken Code dieser Funktion, so stellt man fest, dass durch pos=0 die gesamte while(pos < hdr.size())-Schleife immer wieder aufgerufen wird, ohne zu terminieren. Denn durch die speziellen Eingaben für diese Funktion wird weder pos++ aufgerufen noch return true; ausgeführt.

Ein Patch für diese Funktion wurde veröffentlicht.
Betroffen sind die Versionen 3.2.5 und 3.2.7.

E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben